Практические основы тестирования на php Unit-test: понятия, тонкости, пути решения, вопросы для проработки.
PHPUnittest fast start
Разработано http://webgloss.ru
2. Разработка и отладка тестов
IDE
Тест
разрабатывается в
IDE, затем по
средствам IDE тест
заливается на
тестовый сервер
ssh
Пробные запуски
тестов выполняются
на сервере через
ssh.
разработано WebGloss
3. Термины
●
●
сборка - слепок состония системы и тестов
тесткейс (тест)- список действий, переводящих систему из одного состояния в другое, для
получения результата, на основании которого можно сделать вывод о удовлетворении
реализации, поставленным требованиям
разработано WebGloss
4. Термины
●
●
●
●
тестсюит - набор тесткейсов
фикстура - начальный набор данных
пограничные ситуации – случае, когда тестируемый код может работать неверно
тестовое окружение (fixture) - параметры тестируемой среды называются
разработано WebGloss
7. Этапы процесса Unit тестирования
1) Создание теста
2) Вкладка теста в VCS
3) Создание билда в
CI (Continuous
Integration)
разработано WebGloss
8. Этапы процесса Unit тестирования
4) Запуск Unit тестов в
нужном окружении.
5) Просмотр и анализ
результатов.
разработано WebGloss
9. Базовые соглашения
1. Тесты для класса DemoClass содержатся в классе
DemoClassTest.
2. DemoClassTest унаследован (чаще всего) от
PHPUnit_Framework_TestCase.
3. Тесты это публичные методы с именами test* (кроме
этого, можно использовать аннотацию @test в
док-блоке чтобы пометить метод как тест)
4. Внутри тестовых методов для проверки того что
реальные данные соответствуют ожидаемым
используются методы-утверждения (assertion
methods)
разработано WebGloss
10. Межтестовые зависимости
Использвание аннотации @depends для описания
зависимостей
class DependencyFailureTest extends PHPUnit_Framework_TestCase
{
public function testOne()
{
$this->assertTrue(FALSE);
}
/**
* @depends testOne
*/
public function testTwo()
{ }
}
разработано WebGloss
11. Провайдеры данных
Метод провайдера данных должен быть public и возвращать
либо массив массивов либо объект реализующий интерфейс
Iterator
class DataTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider provider
*/
public function testAdd($a, $b, $c) {
$this->assertEquals($c, $a + $b);
}
public function provider() {
return array(
array(0, 0, 0),
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 3)
);
}
}
разработано WebGloss
12. Тестирование исключений
С помощью аннотации @expectedException можно
проверить было ли вызвано исключение в тестируемом
коде
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
}
}
Дополнительно можно использовать @expectedExceptionMessage и
@expectedExceptionCode в сочетании с @expectedException для проверки
сообщений и кодов исключений.
разработано WebGloss
14. Утверждения (Assertions)
1.
2.
3.
assertEmpty(mixed $actual[, string $message = ''])
assertEquals(mixed $expected, mixed $actual[, string $message = ''])
assertCount($expectedCount, $haystack[, string $message = ''])
Сообщает об ошибке $message если количество элементов в
$haystack не равно $expectedCount.
4.
assertArrayHasKey(mixed $key, array $array[, string $message = ''])
Сообщает об ошибке $message если $array не содержит ключа $key.
assertArrayNotHasKey() утверждает обратное и принимает тот же
набор аргументов
5.
assertXmlStringEqualsXmlString(string $expectedXml, string
$actualXml[, string $message = ''])
6. ...
разработано WebGloss
15. Пример результата теста
phpunit DataTest
class DataTest extends PHPUnit_Framework_TestCase{
PHPUnit 3.7.0 by Sebastian Bergmann.
/**
* @dataProvider provider
...F
*/
public function testAdd($a, $b, $c){
$this->assertEquals($c, $a + $b); Time: 0 seconds, Memory: 5.75Mb
}
public function provider(){
return array(
array(0, 0, 0),
array(0, 1, 1),
array(1, 0, 1),
array(1, 1, 3)
);
}
}
There was 1 failure:
1) DataTest::testAdd with data set #3 (1, 1,
3)
Failed asserting that 2 matches expected
3.
/home/sb/DataTest.php:9
FAILURES!
Tests: 4, Assertions: 4, Failures: 1.
19. Примеры тестов
class ClsUtilsTest extends PHPUnit_Framework_TestCase {
/**
* @var Util
*/
protected $util;
protected function setUp() {
$this->util = Util();
}
public function testToUpper() {
$link = mysql_connect('', '', '');
$this->assertTrue($link, 'Ошибка соединения: ' . mysql_error());
mysql_close($link);
$this->assertEquals($this->util->toUpper('абв'), 'АБВ');
}
public function testToLower() {
$this->assertEquals($this->util->toLower('ABC'), 'abc');
}
public function testCheckEmail() {
$this->assertEquals($this->util->checkEmail('gref@mail.ru'), 'gref@mail.ru');
}
}
разработано WebGloss
20. Неожиданность
По умолчанию, PHPUnit выполняет тесты таким
образом, что изменение глобальных и суперглобальных
переменных:
● $GLOBALS
● $_ENV
● $_POST
● $_GET
● $_COOKIE
● $_SERVER
● $_FILES
● $_REQUEST
не влияет на другие тесты (очищаються)
разработано WebGloss
21. Передача параметров
Варианты:
1.
Статические атрибуты классов
2.
Подход "источник-приемник" с использованием аннотации @depends
public function testEmpty()
return $stack;
}
/**
* @depends testEmpty
3.
*/
public function testPush(array $stack)
Атрибут $sharedFixture доступен во всех объектах классов
разработано WebGloss
22. Вопросы на проработку
1.
2.
3.
4.
5.
PHPUnit_Framework_TestSuite - класс позволяет организовать набор тестов в
иерархическом порядке
Assert`ы самые нужные
Объекты: Mocks, Stubs, Fakes and Spies
Приемочные и модульные тесты, снижение зависимостей
TDD - программирование через тестирование
разработано WebGloss