Entwickler.HowToUnitTest History

Hide minor edits - Show changes to markup

 
 
April 01, 2011, at 11:19 PM by tthelen -
Added lines 1-2:

(:redirect 'http://docs.studip.de/develop/Entwickler/HowToUnitTest':)

 
 
March 29, 2010, at 03:19 PM by mriehe -
Added lines 1-2:
 
 
March 22, 2010, at 09:12 PM by mlunzena -
Changed lines 32-33 from:

Als Beispiel werden wir einen kleinen Test für die Funktion words schreiben, die sich in der Datei lib/functions.php befindet.

to:

Als Beispiel werden wir einen kleinen Test für die Funktion #words schreiben, die sich in der Datei lib/functions.php befindet.

Changed lines 112-113 from:

Ausserdem erkennt man gut das four phase test pattern. Die Kommentare trennen die 4 Phasen eines Tests. Unter "fixture" versteht man die Ausgangssituation, die geschaffen werden muss, um den Test auszuführen. In unserem sehr einfachen Beispiel ist dafür nichts notwendig. In der "exercise"-Phase wird dannn das zu testende Verhalten herbeigeführt, was in diesem Fall dem Aufruf der Funktion #words entspricht. Danach wird überprüft, ob das Ergebnis des Verhaltens den Erwartungen entspricht. Und ganz am Ende räumt man alles ab, damit der nächste Test in einer klar definierten Umgebung ablaufen kann. Bei unserem Test ist dafür nichts zu tun.

to:

Ausserdem erkennt man gut das four phase test pattern. Die Kommentare trennen die 4 Phasen eines Tests. Unter "fixture" versteht man die Ausgangssituation, die geschaffen werden muss, um den Test auszuführen. In unserem sehr einfachen Beispiel ist dafür nichts notwendig. In der "exercise"-Phase wird dannn das zu testende Verhalten herbeigeführt, was in diesem Fall dem Aufruf der Funktion #words entspricht. Danach wird überprüft, ob das Ergebnis des Verhaltens den Erwartungen entspricht. Und ganz am Ende räumt man alles ab, damit der nächste Test in einer klar definierten Umgebung ablaufen kann. Bei unserem Test ist dafür nichts zu tun. Auf die Phasen 1 und 4 (Fixture-Setup und -Teardown) wird weiter unten vertieft eingegangen.

Added lines 143-144:

TODO (mlunzena) fehlt noch

Changed line 152 from:
to:

TODO (mlunzena) Hier fehlen noch ein paar weitere Links.

 
 
