Skip to main content
Logo

Неполные и пропущенные тесты

September 24, 2018
ru
This is an archived post from thewebland.net. Content may be outdated.

Неполные тесты

Когда вы работаете над новым тестовым классом, вы можете начать с написания пустых тестовых методов для отслеживания тех тестов, которые нужно написать, например:

public function testSomething()
{
}

Проблема с пустыми тестовыми методами состоит в том, что фреймворком PHPUnit они интерпретируется как успешно пройденные. Это ошибочное толкование приводит к тому, что отчёты о покрытии становятся бесполезными — вы не сможете увидеть, действительно ли тест прошёл, либо он просто ещё не реализован. Вызов $this->fail() в нереализованном тестовом методе также не поможет, поскольку тогда тест будет интерпретироваться как не пройденный. Это было бы так же неверно, как и считать нереализованный тест как пройденный.

Если мы думаем об успешном тестировании как о зелёном свете, а о непройденном тесте как о красном цвете, то нам нужен дополнительный жёлтый цвет для обозначения теста как неполного или ещё не реализованного. PHPUnit\Framework\IncompleteTest — это интерфейс для обозначения исключения, выбрасываемого тестовым методом как результат на то, что данный тестовый метод неполный или в данный момент ещё не реализован.PHPUnit\Framework\IncompleteTestError — стандартная реализация этого интерфейса.

Пример 7.1 показывает тестовый класс SampleTest, содержащий один тестовый метод testSomething(). Вызывая удобный метод markTestIncomplete() (который автоматически вызывает исключение PHPUnit\Framework\IncompleteTestError) в тестовом методе, мы отмечаем, что данный тест является неполным.

Пример 7.1 Маркировка теста как неполного

<?php
use PHPUnit\Framework\TestCase;
class SampleTest extends TestCase
{
public function testSomething()
{
// Необязательно: протестируйте здесь что-нибудь, если хотите.
$this->assertTrue(true, 'This should already work.');
// Остановиться тут и отметить, что тест неполный.
$this->markTestIncomplete(
'Этот тест ещё не реализован.'
);
}
}

Неполный тест обозначается I в выводе исполнителя тестов командной строки PHPUnit, как показано в следующем примере:

$ phpunit --verbose SampleTest
PHPUnit |version|.0 by Sebastian Bergmann and contributors.
I
Time: 0 seconds, Memory: 3.95Mb
There was 1 incomplete test:
1) SampleTest::testSomething
Этот тест ещё не реализован.
/home/sb/SampleTest.php:12
OK, but incomplete or skipped tests!
Tests: 1, Assertions: 1, Incomplete: 1.

Таблица 7.1 показывает API для маркировки тестов как неполных.

МетодОписание
void markTestIncomplete()Помечает текущий тест как неполный.
void markTestIncomplete(string $message)Помечает текущий тест как неполный, используя $message в качестве пояснительного сообщения.

Пропущенные тесты

Не все тесты могут выполняться в любом окружении. Рассмотрим, например, уровень абстракции базы данных, содержащий несколько драйверов для различных систем баз данных, которые он поддерживает. Разумеется, тесты для драйвера MySQL могут выполняться только в том случае, если доступен сервер MySQL.

Пример 7.2 демонстрирует тестовый класс DatabaseTest, содержащий один тестовый метод testConnection(). В шаблонном методе setUp() тестового класса мы проверяем, доступно ли расширение MySQLi, и используем метод markTestSkipped() для пропуска этого теста в противном случае.

Пример 7.2 Пропуск теста

<?php
use PHPUnit\Framework\TestCase;
class DatabaseTest extends TestCase
{
protected function setUp()
{
if (!extension_loaded('mysqli')) {
$this->markTestSkipped(
'Расширение MySQLi недоступно.'
);
}
}
public function testConnection()
{
// ...
}
}

Пропущенный тест обозначается S в выводе исполнителя тестов командной строки PHPUnit, как показано в следующем примере:

$ phpunit --verbose DatabaseTest
PHPUnit |version|.0 by Sebastian Bergmann and contributors.
S
Time: 0 seconds, Memory: 3.95Mb
There was 1 skipped test:
1) DatabaseTest::testConnection
Расширение MySQLi недоступно.
/home/sb/DatabaseTest.php:9
OK, but incomplete or skipped tests!
Tests: 1, Assertions: 0, Skipped: 1.

Таблица 7.2 показывает API пропущенных тестов.

МетодОписание
void markTestSkipped()Отмечает текущий тест как пропущенный.
void markTestSkipped(string $message)Отмечает текущий тест как пропущенный, используя $message в качестве пояснительного сообщения.

Пропуск тестов с помощью @requires

В дополнение к вышеперечисленным методам можно также использовать аннотацию@requires, чтобы предоставить общие предварительные условия для тестового класса.

Таблица 7.3 Возможные примеры использования @requires

ТипВозможные значенияПримерыДополнительный пример
PHPЛюбой идентификатор версии PHP@requires PHP 5.3.3@requires PHP 7.1-dev
PHPUnitЛюбой идентификатор версии PHPUnit@requires PHPUnit 3.6.3@requires PHPUnit 4.6
OSРегулярное выражения для PHP_OS@requires OS Linux@requires OS WIN32|WINNT
OSFAMILYЛюбое семейство ОС@requires OSFAMILY Solaris@requires OSFAMILY Windows
functionЛюбой корректный параметр для function_exists@requires function imap_open@requires function ReflectionMethod::setAccessible
extensionИмя расширения вместе с необязательным идентификатором версии@requires extension mysqli@requires extension redis 2.2.0

Пример 7.3 Пропуск тестового класса с использованием @requires

<?php
use PHPUnit\Framework\TestCase;
/**
* @requires extension mysqli
*/
class DatabaseTest extends TestCase
{
/**
* @requires PHP 5.3
*/
public function testConnection()
{
// Тест требует расширения mysqli и PHP >= 5.3
}
// ... Все остальные тесты требует расширения mysqli
}

Если вы используете синтаксис, который не компилируется с определённой версией PHP, посмотрите на версии, от которых зависят тестовые классы в XML-конфигурации (см Набор тестов)

https://phpunit.readthedocs.io/ru/latest/incomplete-and-skipped-tests.html