Форум сайта python.su
KogromВторичное использование - это правда. Применение тестов позволяет еще раз взглянуть на дизайн системы под новым углом.
Я понимаю так, что юнит-тесты и код, который они тестируют сильно взаимосвязаны, так как:
1. Юнит-тесты дают примеры использования кода. То есть получается своеобразная живая документация. Поэтому пользователю-программисту они очень пригодятся. Без них код будет беднее.
2. Юнит-тесты формируют из кода некий недофрейворк (библиотеку, пакет - называйте как хотите). Как они это делают? Проверяют классы на вторичное использование. И это хорошо. Посмотрите на библиотечные функции и классы Python-а - они избыточны для конкретного программиста, но никто особо не страдает. Поэтому не вижу ничего плохого в том, что юнит-тест диктует коду каким ему быть.
Офлайн
Андрей СветловЯ не про ляпы говорил, не про сложный интерфейс. Взять какой-нибудь модуль, random, например. Имеется куча разнообразных функций, из которых какой-нибудь конкретный программист использует 3-5. Если вести статистику, то может оказаться, что какой-нибудь randrange используют 3 программиста в мире (но и они легко найдут замену). Но никому дела нет - потенциально может быть востребовано. Или есть у разработчиков понятные методы оценки нужности функций в библиотеке?
Про избыточность библиотечных классов и функций Питона - откровенно говоря, не понял. Как по мне - наоборот. Стандартная библиотека успешно скрывает особенности реализации, давая пользователю простой и понятный интерфейс. Ляпы случаются - но тенденция всё же прослеживается.
Офлайн
KogromЕсли `can_show` и класс `Billing` вообще разрабатываются так, чтобы полностью не зависеть от datetime.now() по дизайну - это хорошо, к такому нужно стремиться. Если вы придумываете новый непротиворечивый сценарий работы, удовлетворяющий тестам и здравому смыслу - почему нет?
проблема в способе отделения “малопонятного крючка” от параметра, который может быть востребован. Так в примере с def can_show(self, date=None) можно сказать, что тут есть возможность задать дату не нашего компьютера, а удалённого сервера, например. Но неизвестно, будет ли кто-то использовать эту возможность.
Офлайн
Всё, до меня дошло :)
Офлайн
Рад за вас. До меня доходило очень долго - и не уверен, что в полной мере осознал :)
Офлайн
Я надеюсь, дошло то, что собеседник хотел сказать про “малопонятные крючки”. Хотя для полной ясности надо бы примеры, но в теории понятно.
До полного понимания TDD и до ясного дизайна мне ещё далеко. В Python ещё приемлемо, а в C++ быстро скатываюсь в какую-то legacy-процедурщину…
Офлайн
Kogrom, я попытаюсь изложить все мои соображения чётко и ясно, создавая по ходу дела нужные примеры.
Не могу обещать, что сделаю это скоро. Но задумка интересная.
Этот топик наткнулся на неочевидную (хоть и распространенную) проблему юнит-тестирования.
Научиться писать self.assertEqual легко, а тестировать живое приложение - гораздо сложнее.
Офлайн
Обещал расписать подробно - вот: http://asvetlov.blogspot.com/2011/02/funny-unittests.html
Офлайн
Андрей СветловУпущен ещё один способ (хотя можно его считать разновидностью третьего):
Обещал расписать подробно - вот: http://asvetlov.blogspot.com/2011/02/funny-unittests.html
def _test_html_fresh(self, rst_time, html_time):
return rst_time <= html_time
@property
def is_html_fresh(self):
if not os.path.exists(self.html_path):
return False
rst_time = os.path.getmtime(self.full_path)
html_time = os.path.getmtime(self.html_path)
return self._test_html_fresh(rst_time, html_time)
Отредактировано (Фев. 16, 2011 22:24:05)
Офлайн
Как мне кажется, тесты всё же должны работать в первую очередь с public interface.
Сам по себе _test_html_fresh не имеет смысла (по крайней мере в моем случае) - это по сути staticmethod, так как не может вызывать методы экземпляра (потенциально небезопасные). Попробуйте написать аналог для refresh_html.
Приходится полагаться на то, что is_html_fresh не может ошибаться, а все беды только от _test_html_fresh. Таким образом опять отходим от полного покрытия тестами.
Одно дело - когда эта ситуация объясняется недостаточными усилиями программиста.
И совершенно другое - если мы сознательно строим изначально ущербный подход.
К тому же настоятельно не рекомендую использовать третий способ, а вариантов это сделать вопреки всему - миллион.
Подмена FileSystem всяко лучше и удобней.
Офлайн