March 22, 2010, at 09:06 PM by mlunzena -
Changed lines 59-60 from:
    function test_something() {
to:
    function testSomething()
    {
Changed lines 94-95 from:
    function testWords() {
to:
    function testWords()
    {
 
 
March 19, 2010, at 11:04 PM by mlunzena -
Changed lines 139-148 from:

Setup und TearDown

to:

Setup und TearDown

Weitere Informationen

  • SimpleTest-Homepage
  • SimpleTest-Dokumentation
  • SimpleTest-API-Dokumentation
 
 
March 19, 2010, at 11:00 PM by mlunzena -
Changed lines 118-138 from:
assertTrue($x)Fail unless $x evaluates true
assertFalse($x)Fail unless $x evaluates false
assertNull($x)Fail unless $x is not set
assertNotNull($x)Fail unless $x is set to something
assertIsA($x, $t)Fail unless $x is the class or type $t
assertNotA($x, $t)Fail unless $x is not the class or type $t
assertEqual($x, $y)Fail unless $x == $y is true
assertNotEqual($x, $y)Fail unless $x == $y is false
assertWithinMargin($x, $y, $margin)Fail unless $x and $y are separated less than $margin
assertOutsideMargin($x, $y, $margin)Fail unless $x and $y are sufficiently different
assertIdentical($x, $y)Fail unless $x === $y for variables, $x == $y for objects of the same type
assertNotIdentical($x, $y)Fail unless $x === $y is false, or two objects are unequal or different types
assertReference($x, $y)Fail unless $x and $y are the same variable
assertCopy($x, $y)Fail unless $x and $y are the different in any way
assertSame($x, $y)Fail unless $x and $y are the same objects
assertClone($x, $y)Fail unless $x and $y are identical, but separate objects
assertPattern($p, $x)Fail unless the regex $p matches $x
assertNoPattern($p, $x)Fail if the regex $p matches $x
expectError($e)Triggers a fail if this error does not happen before the end of the test
expectException($e)Triggers a fail if this exception is not thrown before the end of the test''
to:
assertTrue($x)schlägt fehl, es sei denn $x entspricht true
assertFalse($x)schlägt fehl, es sei denn $x entspricht false
assertNull($x)schlägt fehl, es sei denn $x ist nicht gesetzt
assertNotNull($x)schlägt fehl, es sei denn $x ist gesetzt
assertIsA($x, $t)schlägt fehl, es sei denn die Klasse oder der Typ von $x entspricht $t
assertNotA($x, $t)schlägt fehl, es sei denn die Klasse oder der Typ von $x entspricht nicht $t
assertEqual($x, $y)schlägt fehl, es sei denn $x == $y ist wahr
assertNotEqual($x, $y)schlägt fehl, es sei denn $x == $y ist falsch
assertWithinMargin($x, $y, $margin)schlägt fehl, es sei denn $x und $y liegen weniger als $margin auseinander
assertOutsideMargin($x, $y, $margin)schlägt fehl, es sei denn $x und $y liegen mehr als $margin auseinander
assertIdentical($x, $y)schlägt fehl, es sei denn $x === $y für primitive Variablen, $x == $y für Objekte desselben Typs
assertNotIdentical($x, $y)schlägt fehl, wenn $x === $y falsch ist, oder zwei Objekte ungleich oder von unterschiedlichem Typ sind
assertReference($x, $y)schlägt fehl, es sei denn $x und $y sind dieselbe Variable
assertCopy($x, $y)schlägt fehl, wenn $x und $y dieselbe Variable sind
assertSame($x, $y)schlägt fehl, es sei denn $x und $y sind dieselben Objekte
assertClone($x, $y)schlägt fehl, es sei denn $x und $y sind identisch, aber nicht dieselben Objekte
assertPattern($p, $x)schlägt fehl, es sei denn der reguläre Ausdruck $p matched $x
assertNoPattern($p, $x)schlägt fehl, wenn denn der reguläre Ausdruck $p matched $x
expectError($e)schlägt fehl, wenn der Fehler $e nicht vor Ende dieses Tests eintritt
expectException($e)schlägt fehl, wenn die Exception $e nicht vor Ende dieses Tests geworfen wird
 
 
March 19, 2010, at 10:46 PM by mlunzena -
Changed lines 118-137 from:
assertTrue($x)Fail unless $x evaluates true
assertFalse($x)Fail unless $x evaluates false
assertNull($x)Fail unless $x is not set
assertNotNull($x)Fail unless $x is set to something
assertIsA($x, $t)Fail unless $x is the class or type $t
assertNotA($x, $t)Fail unless $x is not the class or type $t
assertEqual($x, $y)Fail unless $x == $y is true
assertNotEqual($x, $y)Fail unless $x == $y is false
assertWithinMargin($x, $y, $margin)Fail unless $x and $y are separated less than $margin
assertOutsideMargin($x, $y, $margin)Fail unless $x and $y are sufficiently different
assertIdentical($x, $y)Fail unless $x === $y for variables, $x == $y for objects of the same type
assertNotIdentical($x, $y)Fail unless $x === $y is false, or two objects are unequal or different types
assertReference($x, $y)Fail unless $x and $y are the same variable
assertCopy($x, $y)Fail unless $x and $y are the different in any way
assertSame($x, $y)Fail unless $x and $y are the same objects
assertClone($x, $y)Fail unless $x and $y are identical, but separate objects
assertPattern($p, $x)Fail unless the regex $p matches $x
assertNoPattern($p, $x)Fail if the regex $p matches $x
expectError($e)Triggers a fail if this error does not happen before the end of the test
expectException($e)Triggers a fail if this exception is not thrown before the end of the test''
to:
assertTrue($x)Fail unless $x evaluates true
assertFalse($x)Fail unless $x evaluates false
assertNull($x)Fail unless $x is not set
assertNotNull($x)Fail unless $x is set to something
assertIsA($x, $t)Fail unless $x is the class or type $t
assertNotA($x, $t)Fail unless $x is not the class or type $t
assertEqual($x, $y)Fail unless $x == $y is true
assertNotEqual($x, $y)Fail unless $x == $y is false
assertWithinMargin($x, $y, $margin)Fail unless $x and $y are separated less than $margin
assertOutsideMargin($x, $y, $margin)Fail unless $x and $y are sufficiently different
assertIdentical($x, $y)Fail unless $x === $y for variables, $x == $y for objects of the same type
assertNotIdentical($x, $y)Fail unless $x === $y is false, or two objects are unequal or different types
assertReference($x, $y)Fail unless $x and $y are the same variable
assertCopy($x, $y)Fail unless $x and $y are the different in any way
assertSame($x, $y)Fail unless $x and $y are the same objects
assertClone($x, $y)Fail unless $x and $y are identical, but separate objects
assertPattern($p, $x)Fail unless the regex $p matches $x
assertNoPattern($p, $x)Fail if the regex $p matches $x
expectError($e)Triggers a fail if this error does not happen before the end of the test
expectException($e)Triggers a fail if this exception is not thrown before the end of the test''
 
 
March 19, 2010, at 10:45 PM by mlunzena -
Changed lines 94-97 from:
        $string = "one two three";
        $expected = array('one', 'two', 'three');
        $outcome = words($string);
        $this->assertEqual(, $expected);
to:
        // setup fixture

        // exercise system under test
        $words = words("one two three");

        // validate outcome
        $this->assertEqual($words, array('one', 'two', 'three'))

        // teardown fixture
Changed lines 108-131 from:

Es wird also einfach ein String mit drei Wörtern angelegt, dann an #words verfüttert, und zum Schluss mit Hilfe der Methode #assertEqual verglichen. Wenn diese Assertion erfolgreich ist, wird dieser Test wiederum erfolgreich sein.

''The smallest unit of a…er…unit test is the assertion. Here we want to assert that the log file we just sent a message to was indeed created. UnitTestCase::assertTrue() will send a pass event if the condition evaluates to true and a fail event otherwise. We can have a variety of different assertions and even more if we extend our base test cases.

Here is the base list… assertTrue($x) Fail unless $x evaluates true assertFalse($x) Fail unless $x evaluates false assertNull($x) Fail unless $x is not set assertNotNull($x) Fail unless $x is set to something assertIsA($x, $t) Fail unless $x is the class or type $t assertNotA($x, $t) Fail unless $x is not the class or type $t assertEqual($x, $y) Fail unless $x == $y is true assertNotEqual($x, $y) Fail unless $x == $y is false assertWithinMargin($x, $y, $margin) Fail unless $x and $y are separated less than $margin assertOutsideMargin($x, $y, $margin) Fail unless $x and $y are sufficiently different assertIdentical($x, $y) Fail unless $x === $y for variables, $x == $y for objects of the same type assertNotIdentical($x, $y) Fail unless $x === $y is false, or two objects are unequal or different types assertReference($x, $y) Fail unless $x and $y are the same variable assertCopy($x, $y) Fail unless $x and $y are the different in any way assertSame($x, $y) Fail unless $x and $y are the same objects assertClone($x, $y) Fail unless $x and $y are identical, but separate objects assertPattern($p, $x) Fail unless the regex $p matches $x assertNoPattern($p, $x) Fail if the regex $p matches $x expectError($e) Triggers a fail if this error does not happen before the end of the test expectException($e) Triggers a fail if this exception is not thrown before the end of the test''

to:

In diesem Test wird ein String mit drei Wörtern angelegt, dann an #words verfüttert, und zum Schluss mit Hilfe der Methode #assertEqual verglichen. Ist diese Assertion wahr, ist der Test erfolgreich.

Ausserdem erkennt man gut das four phase test pattern. Die Kommentare trennen die 4 Phasen eines Tests. Unter "fixture" versteht man die Ausgangssituation, die geschaffen werden muss, um den Test auszuführen. In unserem sehr einfachen Beispiel ist dafür nichts notwendig. In der "exercise"-Phase wird dannn das zu testende Verhalten herbeigeführt, was in diesem Fall dem Aufruf der Funktion #words entspricht. Danach wird überprüft, ob das Ergebnis des Verhaltens den Erwartungen entspricht. Und ganz am Ende räumt man alles ab, damit der nächste Test in einer klar definierten Umgebung ablaufen kann. Bei unserem Test ist dafür nichts zu tun.

Die kleinste Einheit eines Unit-Tests ist die Assertion. Im Beispiel wollten wir sicherstellen, dass die Funktion tatsächlich das erwartete Array zurückliefert. UnitTestCase#assertEqual ist erfolgreich, wenn der erste Parameter == dem zweiten Parameter ist.

Es gibt eine noch viele weitere Assertions und selbstverständlich kann der Programmierer jederzeit durch Erweiterung der Klasse UnitTestCase neue hinzufügen.

Die grundsätzlichen Assertions werden in der folgenden Tabelle aufgelistet:

assertTrue($x)Fail unless $x evaluates true
assertFalse($x)Fail unless $x evaluates false
assertNull($x)Fail unless $x is not set
assertNotNull($x)Fail unless $x is set to something
assertIsA($x, $t)Fail unless $x is the class or type $t
assertNotA($x, $t)Fail unless $x is not the class or type $t
assertEqual($x, $y)Fail unless $x == $y is true
assertNotEqual($x, $y)Fail unless $x == $y is false
assertWithinMargin($x, $y, $margin)Fail unless $x and $y are separated less than $margin
assertOutsideMargin($x, $y, $margin)Fail unless $x and $y are sufficiently different
assertIdentical($x, $y)Fail unless $x === $y for variables, $x == $y for objects of the same type
assertNotIdentical($x, $y)Fail unless $x === $y is false, or two objects are unequal or different types
assertReference($x, $y)Fail unless $x and $y are the same variable
assertCopy($x, $y)Fail unless $x and $y are the different in any way
assertSame($x, $y)Fail unless $x and $y are the same objects
assertClone($x, $y)Fail unless $x and $y are identical, but separate objects
assertPattern($p, $x)Fail unless the regex $p matches $x
assertNoPattern($p, $x)Fail if the regex $p matches $x
expectError($e)Triggers a fail if this error does not happen before the end of the test
expectException($e)Triggers a fail if this exception is not thrown before the end of the test''
 
 
March 19, 2010, at 06:39 PM by mlunzena -
Changed lines 104-106 from:

'' The smallest unit of a…er…unit test is the assertion. Here we want to assert that the log file we just sent a message to was indeed created. UnitTestCase::assertTrue() will send a pass event if the condition evaluates to true and a fail event otherwise. We can have a variety of different assertions and even more if we extend our base test cases.

to:

''The smallest unit of a…er…unit test is the assertion. Here we want to assert that the log file we just sent a message to was indeed created. UnitTestCase::assertTrue() will send a pass event if the condition evaluates to true and a fail event otherwise. We can have a variety of different assertions and even more if we extend our base test cases.

Changed lines 125-126 from:

expectException($e) Triggers a fail if this exception is not thrown before the end of the test ''

to:

expectException($e) Triggers a fail if this exception is not thrown before the end of the test''

 
 
March 19, 2010, at 06:38 PM by mlunzena -
Changed lines 96-97 from:
        $this->assertEqual(words($string), $expected);
to:
        $outcome = words($string);
        $this->assertEqual(, $expected);
Changed lines 104-127 from:

#assertEqual überprüft, ob beide Argument gleich sind. Dabei wird der einfache Vergleich mit == verwendet.

to:

'' The smallest unit of a…er…unit test is the assertion. Here we want to assert that the log file we just sent a message to was indeed created. UnitTestCase::assertTrue() will send a pass event if the condition evaluates to true and a fail event otherwise. We can have a variety of different assertions and even more if we extend our base test cases.

Here is the base list… assertTrue($x) Fail unless $x evaluates true assertFalse($x) Fail unless $x evaluates false assertNull($x) Fail unless $x is not set assertNotNull($x) Fail unless $x is set to something assertIsA($x, $t) Fail unless $x is the class or type $t assertNotA($x, $t) Fail unless $x is not the class or type $t assertEqual($x, $y) Fail unless $x == $y is true assertNotEqual($x, $y) Fail unless $x == $y is false assertWithinMargin($x, $y, $margin) Fail unless $x and $y are separated less than $margin assertOutsideMargin($x, $y, $margin) Fail unless $x and $y are sufficiently different assertIdentical($x, $y) Fail unless $x === $y for variables, $x == $y for objects of the same type assertNotIdentical($x, $y) Fail unless $x === $y is false, or two objects are unequal or different types assertReference($x, $y) Fail unless $x and $y are the same variable assertCopy($x, $y) Fail unless $x and $y are the different in any way assertSame($x, $y) Fail unless $x and $y are the same objects assertClone($x, $y) Fail unless $x and $y are identical, but separate objects assertPattern($p, $x) Fail unless the regex $p matches $x assertNoPattern($p, $x) Fail if the regex $p matches $x expectError($e) Triggers a fail if this error does not happen before the end of the test expectException($e) Triggers a fail if this exception is not thrown before the end of the test ''

 
 
March 19, 2010, at 06:32 PM by mlunzena -
Changed lines 95-96 from:
        $this->assertEqual(words($string), array('one', 'two', 'three'));
to:
        $expected = array('one', 'two', 'three');
        $this->assertEqual(words($string), $expected);
Changed lines 101-103 from:

Normalerweise würde man mehr Test-Methoden in einem TestCase haben, aber das kann ja noch kommen.

Assertions in den Test-Methoden führen zu Meldungen im Test-Framework, welches diese je nach Erfolg oder Mißerfolg anzeigt.

to:

Es wird also einfach ein String mit drei Wörtern angelegt, dann an #words verfüttert, und zum Schluss mit Hilfe der Methode #assertEqual verglichen. Wenn diese Assertion erfolgreich ist, wird dieser Test wiederum erfolgreich sein.

#assertEqual überprüft, ob beide Argument gleich sind. Dabei wird der einfache Vergleich mit == verwendet.

 
 
March 19, 2010, at 06:25 PM by mlunzena -
Changed lines 67-102 from:

Ein Beispiel Test

to:

Eine Test-Funktion

In unserem ersten Test wollen wir den happy path der Funktion #words testen. Schauen wir uns noch einmal diese Funktion an:

(:source lang=php linenum:)
/**
 * Splits a string by space characters and returns these words as an array.
 *
 * @param  string       the string to split
 *
 * @return array        the words of the string as array
 */
function words($string) {
  return preg_split('/ /', $string, -1, PREG_SPLIT_NO_EMPTY);
}

Diese Funktion erlaubt es also offenbar, aus einem String ein Array zu machen, das die Wörter des Strings als Elemente hat.

Damit sieht der erste Test so aus:

(:source lang=php linenum:)
[...]

class FunctionsTest extends UnitTestCase {

    function testWords() {
        $string = "one two three";
        $this->assertEqual(words($string), array('one', 'two', 'three'));
    }
}

Normalerweise würde man mehr Test-Methoden in einem TestCase haben, aber das kann ja noch kommen.

Assertions in den Test-Methoden führen zu Meldungen im Test-Framework, welches diese je nach Erfolg oder Mißerfolg anzeigt.

 
 
March 19, 2010, at 06:17 PM by mlunzena -
Added lines 64-65:

Man halt also eine Klasse, die von UnitTestCase abstammt, und die Test-Methoden enthält, deren Name mit test beginnt. Der Name sollte andeuten, was man eigentlich gerade testet. Er darf gerne lang sein. Niemand wird diese Methoden per Hand aufrufen müssen.

 
 
March 19, 2010, at 06:15 PM by mlunzena -
Changed line 60 from:
to:
 
 
March 19, 2010, at 06:14 PM by mlunzena -
Added lines 58-61:
    function test_something() {
        …
    }
 
 
March 19, 2010, at 06:14 PM by mlunzena -
Changed lines 40-59 from:
to:

Jeder Unit-Test sieht minimal so aus:

(:source lang=php linenum:)
<?php

/*
 * Copyright (C) 2010 - Marcus Lunzenauer <mlunzena@uos.de>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 */

// make sure that the code under test is available
require_once 'lib/functions.php';

class FunctionsTest extends UnitTestCase {
}
 
 
March 19, 2010, at 06:10 PM by mlunzena -
Added lines 32-33:

Als Beispiel werden wir einen kleinen Test für die Funktion words schreiben, die sich in der Datei lib/functions.php befindet.

Added lines 35-38:

Der Unit-Test-Runner, den wir oben ausführten, findet Test-Dateien in den Verzeichnissen test/lib und test/lib/classes. Dabei müssen die Namen dieser Dateien auf test.php enden.

In unserem Beispiel legen wir also eine Datei test/lib/functions_test.php an. Per Konvention sollen Tests, die sich auf Code in lib beziehen, im Verzeichnis test/lib liegen, und Tests, die sich auf Klassen aus lib/classes beziehen, im Verzeichnis test/lib/classes.

 
 
March 19, 2010, at 06:02 PM by mlunzena -
Added lines 1-4:

Unit-Tests in Stud.IP

TODO (mlunzena) Was sind Unit-Tests? Wofür sind sie gut? Welches Tool wird verwendet?

Changed lines 11-12 from:

Daraufhin erhält man als Ausgabe die Zahl der ausgeführten und erfolgreichen Tests. Das sieht dann z.B. so aus:

to:

Dieses Kommando durchsucht das Test-Verzeichnis nach Unit-Tests und führt diese aus. Daraufhin erhält man als Ausgabe die Zahl der ausgeführten und erfolgreichen Tests. Das sieht dann z.B. so aus:

Added lines 33-34:
 
 
March 15, 2010, at 10:28 AM by mlunzena -
Added lines 28-32:

Wohin kommen die Tests?

Ein Beispiel Test

Setup und TearDown

 
 
March 12, 2010, at 02:21 PM by mlunzena -
Added lines 13-23:

@]

Ein Fehler würde in etwa so aussehen:

[@ All tests 1) at [/test/lib/classes/assets_class_test.php line 43]

	in test_class_should_exist
	in AssetsTestCase

FAILURES!!! Test cases run: 10/10, Passes: 185, Failures: 1, Exceptions: 0

 
 
March 12, 2010, at 02:18 PM by mlunzena -
Added lines 1-16:

Wie führt man die Unit-Tests aus?

Rufe in deiner Stud.IP-Working-Copy folgendes Kommando im Terminal auf:

php test/all_tests.php

Daraufhin erhält man als Ausgabe die Zahl der ausgeführten und erfolgreichen Tests. Das sieht dann z.B. so aus:

All tests
OK
Test cases run: 10/10, Passes: 186, Failures: 0, Exceptions: 0

Wie schreibt man einen Unit-Test?

 

 

Source: Basis-Wiki-Hilfe | Last change: April 01, 2011, at 11:19 PM, tthelen | Local view: Basis-Hilfe