Тестирование моментальных снимков — это способ тестирования без написания реальных тестовых примеров.
Вы можете узнать больше в этом бесплатном видео из нашего курса «Тестирование Laravel». Не волнуйтесь, вы можете использовать этот пакет и в проектах, отличных от Laravel.
используйте SpatieSnapshotsMatchesSnapshots;класс OrderTest {use MatchesSnapshots; публичная функция test_it_casts_to_json() {$order = новый заказ(1);$this->assertMatchesJsonSnapshot($order->toJson()); } }
При первом запуске программа запуска тестов создаст новый снимок.
> ./vendor/bin/phpunit There was 1 incomplete test: 1) OrderTest::test_it_casts_to_json Snapshot created for OrderTest__test_it_casts_to_json__1 OK, but incomplete, skipped, or risky tests! Tests: 1, Assertions: 0, Incomplete: 1.
При последующих запусках тест будет пройден до тех пор, пока снимок не изменится.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Если есть регрессия, тест провалится!
$orderId = новый заказ (2); // Регресс! Был `1`
> ./vendor/bin/phpunit 1) OrderTest::test_it_casts_to_json Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ Failed asserting that '{"id":2}' matches JSON string "{ "id": 1 } FAILURES! Tests: 1, Assertions: 1, Failures: 1.
Мы вкладываем много ресурсов в создание лучших в своем классе пакетов с открытым исходным кодом. Вы можете поддержать нас, купив один из наших платных продуктов.
Мы очень признательны вам за отправку нам открытки из вашего родного города с указанием того, какой из наших пакетов вы используете. Наш адрес вы найдете на странице контактов. Все полученные открытки мы публикуем на нашей виртуальной стене открыток.
Вы можете установить пакет через композитор:
композитору требуется --dev spatie/phpunit-snapshot-assertions
Чтобы сделать утверждения моментального снимка, используйте признак SpatieSnapshotsMatchesSnapshots
в своем классе тестового примера. Это добавляет в класс набор методов утверждения:
assertMatchesSnapshot($actual)
assertMatchesFileHashSnapshot($actual)
assertMatchesFileSnapshot($actual)
assertMatchesHtmlSnapshot($actual)
assertMatchesJsonSnapshot($actual)
assertMatchesObjectSnapshot($actual)
assertMatchesTextSnapshot($actual)
assertMatchesXmlSnapshot($actual)
assertMatchesYamlSnapshot($actual)
assertMatchesImageSnapshot($actual)
Давайте сделаем утверждение снимка для простой строки «foo».
общественная функция test_it_is_foo() {$this->assertMatchesSnapshot('foo'); }
При первом запуске утверждения у него нет моментального снимка, с которым можно было бы сравнить строку. Средство запуска тестов создает новый снимок и помечает тест как незавершенный.
> ./vendor/bin/phpunit There was 1 incomplete test: 1) ExampleTest::test_it_matches_a_string Snapshot created for ExampleTest__test_it_matches_a_string__1 OK, but incomplete, skipped, or risky tests! Tests: 1, Assertions: 0, Incomplete: 1.
Идентификаторы снимков генерируются на основе имен теста и тестового набора. Базовые снимки возвращают фактическое значение в виде простого текста или представления YAML.
фу
Давайте повторим тест. Выполняющий тест увидит, что снимок утверждения уже существует, и выполнит сравнение.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Если мы изменим фактическое значение на «bar», тест завершится неудачей, поскольку снимок по-прежнему возвращает «foo».
общественная функция test_it_is_foo() {$this->assertMatchesSnapshot('bar'); }
> ./vendor/bin/phpunit 1) ExampleTest::test_it_matches_a_string Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'foo' +'bar' FAILURES! Tests: 1, Assertions: 1, Failures: 1.
Когда мы ожидаем изменения значения, нам нужно указать средству запуска теста обновить существующие снимки вместо того, чтобы провалить тест. Это возможно, добавив флаг -d --update-snapshots
к команде phpunit
или установив для переменной env UPDATE_SNAPSHOTS
значение true
.
> ./vendor/bin/phpunit -d --update-snapshots OK (1 test, 1 assertion)
В результате наш файл снимка возвращает «bar» вместо «foo».
бар
Признак MatchesSnapshots
предлагает два способа подтвердить, что файл идентичен снимку, сделанному при первом запуске теста:
Утверждение assertMatchesFileHashSnapshot($filePath)
утверждает, что хэш файла, переданного в функцию, и хэш, сохраненный в снимке, совпадают. Это утверждение выполняется быстро и использует очень мало дискового пространства. Обратной стороной этого утверждения является то, что не существует простого способа увидеть, чем отличаются два файла, если тест не пройден.
Утверждение assertMatchesFileSnapshot($filePath)
работает почти так же, как утверждение хэша файла, за исключением того, что оно фактически сохраняет весь файл в каталоге моментальных снимков. Если утверждение не выполнено, файл с ошибкой помещается рядом с файлом моментального снимка, чтобы их можно было легко сравнить вручную. Сохраненный файл с ошибкой автоматически удаляется после прохождения теста. Это утверждение наиболее полезно при работе с двоичными файлами, которые необходимо сравнивать вручную, например с изображениями или PDF-файлами.
Для assertImageSnapshot
необходимо установить пакет spatie/pixelmatch-php.
Это утверждение будет выполнено, если данное изображение почти идентично снимку, сделанному при первом запуске теста. Вы можете настроить порог, передав в утверждение второй аргумент. Более высокие значения сделают сравнение более чувствительным. Порог должен находиться в диапазоне от 0 до 1.
$this->assertMatchesImageSnapshot($imagePath, 0.1);
Идентификаторы снимков генерируются с помощью метода getSnapshotId
признака MatchesSnapshot
. Переопределите метод для настройки идентификатора. По умолчанию существует идентификатор снимка, состоящий из имени теста, имени тестового набора и возрастающего значения, например Test__my_test_case__1
.
__
на --
защищенная функция getSnapshotId(): string{return (new ReflectionClass($this))->getShortName().'--'.$this->name().'--'.$this->snapshotIncrementor; }
По умолчанию снимки хранятся в каталоге __snapshots__
относительно тестового класса. Это можно изменить, переопределив метод getSnapshotDirectory
.
__snapshots__
в snapshots
защищенная функция getSnapshotDirectory(): string{return dirname((new ReflectionClass($this))->getFileName()).DIRECTORY_SEPARATOR.'snapshots'; }
Драйвер, используемый для сериализации данных, можно указать в качестве второго аргумента метода assertMatchesSnapshot
, чтобы вы могли выбрать тот, который лучше соответствует вашим потребностям:
используйте SpatieSnapshotsDriversJsonDriver; используйте SpatieSnapshotsMatchesSnapshots; класс OrderTest {use MatchesSnapshots; общедоступная функция test_snapshot_with_json_driver() {$order = new Order(1);$this->assertMatchesSnapshot($order->toJson(), new JsonDriver()); } }
Драйверы гарантируют, что различные типы данных могут быть сериализованы и сопоставлены по-своему. Драйвер — это класс, реализующий интерфейс SpatieSnapshotsDriver
, для которого требуются три реализации метода: serialize
, extension
и match
.
Давайте кратко рассмотрим JsonDriver
.
пространство имен SpatieSnapshotsDrivers; используйте PHPUnitFrameworkAssert; используйте SpatieSnapshotsDriver; используйте SpatieSnapshotsExceptionsCantBeSerialized; класс JsonDriver реализует драйвер {публичная функция сериализации ($ данные): строка {if (! is_string ($ данные)) {throw new CantBeSerialized («Только строки могут быть сериализованы в json»); } return json_encode(json_decode($data), JSON_PRETTY_PRINT).PHP_EOL; } Расширение публичной функции (): строка {return 'json'; } Соответствие публичной функции ($ ожидаемое, $ фактическое) { Assert::assertJsonStringEqualsJsonString($actual, $expected); } }
Метод serialize
возвращает строку, которая будет записана в файл моментального снимка. В JsonDriver
мы декодируем и перекодируем строку json, чтобы обеспечить качественную печать снимка.
Мы хотим сохранять снимки json в виде файлов json, поэтому будем использовать json
в качестве расширения файла.
При сопоставлении ожидаемых данных с фактическими данными мы хотим использовать встроенные в PHPUnit утверждения json, поэтому мы вызовем конкретный метод assertJsonStringEqualsJsonString
.
Драйверы можно использовать, передав их в качестве второго аргумента метода assertMatchesSnapshot
.
$this->assertMatchesSnapshot($something->toYaml(), new MyYamlDriver());
При запуске тестов в режиме непрерывной интеграции вы, возможно, захотите отключить создание снимков.
Используя параметр --without-creating-snapshots
или установив для переменной env CREATE_SNAPSHOTS
значение false
, PHPUnit завершится ошибкой, если снимки не существуют.
> ./vendor/bin/phpunit -d --без создания снимков 1) Пример теста::test_it_matches_a_string Снимок «ExampleTest__test_it_matches_a_string__1.txt» не существует. Вы можете создать его автоматически, удалив переменную окружения `CREATE_SNAPSHOTS=false` или `-d --no-create-snapshots` из аргументов CLI PHPUnit.
Если вы хотите запустить тест параллельно с таким инструментом, как Paratest, или с командой php artisan test --parallel
Laravel, вам придется использовать переменные среды.
> CREATE_SNAPSHOTS=false php artisan test --parallel 1) Пример теста::test_it_matches_a_string Снимок «ExampleTest__test_it_matches_a_string__1.txt» не существует. Вы можете создать его автоматически, удалив переменную окружения `CREATE_SNAPSHOTS=false` или `-d --no-create-snapshots` из аргументов CLI PHPUnit.
Пользователи Windows должны настроить окончания строк в .gitattributes
.
# Снимки, используемые в тестах, содержат сериализованные данные, и окончание их строк следует оставить неизменнымtest/**/__snapshots__/**binary
Пожалуйста, посетите CHANGELOG для получения дополнительной информации о том, что изменилось за последнее время.
композиторский тест
Пожалуйста, смотрите ВКЛАД для получения подробной информации.
Если вы обнаружили ошибку, связанную с безопасностью, отправьте электронное письмо по адресу [email protected] вместо использования системы отслеживания проблем.
Вы можете свободно использовать этот пакет, но если он попадет в вашу производственную среду, мы будем очень признательны, если вы отправите нам открытку из вашего родного города с указанием того, какой из наших пакетов вы используете.
Наш адрес: Spatie, Kruikstraat 22, 2018, Антверпен, Бельгия.
Все полученные открытки мы публикуем на сайте нашей компании.
Себастьян Де Дейн
Алекс Вандербист
Все участники
Лицензия MIT (MIT). Пожалуйста, смотрите файл лицензии для получения дополнительной информации.