Webtesting mit SimpleTest – Selenium light

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.

Erster Test

Erster Test

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:

Testergebnis

Testergebnis

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

Weitere Posts:

Dieser Beitrag wurde unter php, Quicktips, webdev veröffentlicht. Setze ein Lesezeichen auf den Permalink.

2 Antworten auf Webtesting mit SimpleTest – Selenium light

  1. karsten sagt:

    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?)

    • david sagt:

      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 ;)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.