Nette Documentation Preview

syntax
TestCase
********

.[perex]
В простите тестове твърденията могат да следват едно след друго. Понякога обаче е полезно да се затворят твърденията в тестови клас и да се структурират по този начин.

Класът трябва да бъде потомък на `Tester\TestCase`, а ние го наричаме просто **testcase**.

```php
use Tester\Assert;

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

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

# Run testing methods
(new RectangleTest)->run();
```

Можем да обогатим тестовия пример с методите `setUp()` и `tearDown()`. Те се извикват преди/след всеки метод за изпитване:

```php
use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Preparation
	}

	public function tearDown()
	{
		# Clean-up
	}

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

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

# Run testing methods
(new NextTest)->run();

/*


Method Calls Order
------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/
```

Ако се появи грешка във фазата `setUp()` или `tearDown()`, тестът ще се провали. Ако в тестовия метод възникне грешка, методът `tearDown()` се извиква въпреки това, но с потиснати в него грешки.

Препоръчваме анотацията [@testCase |test-annotations#testCase] да се запише в началото на теста, след което програмата за стартиране на тестове от командния ред ще изпълнява отделните методи на тестовия случай в отделни процеси и паралелно в няколко нишки. Това може значително да ускори целия процес на тестване.

/--php
<?php
/** @testCase */
\--


Анотиране на методи .[#toc-annotation-of-methods]
=================================================

Има няколко анотации, които ни помагат при тестването на методите. Записваме ги в посока на метода за изпитване.


@throws .[filter]
-----------------
Това е същото използване на `Assert::exception()` в рамките на метод за изпитване. Но обозначението е по-четивно:

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


/**
 * @throws LogicException Грешен ред на аргументите
 */
public function testTwo()
{
	// ...
}
```


@dataProvider .[filter]
-----------------------
Тази анотация е подходяща, когато искаме да стартираме даден тестови метод многократно, но с различни аргументи. (Да не се бърка с анотацията на [файла |test-annotations#dataProvider] със същото име).

Като аргумент записваме името на метода, който връща параметрите на тестовия метод. Методът трябва да връща масив или Traversable. Един прост пример:

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


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

Друга разновидност на анотацията **@dataProvider** приема като аргумент пътя до файла INI (относително към тестовия файл). Методът се извиква толкова пъти, колкото секции има в INI файла. Файл `loop-args.ini`:

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

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

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

и метода, използващ файла INI:

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

По същия начин можем да предадем път до PHP скрипт вместо INI. Тя трябва да връща масив или Traversable. Файл `loop-args.php`:

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

TestCase

В простите тестове твърденията могат да следват едно след друго. Понякога обаче е полезно да се затворят твърденията в тестови клас и да се структурират по този начин.

Класът трябва да бъде потомък на Tester\TestCase, а ние го наричаме просто testcase.

use Tester\Assert;

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

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

# Run testing methods
(new RectangleTest)->run();

Можем да обогатим тестовия пример с методите setUp() и tearDown(). Те се извикват преди/след всеки метод за изпитване:

use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Preparation
	}

	public function tearDown()
	{
		# Clean-up
	}

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

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

# Run testing methods
(new NextTest)->run();

/*


Method Calls Order
------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Ако се появи грешка във фазата setUp() или tearDown(), тестът ще се провали. Ако в тестовия метод възникне грешка, методът tearDown() се извиква въпреки това, но с потиснати в него грешки.

Препоръчваме анотацията @testCase да се запише в началото на теста, след което програмата за стартиране на тестове от командния ред ще изпълнява отделните методи на тестовия случай в отделни процеси и паралелно в няколко нишки. Това може значително да ускори целия процес на тестване.

<?php
/** @testCase */

Анотиране на методи

Има няколко анотации, които ни помагат при тестването на методите. Записваме ги в посока на метода за изпитване.

@throws

Това е същото използване на Assert::exception() в рамките на метод за изпитване. Но обозначението е по-четивно:

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


/**
 * @throws LogicException Грешен ред на аргументите
 */
public function testTwo()
{
	// ...
}

@dataProvider

Тази анотация е подходяща, когато искаме да стартираме даден тестови метод многократно, но с различни аргументи. (Да не се бърка с анотацията на файла със същото име).

Като аргумент записваме името на метода, който връща параметрите на тестовия метод. Методът трябва да връща масив или Traversable. Един прост пример:

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


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

Друга разновидност на анотацията @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)
{
	// ...
}

По същия начин можем да предадем път до PHP скрипт вместо INI. Тя трябва да връща масив или Traversable. Файл loop-args.php:

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