Frage

Ich bin meistens überzeugt von den Vorteilen der Unit-Tests, und ich würde das Konzept zu einer großen bestehenden Code-Basis in PHP geschrieben starten möge anwenden. Weniger als 10% dieses Codes ist objektorientiert.

Ich habe an mehrere Unit-Test-Frameworks (PHPUnit, Simple und PHPT) sieht. Ich habe jedoch keine Beispiele für eine dieser gefunden, die prozeduralen Code zu testen. Was ist der beste Rahmen für meine Situation und gibt es Beispiele von Unit-Tests PHP nicht-OOP Code?

War es hilfreich?

Lösung

Sie können Unit-Test-prozedurale PHP, kein Problem. Und Sie sind auf jeden Fall nicht aus Glück, wenn Ihr Code gemischt mit HTML in.

Bei der Anwendung oder Abnahmeprüfung Ebene, Ihr Verfahren PHP hängt wahrscheinlich von dem Wert des Superglobals ($_POST, $_GET, $_COOKIE, etc.) Verhalten zu bestimmen, und endet durch eine Vorlagendatei mit und die Ausgabe auszuzuspucken.

Anwendungsebene Tests zu tun, können Sie einfach die superglobalen Werte eingestellt; beginnt einen Ausgangspuffer (ein Bündel von html von Überschwemmungen des Bildschirm zu halten); rufen Sie die Seite; behaupten gegen Sachen in den Puffer; und Müll die Puffer am Ende.   Also, Sie so etwas tun könnte:

public function setUp()
{
    if (isset($_POST['foo'])) {
        unset($_POST['foo']);
    }
}

public function testSomeKindOfAcceptanceTest()
{
    $_POST['foo'] = 'bar';
    ob_start();
    include('fileToTest.php');
    $output = ob_get_flush();
    $this->assertContains($someExpectedString, $output);
}

Auch für enorme „Rahmen“ mit vielen enthält, ist diese Art der Prüfung wird Ihnen sagen, wenn Sie auf Anwendungsebene Funktionen haben oder nicht funktioniert. Das wird wirklich wichtig sein, wie Sie Ihren Code beginnen zu verbessern, denn selbst wenn Sie überzeugt sind, dass die Datenbank-Connector funktioniert immer noch und sieht besser aus als zuvor, möchten Sie auf eine Schaltfläche klicken und sehen, dass, ja, man kann immer noch Anmeldung und Abmeldung durch die Datenbank.

Auf den unteren Ebenen gibt es geringfügige Abweichungen auf variable Umfang abhängig und ob Funktionen von Nebenwirkungen arbeiten (wahr oder falsch zurückkehrt), oder das Ergebnis direkt zurück.

Variablen um explizit übergeben, als Parameter oder Arrays von Parametern zwischen den Funktionen? Oder Variablen in vielen verschiedenen Orten, und implizit als Globals weitergegeben? Wenn es der (gut) explizite Fall ist, können Sie testen, Einheit eine Funktion von (1), einschließlich der Datei, um die Funktion zu halten, dann (2) Zuführen der Funktionstestwerte direkt und (3) die Erfassung der Ausgabe und behaupten dagegen. Wenn Sie Globals verwenden, müssen Sie nur noch besonders vorsichtig sein (wie oben im $ _POST Beispiel) sorgfältig null heraus alle Globals zwischen den Tests. Es ist auch besonders hilfreich Tests sehr klein zu halten (5-10 Zeilen, 1-2 behauptet), wenn sie mit einer Funktion handelt, die schiebt und zieht viele Globals.

Eine weitere grundlegende Frage ist, ob die Funktionen arbeiten, indem sie die Ausgabe der Rückkehr oder durch die params übergeben zu verändern, Rückkehr wahr / falsch statt. Im ersten Fall ist Prüfung einfacher, aber auch hier ist es möglich, in beiden Fällen:

// assuming you required the file of interest at the top of the test file
public function testShouldConcatenateTwoStringsAndReturnResult()
{
  $stringOne = 'foo';
  $stringTwo = 'bar';
  $expectedOutput = 'foobar';
  $output = myCustomCatFunction($stringOne, $stringTwo);
  $this->assertEquals($expectedOutput, $output);
}

Im schlechten Fall, in dem der Code funktioniert durch Nebenwirkungen und gibt wahr oder falsch, man kann immer noch ziemlich leicht testen:

/* suppose your cat function stupidly 
 * overwrites the first parameter
 * with the result of concatenation, 
 * as an admittedly contrived example 
 */
public function testShouldConcatenateTwoStringsAndReturnTrue()
    {
      $stringOne = 'foo';
      $stringTwo = 'bar';
      $expectedOutput = 'foobar';
      $output = myCustomCatFunction($stringOne, $stringTwo);
      $this->assertTrue($output);
      $this->Equals($expectedOutput, $stringOne);
    }

Hope, das hilft.

Andere Tipps

Was für Unit-Tests gut tun, und was Sie sollten sie für verwenden, ist, wenn Sie ein Stück Code, dass Sie eine bestimmte Anzahl von Eingaben geben, und Sie erwarten, dass eine bestimmte Anzahl von Ausgängen aus zurückzubekommen. Die Idee ist, wenn Sie die Funktionalität später hinzufügen, können Sie Ihre Tests ausführen und stellen Sie sicher, dass es immer noch die alte Funktionalität die gleiche Art und Weise durchgeführt wird.

Wenn Sie also eine prozeduralen Code-Basis haben, können Sie erreichen dies Ihre Funktionen in den Testverfahren Aufruf

require 'my-libraries.php';
class SomeTest extends SomeBaseTestFromSomeFramework {
    public function testSetup() {
        $this->assertTrue(true);
    }

    public function testMyFunction() {
        $output = my_function('foo',3);

        $this->assertEquals('expected output',$output);
    }
}

Dieser Trick mit PHP-Code-Basen ist, oft der Bibliothekscode wird mit dem Ablauf Ihres Test-Framework, wie Ihre Code-Basis stören und das Test-Frameworks wird eine Menge von Code zur Einrichtung eine Anwendungsumgebung in einem Web-Browser im Zusammenhang hat ( Sitzung, gemeinsame globale Variablen, etc.). Erwarten Sie irgendwann zu verbringen, um zu einem Punkt, wo Sie Ihre Bibliothek Code enthalten können, und führen Sie einen Schmutz einfachen Test (die testSetup Funktion oben).

Wenn Ihr Code nicht funktioniert hat, und ist nur eine Reihe von PHP-Dateien, dass die Ausgabe von HTML-Seiten, sind Sie Art von Glück. Ihr Code kann nicht in einzelne Einheiten getrennt werden, was bedeutet, Unit-Test wird nicht für Sie von großem Nutzen sein. Sie würden besser dran, wie mit Produkten Ihrer Zeit bei der „Abnahmeprüfung“ -Niveau Ausgaben Selen und Watir . Diese lassen Sie einen Browser automatisiert, und dann überprüfen Sie die Seiten für Inhalte wie bestimmte Orte / in Formen.

Sie könnten versuchen, Ihren Nicht-oop-Code in eine Testklasse schließen mit

require_once 'your_non_oop_file.php' # Contains fct_to_test()

Und mit PHPUnit Sie definieren Ihre Testfunktion:

testfct_to_test() {
   assertEquals( result_expected, fct_to_test(), 'Fail with fct_to_test' );
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top