Обложка канала

Александр Кунташов — про 1С и не только

Заметки про разработку и смежные штуки. 1С, Битрикс24, 1Script, PHP, Linux, JS и другое

Александр Кунташов — про 1С и не только

6 лет назад
Открыть в
Лет десять назад у меня был коллега из Ульяновска, тоже звали Никитой, кстати. Устроился он тогда в компанию, у которой несколько лет уже работал большой, живой, высоконагруженный продукт, приносивший достаточно денег, чтобы платить команде в России. Продукт активно дорабатывался прямо по живому, а чтобы не сойти с ума, функциональность была покрыта интеграционным тест сьютом. Все бы хорошо, но фичи приоритезировались больше, чем тесты, которые в результате начали подгнивать, перестали отражать реальную ситуацию, и в какой-то момент превратились из инструмента безопасного релиза в театр безопасности. Никто не знал, можно ли им верить, они падали в рандомные моменты времени даже на работающем коде, CI перезапускал тест сьют трижды (!) и считал тест успешным, если он прошел хотя бы один раз из трех. Ситуация быстро кульминировала в пик outages (несколько штук в неделю), невыспавшуюся команду и дерганый менеджмент. Дошло до того, что по общему соглашению разработку вообще всех новых фич остановили на полгода (!), которые посвятили исключительно техдолгу, починке тестов и настройке нормальных процессов релиза. Довольно беспрецендентный шаг, по моему опыту, который тем не менее завершился ощутимым успехом (тоже, кстати, редкость, чтобы такие большие планы ожидаемо сбывались) — работать снова стало возможно. Потом, правда, деньги кончились, но это другая уже история.

Никита тогда занимался как раз починкой тест сьюта и вынес несколько патентованых афоризмов.

Зачем тесты:

- Тесты помогают двигаться вперед, не оглядываясь назад.
- Тесты не делают программу лучше или надежнее. Код самой программы делает программу лучше и надежнее. Акцент всегда на коде! Тесты всегда средство.
- Тесты пишутся только из острой необходимости, когда нет других способов обеспечить надежность (простота, гарантии компилятора, БД, ОС).
- Смысл тестов в том, чтобы падать.
- Прошедший/упавший тест — это сигнал, единица информации.
- Тест, падающий всегда, плох. Он ничего не показывает.
- Также плох и тест, не падающий никогда.
- Мигающий тест не несет информации, это шум.

Что тестировать:

- Ровно то, что программа обеспечивает де факто.
- Про каждый (каждый!) тест должно быть понятно, почему он написан, что проверяет, почему это нужно проверять.
- Не должно быть тестов «на всякий случай», «просто».
- Нет смысла тестировать простые, предсказуемые вещи.
- Юнит-тесты тестируют то, что удобно, вместо того, что требует тестирования.
- Погоня за 100% покрытием (или любым другим — 90%, 85%) бессмысленное дрочево^W^W формализм.

Как тестировать:

- Тесты не должны отнимать больше усилий, чем код.
- Тесты должны быть гибкими и податливыми, не быть обузой, когда надо изменить код.
- Не запускать тесты в отдельных, специально создаваемых условиях. Эмуляция окружения, БД, mock-и дают уверенность, что волшебные феечки в волшебной стране работают нормально, а интересно должно быть, как работает реальность.
- Асинхронность — не проблема. Надо признать ее существование и тестировать ровно то и ровно так, как оно на самом деле происходит.
- Тестирование sleep-ами, фиксированные взятые с потолка задержки, retry тестов — прямая дорога к моргающим тестам, дергающемуся глазу, неврозу, дурке.
- Тесты должны быть быстрыми, чтобы запускаться как можно чаще. Duh.
- Тесты должны работать локально так же просто, как и на CI.
- Кажется, что это сложно или невозможно? Только кажется. Обычно фундаментальных препятствий к этому нет, надо лишь один раз заморочиться.
- Править код, архитектуру и даже инфраструктуру (например, взять другую БД!), чтобы написать тесты хорошо — нормально. Тесты тоже часть архитектуры.

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