Как сделать тест в php
2. Написание тестов на PHPUnit
Пример 2.1 показывает, как мы можем писать тесты, используя PHPUnit, которые выполняют операции с массивом PHP. В этом примере представлены основные соглашения и шаги для написания тестов с помощью PHPUnit:
Кроме того, вы можете использовать аннотацию @test в докблоке метода, чтобы пометить его как метод тестирования.
Внутри тестовых методов для проверки того, соответствует ли фактическое значение ожидаемому используются методы-утверждения, такие как assertSame() (см. Утверждения ).
Зависимости тестов
Адриан Кун (Adrian Kuhn) и другие:
Модульные тесты главным образом пишутся в качестве хорошей практики, помогающей разработчикам выявлять и исправлять баги, проводить рефакторинг кода и служить в качестве документации для тестируемого программного модуля (программы). Для достижения этих преимуществ модульные тесты в идеале должны охватывать все возможные пути исполнения программы. Один модульный тест обычно покрывает один конкретный путь в одной функции или методе. Однако тестовые методы необязательно должны быть инкапсулированными и независимыми. Часто существуют неявные зависимости между тестовыми методами, скрытые в сценарии реализации теста.
PHPUnit поддерживает объявление явных зависимостей между тестовыми методами. Эти зависимости не определяют порядок, в котором должны выполняться тестовые методы, но они позволяют возвращать экземпляр (данные) фикстуры теста, созданные поставщиком (producer) для передачи его зависимым потребителям (consumers).
Пример 2.2 показывает, как использовать аннотацию @depends для представления зависимостей между тестовыми методами.
Провайдеры данных
Метод провайдера данных должен быть объявлен как public и возвращать либо массив массивов, либо объект, реализующий интерфейс Iterator и возвращать массив при каждой итерации. Для каждого массива, являющегося частью коллекции, будет вызываться тестовый метод с элементами массива в качестве его аргументов.
При использовании большого количества наборов данных полезно указывать для каждого из них строковый ключ, вместо использования числового ключа по умолчанию. Вывод станет более подробным, так как он будет содержать имя набора данных, не прошедший тест.
Юнит-тестирование на PHP в примерах
Содержание
Тестовые дубли
Это фальшивые зависимости, используемые в тестах.
Заглушки (Stub)
Имитатор (Dummy)
Имитатор — всего лишь простая реализация, которая ничего не делает.
Фальшивка (Fake)
Фальшивка — это упрощённая реализация, эмулирующая нужное поведение.
Заглушка (Stub)
Заглушка — это простейшая реализация с прописанным в коде поведением.
Моки (Mock)
Шпион (Spy)
Шпион — реализация для проверки конкретного поведения.
Мок (Mock)
Мок — сконфигурированная имитация для проверки вызовов взаимодействующих объектов.
! Для проверки входящий взаимодействий используйте заглушку, а для проверки исходящих взаимодействий — мок. Подробнее об этом в главе Моки и заглушки.
Наименования
Явно указывайте, что вы тестируете.
Описание поведения важно при тестировании предметных сценариев. Если ваш код утилитарный, то это уже не так важно.
Почему важно, чтобы непрограммисты могли читать юнит-тесты? Если в проекте сложная предметная логика, то эта логика должна быть очевидна для всех, а для этого тесты должны описывать подробности без технических терминов, чтобы вы могли говорить с представителями бизнеса на том же языке, что используется в тестах. Освободите от терминов и весь код, связанный с предметной областью, иначе непрограммисты не смогут понять эти тесты. Не надо писать в комментариях «возвращает null», «бросает исключение» и т.д. Такая информация не относится к предметной области.
Шаблон AAA
Также известен как «Given, When, Then».
Выделяйте в тестах три этапа:
Мать объекта
Этот шаблон помогает создавать конкретные объекты, которые можно использовать в нескольких тестах. Благодаря этому этап «arrange» получается кратким, а весь тест — более удобочитаемым.
Параметризированный тест
Параметризированный тест — хороший способ тестирования SUT с многочисленными параметрами без повторения кода. Но такие тесты менее удобочитаемые. Чтобы немного улучшить ситуацию, отрицательные и положительные примеры нужно раскидать по разным тестам.
Две школы юнит-тестирования
Классическая (Детройтская школа)
Моковая (Лондонская школа)
Классический подход лучше позволяет избегать хрупких тестов.
Зависимости
Моки и заглушки
Три стиля юнит-тестирования
Результат
Состояние
Взаимодействие
Функциональная архитектура и тесты
Как тестировать подобный код? Это можно сделать только с помощью интеграционных тестов, потому что они напрямую используют инфраструктурный код, относящийся к файловой системе.
Как и в функциональной архитектуре, нам нужно отделить код с побочными эффектами от кода, который содержит только логику.
Наблюдаемое поведение и подробности реализации
Единица поведения
Не пишите код 1:1: один класс — один тест. Это приводит к хрупким тестам, что затрудняет рефакторинг.
Шаблон humble
Как правильно выполнять юнит-тестирование такого класса?
Нужно разбить чрезмерно усложнённый код на отдельные классы.
Бесполезный тест
Тестировать код, не содержащий какой-либо сложной логики, не только бессмысленно, но и приводит к хрупким тестам.
Хрупкий тест
Подобное тестирование репозиториев приводит к хрупким тестам и затрудняет рефакторинг. Тестируйте репозитории с помощью интеграционных тестов.
Исправления тестов
Общие антипаттерны тестирования
Раскрытие приватного состояния
Внесение дополнительного production-кода (например, метода-получателя getCustomerType() ) только ради проверки состояния в тестах — плохая практика. Состояние нужно проверять другим важным предметным значением (в этом случае — getPercentageDiscount() ). Конечно, иногда трудно найти другой способ проверки операции, и мы можем оказаться вынуждены внести дополнительный production-код для проверки корректности тестов, но нужно стараться избегать этого.
Утечка подробностей о предметной области
Не дублируйте в тестах production-логику. Проверяйте результаты с помощью прописанных в коде значений.
Мокинг конкретных классов
Необходимость мокать конкретный класс для замены части его поведения означает, что этот класс, вероятно, слишком сложен и нарушает принцип единственной ответственности.
Тестирование приватных методов
Тесты должны проверять только публичный API.
Время как непостоянная зависимость
Время является непостоянной зависимостью из-за своего недетерминизма. Каждый вызов даёт другой результат.
В коде, относящемся к предметной области, нельзя напрямую генерировать время и случайные числа. Для проверки поведения нужны детерминистские результаты, поэтому нужно внедрять эти значения в объект, относящийся к предметной области, как в примере выше.
Не гонитесь за полным покрытием
Полное покрытие не является целью, или даже не желательно, потому что в противном случае тесты наверняка будут очень хрупкими, а рефакторинг — очень сложным. Мутационное тестирование даёт более полезную обратную связь о качестве тестов. Подробнее.
Зачем и как писать тесты? — PHP: Автоматическое тестирование
Какую главную задачу должны решать тесты? Этот вопрос невероятно важен. Ответ на него даёт понимание того, как правильно писать тесты и как писать их не нужно.
Вот один из вариантов её реализации:
Что мы делаем после создания функции? Проверяем, как она работает. Например, открываем REPL и вызываем функцию с разными аргументами:
Таким нехитрым способом убеждаемся, что функция работает. По крайней мере для тех аргументов, которые мы передали в неё. Если во время проверки заметили ошибки, то исправляем функцию и повторяем всё заново.
Фактически, весь этот процесс и есть тестирование. Но не автоматическое, а ручное. Задача такого тестирования — убедиться, что код работает, как надо. И нам совершенно без разницы, как конкретно реализована эта функция. Это и есть главный ответ на вопрос, заданный в начале урока.
Тесты проверяют, что код (или приложение) работает корректно. И не заботятся о том, как конкретно написан код, который они проверяют.
Автоматические тесты
Всё, что требуется от автоматических тестов — повторить проверки, которые мы выполняли, делая ручное тестирование. Для этого достаточно старого доброго if и исключений.
Даже если вы не знакомы с исключениями, ничего страшного. В этом курсе достаточно знать две вещи: для чего они нам нужны и какой у них синтаксис. До сих пор в курсах Хекслета вы встречались с ошибками, которые возникают непроизвольно: вызов несуществующей функции, обращение к несуществующей переменной и так далее. Но ошибки можно порождать самостоятельно с помощью исключений, что необходимо для нашей ситуации. Исключения создаются такой конструкцией:
Из примера выше видно, что тесты — это точно такой же код, как и любой другой. Он работает в том же окружении и подчиняется тем же правилам, например, стандартам кодирования. А ещё он может содержать ошибки. Но это не значит, что надо писать тесты на тесты. Избежать всех ошибок невозможно, да и не нужно, иначе стоимость разработки стала бы неоправданно высокой. Обнаруженные ошибки в тестах исправляются, и жизнь продолжается дальше 😉
В коде тесты, как правило, складывают в специальную директорию в корне проекта. Обычно она называется tests, хотя встречаются и другие варианты:
Структура этой директории зависит от того, на базе чего пишутся тесты, например, на базе какого фреймворка. В простых случаях она отражает структуру исходного кода. Если предположить, что наша функция capitalize($text) определена в файле src/StringUtils.php, то её тест лучше поместить в файл tests/StringUtilsTest.php. Слово Test в имени модуля с тестами используется только для более явного обозначения цели файла.
Теперь при любых изменениях, затрагивающих эту функцию, важно не забывать запускать тесты:
Как пишутся тесты
Тесты — это не магия. Нам, как разработчикам, нужно самостоятельно импортировать тестируемые функции, вызывать их с необходимыми аргументами и проверять, что функции возвращают ожидаемые значения.
Если поменялась сигнатура функции (входные или выходные параметры, её имя), то придётся переписывать тесты. Если сигнатура осталась той же, но поменялись внутренности функции:
Тогда тесты должны продолжать работать без изменений. Хорошие тесты ничего не знают про внутреннее устройство проверяемого кода. Это делает их более универсальными и надёжными.
Сколько и какие нужно писать проверки?
Невозможно написать тесты, которые гарантируют 100% работоспособность кода. Для этого потребовалось бы реализовать проверки всех возможных аргументов, что физически неосуществимо. С другой стороны без тестов вообще нет никаких гарантий, только честное слово разработчиков.
При написании тестов нужно ориентироваться на разнообразие входных данных. У любой функции есть один или несколько основных сценариев использования. Например, в случае capitalize() — это любое слово. Достаточно написать ровно одну проверку, которая покрывает этот сценарий. Дальше нужно смотреть на «пограничные случаи». Это ситуации, в которых код может повести себя по-особенному:
Для capitalize() пограничным случаем будет пустая строка:
Добавив тест на пустую строку, мы увидим, что вызов показанной в начале урока функции capitalize() завершается с ошибкой. Внутри неё идёт обращение к первому индексу строки без проверки его существования. Исправленная версия кода:
В большом числе ситуаций пограничные случаи требуют отдельной обработки, наличия условных конструкций. Тесты должны быть построены таким образом, чтобы они затрагивали каждую такую конструкцию. Но не забывайте, что условные конструкции могут порождать хитрые связи. Например, два независимых условных блока порождают 4 возможных сценария:
Комбинация всех возможных вариантов поведения функции называется цикломатической сложностью. Это число показывает все возможные пути выполнения программы внутри функции. Цикломатическая сложность — хороший ориентир для понимания того, сколько и какие тесты нужно написать.
Иногда пограничные случаи не связаны с условными конструкциями. Особенно часто такие ситуации встречаются там, где есть вычисления границ слов или массивов. Такой код может работать в большинстве ситуаций, но только в некоторых может давать сбой:
Проверка входных данных
Особняком стоят ошибки типов входных данных. Например, в функцию capitalize() можно передать число вместо строки. Как она должна себя вести в таком случае? Нужно ли писать такой тест?
Ещё один интересный вопрос. Нужно ли внутри capitalize обрабатывать такие ситуации? Ответ — не нужно. Иначе код превратится в мусорку, а пользы от этого мало. Всё равно должны быть тесты, которые проверяют, что система работает в целом, а они обычно выявляют проблемы кода на более нижних уровнях.
Ответственность за передачу правильных данных в функцию capitalize() лежит не на ней, а на коде, который вызывает эту функцию. И если он хорошо протестирован, то подобная ошибка либо обнаружится, либо вообще не возникнет.
Но даже если ошибка обрабатывается внутри функции, не надо пытаться написать тесты, покрывающие каждую ошибку. Это выливается в огромное число тестов, которые требуют поддержки и времени на написание. Нужно уметь вовремя остановиться и двигаться дальше, к покрытию другого кода.
Собирая всё вместе
В конечном итоге мы получили такую структуру директорий:
Если всё написано правильно, то запуск тестов завершится с выводом строки Все тесты пройдены! Если в тестах или в коде есть ошибка, то сработает исключение и мы увидим сообщение, указывающее на это.
Самостоятельная работа
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Как создать онлайн тест на php
Иногда людям не знающим программирования, нужно создать онлайн тест на php для своего сайта, на самом деле все очень просто, постараюсь наглядно объяснить.
Для решения данной задачи мы будем использовать простую HTML форму и POST запросы. И так приступим.
1. Нам потребуется создать файл php, в общем по сути не важно, если вы используете CMS, то пишете там, где можно вставить php код.
2. Создадим простую форму с полями «radio», то есть для выбора вариантов ответа и кнопкой для результатов.
В результате получим:
3. Отлично мы создали форму. Теперь в неё нужно внести изменения, чтобы она работала.
Добавим атрибуты к форме.
5. А теперь пропишем имя ответов к каждому варианту, например ‘value = «a»‘
В результате получим:
6. Создадим файл result.php в том же каталоге, в котором создадим скрипт теста на php для обработки и вывода результата правильных и не правильных ответов.
7. Перед html кодом добавим скрипт php:
8. Теперь выводим на страницу в html коде правильные и неправильные ответы:
Заключение. Теперь у вас есть простой тест на php и html, теперь можно и запустить его для онлайн. Вы можете добавить сколько угодно вариантов ответов по аналогии. Добавить стилей и улучшить код. Можно было все сделать намного грамотней, но проще этого не придумаешь. Работа у теста такая: выбрали варианты, нажали на кнопку «результат», нас перекидывает на вторую страницу, где выводится подсчет правильных и неправильных ответов. Удачи!
Юнит-тестирование в PHP
Язык PHP очень легок для изучения. Это, а так же обилие литературы «Освой _что_угодно_ за 24 часа» породило большое количество, мягко говоря, некачественного кода. Как следствие, рано или поздно любой программист, который выходит за рамки создания гостевой книги или сайта-визитки сталкивается с вопросом: «а если я здесь немножко добавлю, все остальное не ляжет?» Дать ответ на этот вопрос и на многие другие может юнит-тестирование.
В самом начале хочется оговориться — здесь речь не будет идти о TDD и методологиях разработки ПО. В данной статье я попробую показать начинающему PHP-разработчику основы использования модульного тестирования на базе фреймворка PHPUnit
Вместо предисловия
Вначале возникает вполне резонный вопрос: А зачем, если все и так работает?
Здесь все просто. После очередного изменения что-то перестанет работать так как надо — это я вам обещаю. И тогда поиск ошибки может отнять очень много времени. Модульное тестирование может свести этот процесс к считанным минутам. Не будем так же исключать переезд на другую платформу и связанные с ним «подводные камни». Чего только стоит разность в точности вычислений на 64- и 32-разрядных системах. А когда-то вы в первый раз столкнетесь с нюансами вроде
Если вопрос необходимости отпал, то можно приступить к выбору инструмента. Здесь ассортимент в общем-то невелик — PHPUnit (http://www.phpunit.de/) и SimpleTest (http://www.simpletest.org/). Поскольку PHPUnit уже стал стандартом де-факто в тестировании PHP приложений, то на нем и остановимся.
Первое знакомство
Вопросы установки рассматривать не будем: все достаточно внятно изложено на сайте. Попробуем лучше понять, как это все работает.
Допустим, есть у нас некий класс «MyClass», одним из методов реализующий возведение числа в степень. (Здесь вынужден извиниться, но все примеры, в общем-то, высосаны из пальца)
Хочется проверить, правильно ли он работает. О всем классе речь пока не идет — только об одном методе. Напишем для проверки такой тест.
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
$ phpunit MyClassTest
.
Time: 0 seconds
OK (1 test, 1 assertion)
Результат выполнения теста «ОК». Казалось бы можно остановиться на этом, но иногда было бы неплохо для проверки скормить методу не один набор данных. PHPUnit предоставляет нам такую возможность — это провайдеры данных. Провайдер данных тоже является паблик-методом (название не существенно), который возвращает массив наборов данных для каждой итеррации. Для использования провайдера необходимо указать его в теге @dataProvider к тесту.
Изменим наш тест следующим образом:
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
После запуска увидим следующую картину:
Опишу подробнее. Точка, которую в первом выводе теста многие могли принять за опечатку на самом деле таковой не является — это успешно пройденный тест. F(ailure) — соответственно тест не пройденный. Значит в данном случае, было проведено 3 теста, один из который завершился неудачно. В расширенном описании нам было сказано, какой именно, с каким набором исходных данных, с каким реальным и каким ожидаемым результатом. Если бы 2 3 действительно равнялось 9-ти, то мы увидели бы таким образом ошибку в нашем сценарии.
Здесь, как мне кажется, есть смысл отвлечься от несколько абстрактной практики и перейти ко вполне конкретной теории. А именно, описать какими же assert-методами мы располагаем для проверки поведения тестируемых сценариев.
Два самых простых — это assertFalse() и assertTrue(). Проверяют, является ли полученное значение false и true соответственно. Далее идут уже упомянутый assertEquals() и обратный ему assertNotEquals(). В их использовании есть нюансы. Так при сравнении чисел с плавающей точкой есть возможность указать точность сравнения. Так же эти методы используются для сравнения экземпляров класса DOMDocument, массивов и любых объектов (в последнем случае равенство будет установлено, если атрибуты объектов содержат одинаковые значения). Так же следует упомянуть assertNull() и assertNotNull() которые проверяют соответствие параметра типу данных NULL (да-да, не забываем, что в PHP это отдельный тип данных). Этим возможные сравнения не ограничиваются. Нет смысла в рамках этой статьи заниматься перепечаткой документации, потому приведу по возможности структурированный список всех возможных методов. Более детально интересующиеся могут прочитать здесь
Базовые методы сравнения
assertTrue() / assertFalse()
assertEquals() / assertNotEquals()
assertGreaterThan()
assertGreaterThanOrEqual()
assertLessThan()
assertLessThanOrEqual()
assertNull() / assertNotNull()
assertType() / assertNotType()
assertSame() / assertNotSame()
assertRegExp() / assertNotRegExp()
Методы сравнения массивов
assertArrayHasKey() / assertArrayNotHasKey()
assertContains() / assertNotContains()
assertContainsOnly() / assertNotContainsOnly()
ООП специфичные методы
assertClassHasAttribute() / assertClassNotHasAttribute()
assertClassHasStaticAttribute() / assertClassNotHasStaticAttribute()
assertAttributeContains() / assertAttributeNotContains()
assertObjectHasAttribute() / assertObjectNotHasAttribute()
assertAttributeGreaterThan()
assertAttributeGreaterThanOrEqual()
assertAttributeLessThan()
assertAttributeLessThanOrEqual()
Методы сравнения файлов
assertFileEquals() / assertFileNotEquals()
assertFileExists() / assertFileNotExists()
assertStringEqualsFile() / assertStringNotEqualsFile()
Методы сравнения XML
assertEqualXMLStructure()
assertXmlFileEqualsXmlFile() / assertXmlFileNotEqualsXmlFile()
assertXmlStringEqualsXmlFile() / assertXmlStringNotEqualsXmlFile()
assertXmlStringEqualsXmlString() / assertXmlStringNotEqualsXmlString()
Разное
assertTag()
assertThat()
Исключения
Если еще не надоело, то вернемся к практике, а именно к обработке исключений. Для начала модифицируем наш тестируемый класс — введем в него метод, который будет это исключение выбрасывать.
class MathException extends Exception < >;
Теперь надо создать тест, который будет завершаться успешно в том случае, если при определенном наборе данных будет вызвано это исключение. Задать требуемое исключение можно как минимум двумя способами — добавив к тесту @expectedException либо вызвав в тесте метод setExpectedException().
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
Тесты, в общем-то, абсолютно идентичны. Выбор способа остается на ваше усмотрение. Помимо механизмов предоставляемых непосредственно PHPUnit, для тестирования исключений можно воспользоваться стандартным try <…>catch (), к примеру, так:
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
В этом примере мы так же видим не рассмотренный ранее способ завершения теста с помощью вызова метода fail(). Вывод теста будет следующим:
F
Time: 0 seconds
There was 1 failure:
1) testDivision3(MyClassTest)
Not raise an exception
/home/user/unit/MyClassTest.php:50
Принадлежности
Базовые методы тестирования мы освоили. Можно ли улучшить наш тест? Да. Написанный c начала этой статьи класс проводит несколько тестов, в каждом из которых создается экземпляр тестируемого класса, что абсолютно излишне, потому как PHPUnit предоставляет в наше пользование механизм принадлежностей теста (fixtures). Установить их можно защищенным методом setUp(), который вызывается один раз перед началом каждого теста. После окончания теста вызывается метод tearDown(), в котором мы можем провести «сборку мусора». Таким образом, исправленный тест может выглядеть так:
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
Наборы тестов
После того, как код нескольких классов будет покрыт тестами, становится довольно таки неудобно запускать каждый тест по отдельности. Здесь нам на помощь могут прийти наборы тестов — несколько связанных единой задачей тестов можно объединить в набор и запускать соответственно его. Наборы реализованы классом PHPUnit_Framework_TestSuite. Необходимо создать экземпляр этого класса и добавить в него необходимые тесты с помощью метода addTestSuite(). Так же с помощью метода addTest() возможно добавление другого набора.
require_once ‘PHPUnit/Framework.php’ ;
// подключаем файлы с тестами
require_once ‘MyClassTest.php’ ;
require_once ‘PHPUnit/Framework.php’ ;
// подключаем файл с набором тестов
require_once ‘SpecificTests.php’ ;
А теперь представим себе набор тестов для сценария, работающего с БД. Неужели нам в каждом тесте придется подключаться к базе? Нет — не придется. Для этого можно создать свой класс унаследованный от PHPUnit_Framework_TestSuite, определить его методы setUp() и tearDown() для инициализации интерфейса БД и просто передать его в тест атрибутом sharedFixture. Базы данных мы оставим на потом, а пока попробуем создать собственный набор тестов для уже имеющегося класса.
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘MyClass.php’ ;
class MyClassTest extends PHPUnit_Framework_TestCase <
class MySuite extends PHPUnit_Framework_TestSuite <
Здесь мы в sharedFixture положили экземпляр тестируемого класса, а в тесте просто его использовали — решение не слишком красивое (я бы даже сказал, вообще не красивое), но общее представление о наборах тестов и передаче принадлежностей между тестами оно дает. Если наглядно изобразить очередность вызова методов, то получится нечто вроде такого:
MySuite::setUp()
MyClassTest::setUp()
MyClassTest::testPower()
MyClassTest::tearDown()
MyClassTest::setUp()
MyClassTest::testDivision()
MyClassTest::tearDown()
.
MySuite::tearDown()
Дополнительные возможности
Помимо всего вышеизложенного может возникнуть необходимость проверить не только расчеты и поведение сценария, но так же вывод и скорость отработки. Для этого в наше распоряжение предоставлены расширения PHPUnit_Extensions_OutputTestCase и PHPUnit_Extensions_PerformanceTestCase соответственно. Добавим в наш тестируемый класс еще один метод, и проверим правильно ли он работает.
require_once ‘PHPUnit/Framework.php’ ;
require_once ‘PHPUnit/Extensions/OutputTestCase.php’ ;
require_once ‘PHPUnit/Extensions/PerformanceTestCase.php’ ;
require_once ‘MyClass.php’ ;
class MyClassOutputTest extends PHPUnit_Extensions_OutputTestCase <
class MyClassPerformanceTest extends PHPUnit_Extensions_PerformanceTestCase <
class MyClassTest extends PHPUnit_Framework_TestCase <
Задать ожидаемый вывод сценария можно с помощью методов expectOutputString() или expectOutputRegex(). А для метода setMaxRunningTime() планируемое время отработки указывается в секундах. Для того, что бы эти тесты запускались вместе с уже написанными их всего лишь надо добавить к нашему набору:
class MySuite extends PHPUnit_Framework_TestSuite <
Пропускаем тесты
И напоследок рассмотрим ситуацию, в которой некоторые тесты необходимо пропускать по каким либо причинам. К примеру в том случае, когда на тестируемой машине отсутствует какое-либо расширение PHP, можно убедившись в его отсутствии пометить тест, как пропущенный добавив к его коду следующее:
Либо в том случае, когда тест написан для кода, которого еще нет в сценарии (не редкая для TDD ситуация) его можно пометить как не реализованный с помощью метода markTestIncomplete()