Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Unit test

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Unit test

    Weiss nicht, ob ich hier richtig bin, aber ich versuchs einfach mal. Hab auch nix dagegen, wenn man mich ins entsprechende Forum verschiebt. Und zwar. Ich habe eine Klasse entworfen, die mein Alter berechnet. Nun möchte ich isoliert testen, ob diese Klasse geht, wie ich das möchte. Ein grober aufbau
    PHP-Code:
    <?php

    class Alter{

        public function 
    bestimmeAlter(geburtstaggebuburtsmonatgeburtsjahr){
        
    //... gibt string mit alter zurück
        
    }

    }

    ?>
    Ich würde einfach wie folgt testen:
    PHP-Code:
    $a = new Alter();
    echo 
    $a->bestimmeAlter(10,7,1987); 
    Passt das so, denn ich will ja nur sehen, ob das ding so tut, wie ich es will. Also teste ich das einmal mit "Fake-daten" und seh's ja. Hintergrund ist, dass ich nicht verstehe, wiesos das frameworks fürs testen gibt.


  • #2
    Das Problem ist aber, das du da manuell das Ergebnis überprüfen musst und nicht sofort siehst wenn etwas schief geht. Bei zig oder hunderten Tests kannst du das unmöglich bei jeder Änderung neu überprüfen. Mit PHPUnit könntest du beispielsweise folgendes machen:
    PHP-Code:
    <?php
    class AlterTest extends PHPUnit_Framework_TestCase {
        public function 
    testBestimmeAlter() {
            
    $gebTag 10;
            
    $gebMonat 7;
            
    $gebJahr 1987;
            
    $ergebnis = new Alter()->bestimmeAlter($gebTag$gebMonat$gebJahr);
            
    $this->assertEquals(27$ergebnis);
        }
    }
    ?>
    Wenn das Alter nicht 27 beträgt, dann schlägt PHPUnit sofort Alarm, das der Test fehlschlägt.

    PS.: Deine Altersklasse sieht mir nicht ganz korrekt aus. Abgesehen davon das ich nicht weiß wozu du dafür eine eigene Klasse brauchst macht es vermutlich mehr Sinn, das Datum
    a) auf einmal, in einem genormten Datumsformat zu übergeben, z.B. YYYY-mm-dd.
    b) das dem Konstruktor zu übergeben anstatt der Methode.

    Kommentar


    • #3
      Ah ok, das war hilfreich. Läuft es dann praktisch so ab, dass, wenn ein assertEquals von den zig testcases nicht passt, er meckert?

      Kommentar


      • #4
        Also grundsätzlich ist es so, dass du bei Unit-Tests zunächst mal ein Framework brauchst, um die Unit-Tests überhaupt auszuführen.

        Im Beispiel von Tropi wird das PHPUnit Framework verwendet ( extends PHPUnit_Framework_TestCase), dass quasi Standard ist.

        Du kannst die Unit-Tests entweder über die Konsole ablaufen lassen oder, wenn du eine IDE wie Eclipse, Netbeans oder PHPStorm verwendest, auch dort integrieren.

        Ich würde dir übrigens empfehlen, mit der Klasse "DateTime" von PHP zu arbeiten und auch gleich die Zeitzone mit zu berücksichtigen, wenn du mit Datumswerten arbeitest. Das spart dir später viel Ärger.

        Die Klasse, die du geschrieben hast (Alter) ist aus meiner Sicht zu Abstrakt. Was du haben willst, ist ja nicht das alter, sondern den Zeitraum, der seit einem bestimmten Datum vergangen ist und das in Jahren. Dazu eignet sich die Klasse DateInterval von PHP ganz gut.

        PHP-Code:
        class DateUtilityTest extends \PHPUnit_Framework_TestCase {

            public function 
        setUp() {
                
        $this->birthDate = new \\DateTime('2001-08-24');
            }

            public function 
        testYears() {
                
        $this->assertEquals(13DateUtility::years($this->birthDate));
            }


        PHP-Code:
        class DateUtility {

            public static function 
        years(\\DateTime $from) {
                
        $now = new \\DateTime();
                
        $interval $now->diff($from);
                return 
        $interval->y;
            }


        Hier noch ein Screenshot von der Unit-Test Ausführung in Netbeans:

        Fynder - http://www.fynder.de - Tutorials zum Thema Technik

        Kommentar


        • #5
          Ich habe sehr gute Erfahrungen mit PHPUnit (https://phpunit.de/ gemacht und kann dies nur empfehlen. Lässt sich in jede große IDE einbinden oder eben über die Konsole ausführen. Neben einfachen Prüfungen von Werten besteht auch die Möglichkeit eine Datenbank zu testen, so dass du auch SQL-Befehle ausführen und anschließend die Strukturen prüfen kannst.

          Falls eines der assertEquals nicht passt wird ein entsprechender Fehler ausgegeben welcher auch beschreibt welche Werte nicht gleich sind. Bei Datenbank-Tests gibt er auch die kompletten Strukturen aus welche nicht passen. Zusätzlich lässt sich noch die Testabdeckung ermitteln um so zu sehen welche Bereiche noch nicht geprüft werden.

          Ein Framework ist um längen besser als eine Sichtkontrolle oder ein selbstprogrammiertes Script.

          Gruß S. Brosch

          Kommentar


          • #6
            Zitat von Andreas Beitrag anzeigen

            PHP-Code:
            class DateUtilityTest extends \PHPUnit_Framework_TestCase {

                public function 
            setUp() {
                    
            $this->birthDate = new \\DateTime('2001-08-24');
                }

                public function 
            testYears() {
                    
            $this->assertEquals(13DateUtility::years($this->birthDate));
                }


            PHP-Code:
            class DateUtility {

                public static function 
            years(\\DateTime $from) {
                    
            $now = new \\DateTime();
                    
            $interval $now->diff($from);
                    return 
            $interval->y;
                }


            Sidetracking, aber(auch aus persönlichem Interesse):

            DateInterval::$y ist immer ein integer, jemand der die statische Methode aufruft kann mit der derzeitigen Implementierung erwarten, das ein solcher zurückgegeben wird. Sollte die Implementierung geändert werden (in diesem Fall unwahrscheinlich, aber im Prinzip möglich) und ein String zurückgeben werden kann der Test doch in der jetzigen Form seine Aussagekraft verlieren, da der aufrufende Code u.U. einen String anders behandelt, als einen Integer.

            Wäre nicht assertSame(bzw. assertInternalType + assertEquals) die angemessenere Lösung?
            Zitat von nikosch
            Naja, anscheinend spricht die Steckdose kein HTTP. LOL

            Kommentar


            • #7
              Leider arbeite ich mit Notepad und habe keine Erfahrung mit der Konsole. Kann man den test nicht händisch machen, indem man ein objekt anlegt und alle methoden auf einmal testet?

              Kommentar


              • #8
                Zitat von Tropi Beitrag anzeigen
                PHP-Code:
                <?php
                class AlterTest extends PHPUnit_Framework_TestCase {
                    public function 
                testBestimmeAlter() {
                        
                $gebTag 10;
                        
                $gebMonat 7;
                        
                $gebJahr 1987;
                        
                $ergebnis = new Alter()->bestimmeAlter($gebTag$gebMonat$gebJahr);
                        
                $this->assertEquals(27$ergebnis);
                    }
                }
                ?>
                Kleine Anmerkung: Dieser Test wird so in ein paar Monaten nicht mehr funktionieren.
                Standards - Best Practices - AwesomePHP - Guideline für WebApps

                Kommentar


                • #9
                  Zitat von rkr Beitrag anzeigen
                  Kleine Anmerkung: Dieser Test wird so in ein paar Monaten nicht mehr funktionieren.

                  Kommentar


                  • #10
                    Ich würde die Implikation "gilt für heute" nicht fest verankern. Gib ein Referenzdatum ein, für das die Berechnung stattfinden soll. Dann veralten auch deine Unittests nicht. Als Defaultwert kannst du ja heute nehmen.

                    PHP-Code:
                    <?php
                    interface Anniversary
                    {
                      public function 
                    __construct(\DateTime $baseDate);
                      public function 
                    getAge(\DateTime $date null); /* if ($date === null) { $date = new \DateTime("today"); } .. */
                    }

                    // tests

                    $anniversary = new Anniversary(new DateTime("2010-01-01"));
                    $age $anniversary->getAge(new DateTime("2014-01-01"));
                    $this->assertEquals($age4);
                    Stellt natürlich nicht sicher, dass bei $date = null für getAge() trotzdem Murks gebaut wird.
                    "Mein Name ist Lohse, ich kaufe hier ein."

                    Kommentar


                    • #11
                      Ok, der Code war nur zu Demonstrationszwecken, ich setze den natürlich nicht ein. Das war nur in zwei Minuten fürs Forum hingeklatscht, um meine Thematik zu erläutern. Ich will aber trotzdem nochmal auf meine vorrige Aussage zurückkommen. Mit der Konsole hab ich keine Erfahrung und entwickeln tu ich auf Notepad++. Kann man somit den Test nicht iwie doch händisch ausführen (objekt erzeugen und methode aufrufen, die alle tests durchführt), was für mich als Anfäänger gerade sehr praktisch wäre; v.a. weil ich auch environment-unabhängig proggen will.

                      Kommentar


                      • #12
                        Zitat von hartCoder Beitrag anzeigen
                        Mit der Konsole hab ich keine Erfahrung und entwickeln tu ich auf Notepad++.
                        Die Konsole wirst du früher oder später als Entwickler brauchen, zumindest Grundkentnisse sollte man damit haben.
                        Und Notepad++, naja... Deine Entscheidung, da will ich mal nix zu sagen

                        Zitat von hartCoder Beitrag anzeigen
                        Kann man somit den Test nicht iwie doch händisch ausführen, was für mich als Anfäänger gerade sehr praktisch wäre; v.a. weil ich auch environment-unabhängig proggen will.
                        Natürlich, über die Konsole
                        Zitat von nikosch
                        Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.

                        Kommentar


                        • #13

                          Kommentar


                          • #14
                            Zitat von hartCoder Beitrag anzeigen
                            [...] Kann man somit den Test nicht iwie doch händisch ausführen (objekt erzeugen und methode aufrufen, die alle tests durchführt), [...]
                            Also entweder händisch oder automatisch? Und Env-unabhängig ist grösstenteils Humbug. Dass dein Projekt von phpUnit oder Symfony oder was-auch-immer abhängig ist kann wohl kaum ein Problem sein?
                            GitHub.com - ChrisAndChris - RowMapper und QueryBuilder für MySQL-Datenbanken

                            Kommentar


                            • #15
                              Zitat von hartCoder Beitrag anzeigen
                              Also bitte... Es kann doch nicht so schwer sein per Konsole in den Ordner des Projekts zu navigieren und "phpunit" einzutippen. Die Konsole ist kein Hexenwerk, einmal kurz reingelesen und du verstehst die funktionsweise. Alles andere sind dann auch nurnoch "programme", die du ausführst.
                              Zitat von nikosch
                              Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.

                              Kommentar

                              Lädt...
                              X