Open Vlad-Shcherbina opened 10 years ago
Это не единственный профит юнит-тестов. В условиях контеста, когда много фигачишь и плохо соображаешь, они сильно помогают не тупить. То есть, сформулировать, чего ты пытаешься добиться, в качестве юнит-теста и потом писать код, который его пройдет - это меньшее умственное усилие, чем писать код и при этом держать задачу в голове.
Юнит-тест — это повторение логики программы на языке юнит-тестового фреймворка, от ошибок в логике оно не спасает. В этой ветке, однако, означены два важных аспекта юнит-тестов в контексте ICFPC.
Для полноты добавлю еще один (очевидный) — когда за несколько часов до конца кто-то (хе-хе) ломает продакшен, юнит-тесты при хорошем покрытии немедленно это замечают и сообщают строку, где всё сломалось.
Кстати, у меня была проблема экстремального чтения логов юниттестов, поскольку стектрейсы были в каких-то стрёмных местах и не запайпав аутпут тестов в файлик, в котором фиг знает что искать, я не мог найти собственно стектрейс. Но это мой косяк, надо конечно освежать инструменты второго питона ежегодно (в чём кстати еще один бонус проведения буткемпов #31).
Юнит-тест — это повторение логики программы на языке юнит-тестового фреймворка, от ошибок в логике оно не спасает.
Да, но это два разных языка, и второй гораздо более to the point. Ты говоришь что должно получиться, а не как это сделать.
Ещё кстати в принципе есть разница между unit tests, and integration/functionality tests. Юниттесты по идее должны чётко указать где у тебя ошибка. 99% наших тестов были functionality tests, и это хорошо, потому что при наших объёмах кода найти ошибку в общем не так сложно, но очень не хочется писать код который мешает рефакторингу потому что вдобавок к перефигачиванию интерфейса и нескольких имплементаций ещё нужно будет перефигачить все юнит-тесты во всех имплементациях.
Кстати пример: половина тестов для Yoleвского GCC были конкретно юнит-тестами (прямой вызов функции интерпретатора вместо call(...)), поэтому когда я попытался применить к своему гцц, я испытал жопаболь и не применил.
Да, юнит-тесты, которые используют mocks и дословно повторяют реализацию, действительно отстой и не нужны. Про реюз моих тестов для других реализаций я не думал, и, наверное, зря - можно было бы сделать, и было бы не сильно сложнее.
Роль тестов в целом это отдельная большая тема, а тут хотел рассказать об одном очень необычном экспириенса. Я вообще ненавижу юниттесты и подумать бы не мог, что когда-нибудь буду писать их к функции на питоне которая считает длину списка, и радоваться что у меня вообще есть такая возможность!
Изначально к программированию на КП я подходил с большим недоверием: что если я неправильно понимаю значение какой-нибудь стрёмной конструкции (кстати, car(x) и cdr(x) должны были быть x[0] и x[1], ну да ладно); или компилятор делает какое-нибудь допущение которое я нарушаю, и вместо того чтобы упасть с ассёртом тихо порождает некорректный код? Но по мере того как я писал простые функции и тесты к ним, выстраивая необходимую стандартную библиотеку, это недоверие очень быстро развеялось. И когда я подошёл к написанию собственно AI (который юниттестить очень сложно потому что надо окружение моделировать), я уже чувствовал себя достаточно комфортно с КП чтобы просто фигарить.
код
Выводы: