python история программирование

Один тест из жизни

Dmitry Vasiliev 13:29, 2009 3 27

Пару дней назад приключилась достаточно забавная история. Началось все с обнаружения на сервере нескольких несанкционированных e-mail сообщений, которые были посланы локально на левый адрес и застряли в отложенной очереди. При этом в теме сообщений значилось - "Новая рассылка N1". Первой мыслью было - кому-то удалось прорваться на одном из сайтов, через форму, которая могла отсылать e-mail... Анализ HTTP логов не показал никаких аномалий в этот момент времени. Были проанализированы все остальные логи и история команд, но никаких следов злоумышленника обнаружить не удалось. Потратив на анализ всех возможностей и размышления где-то около часа, я безнадежно отложил попытки, тем более, что рассылка не повторялась, хотя тема сообщений могла говорить о другом...

Уже вечером, занимаясь другими делами, я параллельно размышлял о том, что же могло произойти и задумался насчет времени рассылки. Именно в этот момент я запускал тесты одного пакета к которому до этого уже давно не обращался. Решив проверить новую гипотезу я подбежал к компьютеру и запустил тесты пакета. В тот же момент появилось еще несколько копий уже знакомых сообщений - "злоумышленник" нашелся!

Проблема была в следующем - один из сервисов в пакете писал другой разработчик, прилежно написавший тесты. Но эти тесты делали реальную рассылку e-mail сообщений через локальный SMTP сервер. Таким образом было нарушено одно из правил написания тестов - у тестов не должно быть побочных эффектов, тем более влияющих на внешнюю систему.

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

Новая проблема оказалась в неосторожном использовании в док-тестах опции ELLIPSIS. Исходный тест выглядел, примерно, таким образом:

>>> messages = service.getReplyMessages(query, "fake@email.address") #doctest: +ELLIPSIS
db[content].queryForResult(SELECT code FROM ...
db[content].execute(INSERT INTO UserEmail ...

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

>>> messages = service.getReplyMessages(query, "fake@email.address") #doctest: +ELLIPSIS
db[content].queryForResult(SELECT code FROM ...)
db[content].execute(INSERT INTO UserEmail ...)
...
To: fake@email.address
...
<BLANKLINE>
...
<BLANKLINE>

Comments All comments

Comment by Andrey Popp on 16:07, 2009 3 27

Andrey Popp's Gravatar

Меня вообще док-тесты раздражают... да, я понимаю их основной плюс - пишешь тест, заодно получаешь хоть какую-то, но документацию. Но вот отладке они никак не подлежат, и это раздражает.

Comment by Vasich on 16:27, 2009 3 27

Vasich's Gravatar

А я-то уже дрожащими потными ручонками удалил все функции отсылки мыла со своих сайтов, которые там хостились, в поте лица искал дырку, а оказалось! Проще надо быть :) Тесты - нафиг :)

Comment by Dmitry Vasiliev on 16:35, 2009 3 27

Dmitry Vasiliev's Gravatar

Не, не надо утрировать. Тесты вещь нужная, но над ними, как и над кодом, надо хотя бы минимально работать и понимать что к чему. ;-)

Comment by Dmitry Vasiliev on 16:49, 2009 3 27

Dmitry Vasiliev's Gravatar

> Меня вообще док-тесты раздражают...

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

Кстати, если неправильно использовать юнит-тесты, то можно наворотить - вообще потом не разгребешь (особенно со множественным наследованием и большими методами). :-)

Вот, кстати, не пробовал nose (http://code.google.com/p/python-nose/), хотя по докам не очень понятны преимущества именно при написании/чтении тестов.

Comment by Andrey Popp on 14:29, 2009 3 28

Andrey Popp's Gravatar

То, что можно наворотить это мы знаем, более того, можно наворотить и в док-тестах ;)

Я пользуюсь nose, из плюсов могу отметить хорошее обнаружение тестов - "то, что выглядит как тест, им и является" :), но вот меня смущает, что надо ставить его в зависимости (test_required в setuptools).

Кстати щас на python-dev идёт дискуссия по включение в stdlib какой-нибудь шутки для test discovery

Comment by user on 18:14, 2009 4 1

user's Gravatar

Как продвигаются дела у проекта qiktok?

Comment by Dmitry Vasiliev on 23:49, 2009 4 1

Dmitry Vasiliev's Gravatar

Фантастически! ;-)

Comment by Nikita Kabardin on 13:39, 2009 4 6

Nikita Kabardin's Gravatar

Все ок в проекте кикток?

Add comment

Name:
Email: (Never will be published.)
Web site:
Comment: (Paragraphs divided by empty lines, line breaks and links will be automatically formatted.)