SimpleTest führt neben dem übermächtigen PHPUnit ein Schattendasein in der PHP-Community. Vielleicht nicht ganz zu Unrecht, schließlich kommt es mit deutlich weniger Features daher. Eher durch Zufall entdeckte ich beim Durchstöbern der Dokumentation das verdammt coole Webtesting Feature – zwar nicht so mächtig wie Selenium (das ja u.a. einen echten Browser fernsteuern kann), aber für kleine Checks durchaus gut zu gebrauchen. Aber der Reihe nach.
SimpleTest installieren
Die aktuelle Alpha-Version 1.1 herunterladen. Zusätzlich noch das File arguments.php direkt aus dem SVN herunterladen und ins simpletest-Verzeichnis stecken. Das wurde anscheinend in der alpha vergessen und führt sonst zu einem Fehler.
Test anlegen
Auf der selben Ebene des simpletest-Ordners erstellen wir eine Datei:
require_once 'simpletest/autorun.php'; require_once 'simpletest/web_tester.php'; class BlogSearchTest extends WebTestCase { function testDoesBlogSearchWork() { $this->get('https://d-mueller.de/blog/'); //we want a "200 - OK" response $this->assertResponse(200); } }
Das wars schon.
Der Test
Um gleich mal ein „full featured“ Beispiel zu bringen, wo alle grundlegenden Funktionalitäten des Webtesters gezeigt werden, planen wir folgendes:
Es soll die Seite „https://d-mueller.de/blog/“ besucht werden, in das Suchfeld rechts oben der Text „timestamps“ eingegeben werden und der „Suchen“ Button gedrückt werden. Auf der Ergebnisseite soll der Link „Dealing with Trusted Timestamps in PHP (RFC 3161)“ gesucht und geklickt werden. Letztendlich suchen wir noch im Artikel selbst einen speziellen Text.
Dabei prüfen wir alles, was wir prüfen können: Response-Code, Vorhandensein der Links etc.pp. Hier das gesamte Beispiel, was für sich selbst spricht:
<?php require_once 'simpletest/autorun.php'; require_once 'simpletest/web_tester.php'; class BlogSearchTest extends WebTestCase { function testDoesBlogSearchWork() { //we are impatient! If a request takes longer than 6 seconds, the test should fail $this->setConnectionTimeout(6); //pretend to be a real browser $this->addHeader("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); $this->get('https://d-mueller.de/blog/'); //we want a "200 - OK" response $this->assertResponse(200); //only html is accepted as response format $this->assertMime("text/html"); //dump the headers for fun $this->showHeaders(); //check if a certain response header matches $this->assertHeader("Server", "Apache/2.2.14 (Ubuntu)"); //is the <title> equal to what we are expecting? $this->assertTitle("davblog: webdev and stuff | jeden Tag ein bisschen besser"); //Is a Textfield with name="s" present? -> search field $this->assertField("s"); //enter the text "timestamps" in the search field $this->setField("s", "timestamps"); //hit search button $this->clickSubmit("Suchen"); //check if search returns "200 - OK" $this->assertResponse(200); //check if a link <a href="...">Dealing with Trusted Timestamps in PHP (RFC 3161)</a> is on the page $this->assertLink("Dealing with Trusted Timestamps in PHP (RFC 3161)"); //click the link $this->clickLink("Dealing with Trusted Timestamps in PHP (RFC 3161)"); //... and visit the article page $this->assertResponse(200); //the url has to be "https://d-mueller.de/blog/dealing-with-trusted-timestamps-in-php-rfc-3161/" now $this->assertEqual($this->getUrl(), "https://d-mueller.de/blog/dealing-with-trusted-timestamps-in-php-rfc-3161/"); //check if the text "Explanation of the concept behind Trusted Timestamp" is present on the page $this->assertText("Explanation of the concept behind Trusted Timestamp"); //dump the request-headers $this->showRequest(); } }
Ausgeführt sieht das dann so aus:
Geht also schon einiges. Eine vollständige Auflistung aller Webtest-Möglichkeiten gibt es auch. Letztendlich lässt sich das webtest-Modul auch als simpler, scriptbarer Browser verwenden, ganz ohne dabei etwas zu testen:
<?php require_once('simpletest/browser.php'); $browser = new SimpleBrowser(); $browser->get('https://d-mueller.de/blog/'); $browser->setField("s", "timestamps"); $browser->clickSubmit('Suchen'); $browser->clickLink('Dealing with Trusted Timestamps in PHP (RFC 3161)'); //print the page <title> echo $browser->getTitle(); //Dealing with Trusted Timestamps in PHP (RFC 3161) | davblog: webdev and stuff //get all urls on the site print_r($browser->getUrls()); /* Array ( [0] => https://d-mueller.de/blog/ [1] => https://d-mueller.de/blog/dealing-with-trusted-timestamps-in-php-rfc-3161/#content [2] => https://d-mueller.de/blog/ [3] => https://d-mueller.de/blog/archiv/ [4] => https://d-mueller.de/blog/rss-feed/ ... }
Im Detail gibt es auch hierzu wieder eine Dokuseite. Da wird dann auch das Handling mit Authentication, Sessions und Cookies demonstriert.
Fazit: Simpel in der Bedinung und für kleine Aufgaben definitv mächtig genug
Wieso wird im Testergebnis eigentlich immer ein Test weniger durchlaufen, als angeblich da ist: „1/2 test cases complete“.
Ich habe das bei mir auch und verstehe es nicht wirklich. Ist das richtig so? (Wieso?)
Hi, da war ich also doch nicht der einzige, den das verwundert hat ;).
Das „Problem“ liegt darin begründet, dass wir die Datei web_tester.php includen. In Zeile 433 dieser Datei steht
class WebTestCase extends SimpleTestCase {
SimpleTest denkt nun deswegen, dass es sich um einen weiteren Testcase handeln würde.
Wenn man jetzt mal testweise sowas nimmt, hast du auch 1/2 test cases complete:
require_once '/simpletest/autorun.php';
class TestFoobar extends UnitTestCase
{
function testSuiteTest()
{
$this->assertEqual(123, 123);
}
}
class AnotherTestCase extends SimpleTestCase {}
Also nix worüber man sich Gedanken machen müsste ;)