Как писать тесты?

Понятно только как писать тесты к функциям которые что-то валидируют и отвечают true или false
Возьмём классическую регистрацию сайта:
1) Непосредственно регистрация с занесением в БД
2) Верификация email с update в БД поля verification
3) Восстановление забытого пароля на почту (напрямую или с помощью ссылки)
4) Поиск допустим какой ни будь в интернет-магазине по свойствам товара

Как написать тест для чего-то что работает с БД, не говоря уж о тестах вещей которые работают с API?
Верификация email - PHPmailer для отправки сработал, дальше мы не можем ничего протестировать, на этом конец?
Восстановление пароля можно протестировать только если в БД есть хеш который можно по ссылке найти и восстановить пароль. Выходит что тест должен сам для себя предварительно создать хеш в БД, потом обновить пароль, но вход протестировать он всё равно не сможет? У тестов тогда очень сильная завязка на БД получается и при изменении её архитектуры всё надо переписывать?
  • Вопрос задан
  • 3598 просмотров
Решения вопроса 3
nonlux
@nonlux
Ну тесты бываю разными: и зелеными и красными. ))

Все зависит от уровня абстракции, который хочется протестировать. Поэтому тесты и делятся на всяческие классификации. Например: юнит (модульные) тесты, интеграционные тесты и т.д. и т.п.

Я как ярый сторонник BDD использую два типа тестов feature (читай интеграционные тесты) и spec (читай юнит тесты)

Итак, features. Берем Behat и херачем кучу тестов по типу:
Зашел на главную,
Потыкал чего-то в форме регистрации
Зашел в профиль и увидел свое имя и фотку на странице
Profit!

Вот в целом и получили: "Непосредственно регистрация с занесением в БД", только в этой ситуации нам абсолютно не важно что там в БД. Нам важно чтобы пользователь зарегистрировался и попал в закрытый раздел сайта.

Для таких тестов хорошо иметь поддержку окружения (prodaction, development, test) в коде, чтобы например можно было капчу отключить или еще какую сложную лабуду не делать.
Если система замудрена до ужаса придется здесь для тестов все окружение поднимать. А лучще вообще отдать CI такое делать пусть друг трудится.
Плюс таких тестов например когда пишем сложный фронт - сложный бек и еще более сложнейший бек-бек, то можно одним чохом протестировать работу всего сервиса.

Следующий уровень абстракции spec:

Если нам в интеграционных тестах было немного пофиг на БД. Она как бы пишет, но что так за структура абсолютно пофиг. То в случае со спекими нам ВАЩЕ ПОФИГ.
Мы берем наш класс (функцию) и проверяем что за результаты она отдает. Вместо объектов, с которыми подопытный (объект тестируемого класса), даем ему резиновую бабу (моки и т.п), и смотрим на результаты нашего труда.

Главное при том и другом подходе нам без разницы, что у нас в кишках мы всегда тестируем публичные свойства системы. В первом случае это реакция на пользователя, во втором публичное API класса.

Вот как то так!

P.S тесты надо бы писать до кода.
Ответ написан
@xfg
Существуют принципы проектирования позволяющие отделять бизнес-логику от хранения. Тесты будут лаконичные и наименее ломкие. Когда невозможно, мокают методы для работы с бд.

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

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

Почему? Потому что ни какие тесты вам не дадут 100% гарантии, а вот устроить себе вечный ад из поддержки кучи хрупких тестов, которые десятками валятся от малейшего изменения - запросто. Выбираем золотую середину. Вариант выше, дает достаточную уверенность, что скорее всего всё работает как ожидается. Важный функционал тоже работает как ожидается.

Если вы будете покрывать тестами всё, что только можно, я вам гарантирую, вы через месяц начнете выкатываться в продакшн с красными тестами.
Ответ написан
@AlexndrNovikov
Solution Architect in Spiral Scout
Ну вообще под тесты часто заводится отдельная бд, которая заполнена либо тестовыми данными, либо является клоном данных с рабочего сервера, либо заполняется данными перед выполнением теста и очищается после.

Ну а с остальными случаями возможны разные варианты решения. Кого-то устроит просто true, которое вернули из PHPmailer::send(), но можно и получать по POP3 новые письма с ящика, на который отправляли, и ждать прихода нужного, с отвалом с непройденным тестом по таймауту. Зависит от вашего конкретного случая

Ну и разумеется у тестов проекта (не отдельной библиотеки, которая с данными не работает) будет сильная завязка на структуре бд, и при сильном изменении ее структуры/кода связанного с ней тесты упадут, и нужно будет их переписать, ровно как и связанный с ними код, для того они и нужны )
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
EvilsInterrupt
@EvilsInterrupt
System programming, Reversing Engineering, C++
Тесты для кого? Для человека или для машины?
Я к тому, что тесты бывают разными: ручные и автоматические. Про это ничего не сказано в вашем вопросе!

Какие именно тесты нужны? Модульные? Интеграционные? Инсталяции? Нагрузочные? Про это тоже ни слова в вашем вопросе!

Тесты пишут так:
1. Выявляют сначала рабочие сценарии, т.е. когда все хорошо и появляется результат. Есть огромное кол-во ситуаций, когда пользователь готов заплатить забажный продукт, если он хотя 1 раз и 50 запусков сделает ему то, чтобы он делал 3 дня! Сценарии сортируются по:
1.1. компонентам
1.2. приоритету и важности.

После сортировки создают наборы тестов

2. Далее выясняют сценарии, когда что-то не хватает "насяльника сеть упала, что делать?". Другими словами проверить работу позитивных сценариях при возможных негативных случаях, которые быть, но не повине пользователя. Примеры: сеть упала, флешка перстала видеться, в БД вдруг доступ не пускают и др. Особенно смотрят на возможную порчу исходных данных. Был у моего знакомого случая, когда они подбирали пароль к базе данных и случайно затерли пару байтов. ;)

3. Только после этого проверяют "ошибку на дурака". Примеры: вместо текстового файла дали exe-файл. Или вместо числа ввели строку.

Предположу, что вы хотите писать модульные тесты. Скажу следующее что эти типы тестов не должны делать:
1. Проверять работу с БД, диском, сетью
2. Код зависящий от времени

Основной показатель модульного теста это скорость работы. Если тест такого типа работает пол-секунды, то значит вы написали что угодно, но это не модульный тест ;)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы