TestCase

Σε απλές δοκιμές, οι assertions μπορούν να ακολουθούν η μία την άλλη. Μερικές φορές όμως είναι πιο βολικό να ομαδοποιούμε τις assertions σε μια κλάση δοκιμής και έτσι να τις δομούμε.

Η κλάση πρέπει να είναι απόγονος της Tester\TestCase και απλουστευμένα την αποκαλούμε testcase. Η κλάση πρέπει να περιέχει μεθόδους δοκιμής που ξεκινούν με test. Αυτές οι μέθοδοι θα εκτελεστούν ως δοκιμές:

use Tester\Assert;

class RectangleTest extends Tester\TestCase
{
	public function testOne()
	{
		Assert::same(/* ... */);
	}

	public function testTwo()
	{
		Assert::match(/* ... */);
	}
}

# Εκτέλεση των μεθόδων δοκιμής
(new RectangleTest)->run();

Μια τέτοια γραμμένη δοκιμή μπορεί επιπλέον να εμπλουτιστεί με τις μεθόδους setUp() και tearDown(). Καλούνται πριν, αντίστοιχα μετά από κάθε μέθοδο δοκιμής:

use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Προετοιμασία
	}

	public function tearDown()
	{
		# Καθαρισμός
	}

	public function testOne()
	{
		Assert::same(/* ... */);
	}

	public function testTwo()
	{
		Assert::match(/* ... */);
	}
}

# Εκτέλεση των μεθόδων δοκιμής
(new NextTest)->run();

/*


Σειρά κλήσης μεθόδων
--------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Εάν προκύψει σφάλμα στη φάση setUp() ή tearDown(), η δοκιμή αποτυγχάνει συνολικά. Εάν προκύψει σφάλμα στη μέθοδο δοκιμής, παρόλα αυτά η μέθοδος tearDown() εκτελείται, αλλά με καταστολή των σφαλμάτων σε αυτήν.

Συνιστούμε στην αρχή της δοκιμής να γράψετε την annotation @testCase, τότε ο εκτελεστής δοκιμών από τη γραμμή εντολών θα εκτελεί τις επιμέρους μεθόδους του testcase σε ξεχωριστές διεργασίες και παράλληλα σε πολλαπλά νήματα. Αυτό μπορεί να επιταχύνει σημαντικά ολόκληρη τη διαδικασία δοκιμών.

<?php
/** @testCase */

Annotations μεθόδων

Για τις μεθόδους δοκιμής έχουμε στη διάθεσή μας αρκετές annotations που μας διευκολύνουν στις δοκιμές. Τις γράφουμε στη μέθοδο δοκιμής.

@throws

Είναι ισοδύναμο με τη χρήση του Assert::exception() μέσα στη μέθοδο δοκιμής. Η σύνταξη όμως είναι πιο ευανάγνωστη:

/**
 * @throws RuntimeException
 */
public function testOne()
{
	// ...
}


/**
 * @throws LogicException  Wrong argument order
 */
public function testTwo()
{
	// ...
}

@dataProvider

Αν θέλουμε να εκτελέσουμε τη μέθοδο δοκιμής πολλές φορές, αλλά με διαφορετικές παραμέτρους, αυτή η annotation είναι χρήσιμη. (Μην τη συγχέετε με την ομώνυμη annotation για αρχεία.)

Μετά από αυτήν αναφέρουμε το όνομα της μεθόδου που επιστρέφει τα ορίσματα για τη μέθοδο δοκιμής. Η μέθοδος πρέπει να επιστρέψει έναν πίνακα ή Traversable. Ένα απλό παράδειγμα:

public function getLoopArgs()
{
	return [
		[1, 2, 3],
		[4, 5, 6],
		[7, 8, 9],
	];
}


/**
 * @dataProvider getLoopArgs
 */
public function testLoop($a, $b, $c)
{
	// ...
}

Η δεύτερη παραλλαγή της annotation @dataProvider δέχεται ως παράμετρο τη διαδρομή προς ένα αρχείο INI (σχετικά με το αρχείο της δοκιμής). Η μέθοδος καλείται τόσες φορές όσες είναι οι ενότητες στο αρχείο INI. Αρχείο loop-args.ini:

[one]
a=1
b=2
c=3

[two]
a=4
b=5
c=6

[three]
a=7
b=8
c=9

και η μέθοδος που χρησιμοποιεί το αρχείο INI:

/**
 * @dataProvider loop-args.ini
 */
public function testLoop($a, $b, $c)
{
	// ...
}

Παρόμοια, αντί για αρχείο INI μπορούμε να παραπέμψουμε σε ένα PHP script. Αυτό πρέπει να επιστρέψει έναν πίνακα ή Traversable. Αρχείο loop-args.php:

return [
	['a' => 1, 'b' => 2, 'c' => 3],
	['a' => 4, 'b' => 5, 'c' => 6],
	['a' => 7, 'b' => 8, 'c' => 9],
];