Каждую проверку, которую мы написали для функции capitalize()
, в тестировании принято называть утверждением (assert).
Утверждения — это ключевая часть тестов. Именно они проверяют функциональность кода:
<?php
// Первое утверждение (проверка на пустую строку)
if (capitalize('') !== '') {
throw new Exception('Функция работает неверно!');
}
// Второе утверждение (проверка на слово)
if (capitalize('hello') !== 'Hello') {
throw new Exception('Функция работает неверно!');
}
Можно заметить, что все проверки строятся одинаковым способом: условие => исключение. PHP внутри себя содержит конструкцию assert()
, которая упрощает написание проверок:
<?php
// Проверка сменилась с отрицательной на положительную
assert(capitalize('') === '');
assert(capitalize('hello') === 'Hello');
Конструкция assert(true)
означает положительный результат, а assert(false)
говорит об ошибке. Последний вариант выбрасывает исключение с таким сообщением:
Fatal error: Uncaught AssertionError: assert(false)
Это сообщение можно перевести так: «Ожидалось, что значением выражения будет истина, но оказалось, что это ложь». Кроме сообщения, выводится бэктрейс, по которому можно найти сработавшее утверждение:
// В этом случае assert сработал на 13 строчке файла index.php
Fatal error: Uncaught AssertionError: assert(false) in /index.php:13
В целом, assert()
сделал наш код короче и проще для восприятия. Положительная проверка смотрится естественнее, потому что это то, что мы ожидаем.
С другой стороны, вывод сообщения об ошибке крайне неинформативный. Для примера попробуем понять, что не так в коде ниже:
# Мы знаем, что тут две переменные
# При этом совершенно не ясно, что находится внутри этих переменных
Fatal error: Uncaught AssertionError: assert($items1 == $items2)
Единственный способ понять, что произошло — открывать код с упавшим утверждением и отлаживать его, выводя значения переменных. Это пытаются исправить с помощью webmozart/assert и других специализированных библиотек. Перепишем код выше с ее использованием:
<?php
use Webmozart\Assert\Assert;
// В строке ниже eq означает equal
Assert::eq(capitalize(''), '');
// Первый параметр actual – то, что пришло
// Второй параметр expected – то, что ожидает тест
// Правильный порядок аргументов имеет большое значение при анализе ошибки
Assert::eq(capitalize('hello'), 'Hello');
Синтаксис Assert::eq()
означает, что перед нами класс Assert, у которого вызывается статический метод (функция) eq()
. К сожалению, в PHP невозможно обойти использование классов даже в начале обучения. Сейчас просто запомните этот синтаксис, а подробнее о нем мы поговорим в курсах по ООП.
Вывод таких утверждений значительно понятнее:
PHP Fatal error: Uncaught InvalidArgumentException:
Expected a value equal to "Hello". Got: null
https://replit.com/@hexlet/php-testing-asserts-capitalize#tests/StringUtilsTest.php
В этом выводе есть не только информация об ошибке, но и данные, которые передавались в утверждение. Такой формат упрощает анализ проблемы и ускоряет отладку.
Для тестирования негативных сценариев предназначена функция Assert::notEq()
. Она тестирует то, что значения не равны:
<?php
Assert::notEq(true, false);
https://replit.com/@hexlet/php-testing-asserts-methods#tests/methodsTest.php
Библиотека webmozart/assert содержит несколько десятков функций-утверждений для разных ситуаций и типов данных. Умение их правильно использовать приходит с опытом и после нескольких попыток чтения документации.
Самостоятельная работа
- Замените в нашем репозитории ручные утверждения на использование библиотеки webmozart/assert
- Запустите тесты и убедитесь, что они работают
- Попробуйте сломать тесты
- Добавьте код на GitHub
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.