Недавно выступала на Education Day в нашей компании, рассказывала о тест-дизайне на примере треугольника. Какие тесты можно написать? В частности, можно логически прикинуть, что треугольники бывают разные - равнобедренные, равносторонние, разносторонние.
И в конце один разработчик спросил "А зачем нам проверять, равносторонний треугольник или разносторонний, если нам площадь нужна? Это же одинаковые тесты". Иногда - да. Но, когда мы тестируем черный ящик, мы никогда не знаем заранее, а программистам, как известно, верить нельзя
Расскажу историю из жизни, подтвердившую эту теорию не далее как сегодня.
Есть у нас, значит, некий калькулятор. Не в смысле виндового калькулятора, а просто есть 8 разных атрибутов (а1, а2, а3... а8), у каждого свой вес и общий должен быть равен 100%.
Атрибутика имеет свои типы и мы хотим, чтобы было неважно, сколько у нас атрибутов типа а4, если у него вес 40, то он будет 40, будет у нас один а4, два или больше.
Такой вот алгоритм. В требованиях указываем эти веса, отдаем разработчику. Он выполняет, передает задачу мне.
Как будем тестировать? В моем случае - автоматизировать.
И в конце один разработчик спросил "А зачем нам проверять, равносторонний треугольник или разносторонний, если нам площадь нужна? Это же одинаковые тесты". Иногда - да. Но, когда мы тестируем черный ящик, мы никогда не знаем заранее, а программистам, как известно, верить нельзя
Расскажу историю из жизни, подтвердившую эту теорию не далее как сегодня.
Есть у нас, значит, некий калькулятор. Не в смысле виндового калькулятора, а просто есть 8 разных атрибутов (а1, а2, а3... а8), у каждого свой вес и общий должен быть равен 100%.
Атрибутика имеет свои типы и мы хотим, чтобы было неважно, сколько у нас атрибутов типа а4, если у него вес 40, то он будет 40, будет у нас один а4, два или больше.
Такой вот алгоритм. В требованиях указываем эти веса, отдаем разработчику. Он выполняет, передает задачу мне.
Как будем тестировать? В моем случае - автоматизировать.
- Сначала выполняем модульные тесты, дергаем каждый атрибут в отдельности и убеждаемся, что у калькулятор выдает вес данного конкретного атрибута.
- Потом проверяем, что если вобьем парочку, будет сумма.
- Потом проверяем, что сумма всех-всех-всех будет 100%.
- Потом проверяем, что если у нас 2 атрибута а4, то результат его вес учитывается 1 раз.
- Потом проверяем негативные тесты (если нюансы в алгоритме).
Ну вот примерный список на алгоритм. А реализация алгоритма тоже разная. Можно создать разными способами, можно отредактировать, можно удалить атрибуты...
Но начать, конечно, надо с простых проверок алгоритма. И вот я начинаю писать тесты:
- Только а1
- Только а2
- Только а3
Потом у меня возникает некий вопрос в реализации и я обращаюсь к разработчику:
Ольга Киселева: Привет! Слушай, имеет ли смысл тестировать вот это и это в обоих методах, или они примерно одинаковы, пишем основные тесты в одном месте, а во втором парочку базовых, чтобы не копипастить лишнего? Отличаются ли эти методы?
Разработчик: Помни что формула расчета полностью покрывается юнит-тестами.
Разработчик: Не сильно, все рассчитывается в одном месте.
Упс, думаю я, то есть я тут начала лишнюю работу делать, раз алгоритм уже покрыт. И правда, сам алгоритм можно оставить на уровне unit-тестов.
А мне уже ограничиться парой базовых тестов на алгоритм (потому что API-тесты на уровне выше и там уже все почти по-честному, надо все-таки проверить, что логика в принципе работает на этом уровне), а потом начать извращаться с реализацией...
Но интересно жеж! Дай-ка, думаю, посмотрю, что ты там понаписал. Благо, в JIRA есть у нас закладка Mercurial Commits и я могу отследить, что там разработчик накоммитил. Смотрю, ага! CalcTest.java - то, что надо.
Открываю, начинаю читать... И что я там вижу? Каких-то жалких 3 теста!!!
Один на одиночный атрибут а1, второй на сумму а1 + а2 + а3 и полная сумма, 100%.
Разговариваем дальше:
Ольга Киселева: и это ВСЕ? О_О
Ольга Киселева: 3 тестика?!
Ольга Киселева: то есть мне основные тесты в этот класс написать, да? В API парочку, чтобы на верхнем уровне тоже поймать, да?
Разработчик: ага
Разработчик: много тестов не значит хорошо
Разработчик: эти 3 теста все покрывают))
Ольга Киселева: 3 тестика!!!
Ольга Киселева: ничего они не покрывают) у тебя четкие требования на каждый атрибут 1 число, а ты 1 число проверил и пошел сумму фигачить
Ольга Киселева: сумма тоже важна
Ольга Киселева: но отдельно каждое число
Ольга Киселева: отдельно сумма ]:)
Ольга Киселева: сама напишу)
Разработчик: пиши, но ваще сумма такая весчь, она слагается из кусочков
Вот так вот отдавать проверку алгоритма на откуп разработчика. А если бы у меня не было доступа к коду? Если бы я тестировала вручную, допустим? Вот поверишь, что весь алгоритм уже покрыт, не проверишь и все...
А это запросто - разработчики у нас классные, продвинутые, код пишут хорошо, быстро и качественно. И unit-тесты пишут сами, а не из-под палки. И ничего. Так что я почти поверила, что мне алгоритм тестировать не нужно...
Нет, оно, конечно, работает. Но автотесты зачем нужны? Чтобы ты потом внес изменение и у тебя отъехали тесты, показав, что ты задел эту часть, этот модуль.
А ведь мы можем изменить код так, чтобы у нас ничего не упало. Например, перепутать коэффициенты а3 и а2. У нас написан тест на а1 + а2 + а3. И он пройдет, все же хорошо, от перемены мест слагаемых сумма не меняется.
Чувствуете, да? Мы вносим изменения, может быть, даже ломаем где-то алгоритм, и ни один тест не упал. Что это значит? Что наши изменения ничего не сломали, вручную можно даже не проверять. И только потом, на регрессии кто-нибудь случайно ткнет и обнаружит ошибку. А может, и не ткнет, покрыто ж автотестами...
Нерадостная перспективка
Отсюда делаем вывод - разработчикам верить нельзя!! Особенно, когда они говорят "это полностью покрыто unit-тестами", ага, полностью... Вот сижу сейчас и наслаждаюсь, что могу на нижнем уровне нафигачить тестов, без всяких дополнительных параметров. А там ведь даже сам алгоритм можно и так повернуть, и сяк, и вот так! Ух! Так интересно А они - 3 тестика...