2016-02-22 3 views
6

Я хочу попытаться написать некоторый код после практики TDD. Я хочу создать простое приложение, основанное на системе торнадо python. Я смотрел через интернет, как люди пишут тесты для торнадо и нашел что-то вроде этого:Как написать модульные тесты для приложения торнадо python?

class TestSomeHandler(AsyncHTTPTestCase): 
    def test_success(self): 
     response = self.fetch('/something') 
     self.assertEqual(response.code, 200) 

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

class SomeHandler(BaseHandler): 
    @gen.coroutine 
    def get(self): 
     try: 
      from_date = self.get_query_argument("from", default=None) 
      datetime.datetime.strptime(from_date, '%Y-%m-%d') 
     except ValueError: 
      raise ValueError("Incorrect argument value for from_date = %s, should be YYYY-MM-DD" % from_date) 

И тест будет выглядеть так:

class TestSomeHandler(AsyncHTTPTestCase): 

    def test_no_from_date_param(self): 
     handler = SomeHandler() 
     with self.assertRaises(ValueError): 
      handler.get() 

Я знаю, что я скучаю по get() заявления и просьбы. Не удалось обработать, как их создать.

Но мой вопрос: люди пишут тесты для торнадо, как в первом примере, или кто-то вызывает обработчики внутри приложения? Какая картина должна следовать? Было бы неплохо, если бы у кого-то был соответствующий код для обмена.

ответ

4

Узор с AsyncHTTPTestCase используется в основном потому, что он делает все необходимое для вас. Конечно, можно использовать AsyncTestCase и обрабатывать его вручную.

описание товара AsyncTestCase пример. Поскольку он будет тестировать метод get, который является сопрограммой, мы будем использовать gen_test, чтобы сделать его немного проще. RequestHandlerApplication и HTTPRequest объектов. Потому что мы не ретранслируем настройки приложения, ui_methods и т. Д. Application - простой макет.

from tornado.testing import AsyncTestCase, gen_test 
from tornado.web import Application 
from tornado.httpserver import HTTPReuqest 
from unittest.mock import Mock 

class TestSomeHandler(AsyncTestCase): 

    @gen_test 
    def test_no_from_date_param(self): 
     mock_application = Mock(spec=Application) 
     payload_request = HTTPRequest(
      method='GET', uri='/test', headers=None, body=None 
     ) 
     handler = SomeHandler(mock_applciation, payload_request) 
     with self.assertRaises(ValueError): 
      yield handler.get() 

ИМХО это зависит от вас, какой образец использовать. Я выбираю AsyncHTTPTestCase для методов HTTP-глагола (получить, пост и так далее), так как:

  • легче
  • потребителем этого метода является HTTP-клиент, так утверждает код ответа, тело делает много смысла
  • предотвращает от чрезмерно сложных методов

конечно остальных методов обработчиков тестируемых с AsyncTestCase.

+0

Как я понимаю, такой поток не является предпочтительным. Но в другом случае я не смогу проверить исключения. –

+0

@viakondratiuk потребителем метода является некоторый клиент http (пользователь), любое исключение, которое вы его подняли, составляет всего 50 раз с некоторым сообщением, возможно, внутренней ошибкой. Все хорошо? Я так не думаю, что это показывает плохую обработку ошибок, попробуйте вернуть «возвращаемые» значимые ошибки (даже некоторые унифицированные сообщения), а дальнейшие вызовы и отладки служб будут намного проще. – kwarunek

1

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

RequestHandler не предназначен для создания экземпляра вручную без использования Application, поэтому, если у вас есть функциональность, которую вы бы предпочли протестировать без полного стека HTTP, этот код обычно должен быть в статических функциях или не- RequestHandler классов.

+0

Итак, как я понимаю, я должен проверить обработчики с помощью «AsyncHTTPTestCase» и другого кода, который может генерировать исключения и т. Д., Я должен изолировать его и протестировать отдельно? –

+0

Да. Линия деления зависит от вас: для примера исключения, приведенного здесь, я лично проверил это по HTTP и проверил, что он выдает правильный код состояния и сообщение об ошибке вместо типа исключения. –

Смежные вопросы