Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Утверждения (Asserts) PHP: Автоматическое тестирование

Каждую проверку, которую мы написали для функции 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 содержит несколько десятков функций-утверждений для разных ситуаций и типов данных. Умение их правильно использовать приходит с опытом и после нескольких попыток чтения документации.

Самостоятельная работа

  1. Замените в нашем репозитории ручные утверждения на использование библиотеки webmozart/assert
  2. Запустите тесты, убедитесь что они работают. Попробуйте их сломать
  3. Добавьте код на гитхаб

Дополнительные материалы

  1. Assert

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 120 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
20 октября 8 месяцев

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»