Тесты нужно писать для того, чтобы они тестировали


2 0

Меня поражает, когда люди создают тесты, чтобы они просто были. Протестировать только один или два удачных случая – это наверно круто, но не решает практически никакой задачи. 

Если писать тесты только для того, чтобы создать видимость работы, то это будет совершенно пустая трата времени. Да, начальство может быть и восхитится тем, что вы написали какой-то тест, но на сколько вам проще после этого сопровождать код? 

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

Лично я обожаю писать интеграционные тесты, которые используют базу данных и когда бизнес логика тестируется от начала до конца. Единственное, что остается в стороне – это пользовательский интерфейс. 

У нас в компании я вижу большинство пишет только unit тесты, которые тестируют конкретную функцию без затрагивания базы данных или делают автоматизацию уже тестирования всего сайта, когда Selenium загружает сайт и очень медленно тестирует функционал. 

Я плохо отношусь к Selenium тестам, потому что они оставляют в базе данных мусор и нужен какой-то метод избавляться от него, например восстанавливать базу данных перед каждым тестом. В случае с интеграционными тестами – их можно писать на том же языке, что и бизнес логика и тут можно создавать транзакцию, делать что-то в базе данных, откатывать транзакцию и в результате в базе данных ничего не остается. 

Интеграционные тесты я отличаю от Unit тестов только тем, что в интеграционных тестируется весь функционал, а не отдельный метод. 

Есть такое мнение, что нужно писать чистые unit тесты не трогая базы данных. Моя политика - желательно писать тесты, которые не работают с базой. Но если работа с базой данных необходима, то почему бы не использовать ее? 

Ну да, если работать с базой, то выполнение немного замедляется, потому что больше требуется времени, но не сильно. У меня сейчас проект с 120 тестами и на из выполнение нужно всего пару минут. 

Буквально пару недель назад мне пришлось переписать сложную логику, на отладку которой код назад ушел целый месяц. Мы долго тестировали тогда, искали проблемные места и в конце концов нашли получили что-то рабочее. Сейчас наверно никто не решился бы трогать этот функционал, потому что там как минимум 50 различных вариаций (а может и больше) бизнес логики с разными результатами, но менять нужно было, потому что сильно изменилось требование и старый код не могу удовлетворять уже новым требованиям. 

Чтобы не так страшно было менять код, я начал писать тесты. Я написал около 30 тестов для существующего код и убедился, что в результате их выполнения везде горит зеленый свет. 

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

Через три дня работы у меня была готова новая реализация той же бизнес логики и все тесты выполнялись на ура. 

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

Прежде чем фиксить баг, я всегда пишу тест и убеждаюсь, что я могу воспроизвести им проблему. Я никогда не пишу тесты до того, как начну начальную разработку, но всегда пишу тесты до того, как начну фиксить баги. Для двух багов я написал еще тестов 10, потому что нашел еще несколько случаев, которые не были покрыты, потом исправил баги и убедился, что все мои тесты выполняются без ошибок. 

Тесты – это самый лучший способ переписать устаревший код, который никто не хочет трогать. 

Тесты нужно писать, чтобы они реально тестировали, а не просто присутствовали в системе. Сколько раз я видел, как программисты пишут тест, который выполняет только одну проверку и забывают про него. А через полгода запускаешь все тесты, и узнаешь, что половина из них не работает, потому что уже устарели или даже присутствуют баги. Не понимаю, когда говорят, что поддерживать тесты очень напряжно. Писать код без тестов – вот это напряжно, страшно и опасно. Я не люблю изменять код, который я на 100% не знаю. Да даже в тех случаях, когда я знаю код, я не люблю его изменять, если нет тестов, потому что потом приходится вручную проверять все, нужно вспоминать, какие нужно варианты учесть, на что посмотреть. Я программист, я не люблю тестировать вручную, но я люблю все автоматизировать. 

Пишите тесты не для того, чтобы они просто присутствовали в системе, а чтобы они реально все тестировали, и вы были уверены, что не отправите клиенту баги, которые фиксили уже пол года назад, но они вылезли только потому, что кто-то изменил непонятную строчку, которая что-то делала, но никто не знает что. 

Посмотри свои тесты, если они есть. Они реально тестируют что-то или просто присутствуют в системе? Если они просто присутствуют, то лучше уж вообще тогда их не писать. Вот это реально трата времени и ноль эффекта.

Я не могу писать сначала тесты и об этом уже говорил на блоге. Но я всегда тестирую свой код с помощью тестов. Просто нужно придерживаться подхода, что тесты должны тестировать, особенно edge cases (не знаю, как правильно перевести). Если есть какие-то сложные случаи, то они обязаны быть покрыты тестами. Когда разработка метода или класса закончена, то я начинаю писать тесты так, чтобы они пытались сломать мой код. Пытаюсь передать параметры, которые могут сломать вывод, которые могут дать неожиданный результат, пытаюсь передать слишком большие или слишком маленькие значения и т.д. 


Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым


Комментарии

Пикачу

31 Июля 2019

Интеграционными тестами не покроешь все кейсы. Их будет очень много. Поэтому дополнительно нужны unit тесты, чтобы протестировать каждый класс в отдельности. Так как в сумме, это декартово произведение количества функций одного класса на другие. Отсюда и количество вариаций может вырасти в слишком большое количество.
50 тестов это очень мало... Я видал проекты где их тысячи.


Михаил Фленов

01 Августа 2019

Ну у меня тесты делают сразу же несколько действий, в среднем по 5 и после каждого действия идут проверки. Если тестировать по одной вещи на тест, как рекомендуют некоторые, то у меня было бы как минимум в 5 раз больше, то есть 250


Добавить Комментарий

Еще что-нибудь

Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповедания, на русском или английском языке.

Пишите мне