Как мне настроить процесс разработки TDD с помощью Google App Engine?
Я в первую очередь парень из Ruby, но в последнее время я работал над большим количеством материалов Python, в частности, с кодом App Engine. В Ruby я бы использовал автоматическую непрерывную интеграцию (autotest), инструменты покрытия кода (rcov), статический анализ (reek) и тестирование мутаций (heckle) в моем процессе разработки, но я не уверен, как лучше всего настроить аналогичный процесс разработки для среды App Engine. Я также интересовался бы аналогами RSpec и Cucumber для Python, который может работать в App Engine.
Ответы
Ответ 1
В моем проекте GAE я использую:
- NoseGAE - это критическая часть, которая связывает всех остальных вместе.
- Макет, как в Джон отличный ответ. Я использую это в основном для AWS и других веб-сервисов.
- Светильники (пакет, а не идея)
Я также предпочитаю многие идиомы Rails. Я разбил свои тесты на единицу и функционально использовал пакеты Python. Вы можете запустить подмножество тестов с помощью --tests=unit
или --tests=functional
. Это все немного более ручно, чем Rails, но по крайней мере я могу unit test жесткий материал и убедиться, что у меня никогда нет регрессий.
Я также сделал простой класс FunctionalTest
для выполнения большинства распространенных действий в Rails, таких как assert_response
и assert_xpath
(аналогично assert_select).
class FunctionalTest(Test):
def get(self, *args, **kw):
self.response = app.get(*args, **kw)
def post(self, *args, **kw):
self.response = app.post(*args, **kw)
def assert_response(self, expected):
pattern = str(expected) if re.search(r'^\d+$', expected) \
else (r'^\d+ %s' % expected)
assert re.search(pattern, self.response.status, re.IGNORECASE), \
'Response status was not "%s": %s' % (expected, self.response.status)
def assert_xpath(self, path, expected):
element = ElementTree.fromstring(self.response.body)
found_nodes = element.findall('.' + path)
if type(expected) is int:
assert_equal(expected, len(found_nodes))
elif type(expected) is str or type(expected) is unicode:
assert (True in [(node.text == expected) for node in found_nodes])
else:
raise Exception, "Unknown expected value: %r" % type(expected)
Если вы выполняете множество поисков равенства элементов ListElement, обязательно изучите синтаксис --tests=foo
, потому что тестирование для сопоставления элементов в списке выполняется очень медленно.
Иногда мне нравится загружать консоль Rails на мои данные прибора, чтобы узнать, что происходит в тестовой среде (т.е. script/console test
). Чтобы сделать что-то подобное с GAE, запустите dev_appserver.py с параметром --datastore_path="$TMPDIR/nosegae.datastore"
(или, возможно, замените /tmp
на $TMPDIR
.
Ответ 2
В Python вы не всегда найдете один-один эквивалент инструментов тестирования Ruby, но в Python есть отличные инструменты тестирования. Некоторые из полезных инструментов, которые я нашел полезными, включают:
- unittest - инструмент xUnit, включенный в стандартную библиотеку Python. Он включает в себя все основы для модульного тестирования.
- doctest - потрясающая часть стандартной библиотеки, она позволяет вам писать тесты в docstrings функций, классов, модулей, методы. Это отлично подходит для передачи предполагаемого использования API. Ian Bicking предлагает использовать доктрину для развития, управляемого поведением. Doctest очень хорошо вписывается в систему документации Sphinx (вы можете убедиться, что все примеры в документации проходят каждый раз при сборке документов).
- nose и py.test видны как версии следующего поколения unittest. Они могут запускать все существующие экземпляры unittest, но допускают более простые, неклассовые модульные тесты. py.test также позволяет распределенное выполнение.
- mock - хорошая библиотека для насмешливого поведения.
- tdaemon наблюдает за каталогом обновлений вашего кода и повторно выполнит ваш тестовый набор. (мой личный филиал содержит несколько неудобных улучшений).
- Buildbot, Bitten и даже Hudson все хорошо работают как полноценные серверы непрерывной интеграции для кода Python.
- coverage.py вычисляет покрытие кода вашего кода.
- pylint предоставит логический анализ вашего кода, убедившись, что он соответствует общим правилам кодирования и не имеет общих ошибок. Существует также "более легкий" инструмент анализа, PyFlakes.
- Существует несколько инструментов тестирования HTTP/Browser, которые хорошо работают в Python, включая Twill, Selenium и Windmill.
Если вы используете Django для App Engine, он включает несколько расширений для unittest, которые позволяют имитировать HTTP-клиент и постоянство базы данных.
Существует множество других инструментов, которые я не использовал (например, PySpec и Behaviour), что также может быть полезно. Я не видел никакого инструмента тестирования мутаций в Python, но я уверен, что есть один (я хотел бы узнать, что это такое).
Счастливое тестирование!
Ответ 3
Не использовал App Engine, но мое чувство для самых популярных инструментов тестирования python -
- unittest/doctest - это пакеты тестирования из стандарта Python
библиотека. unittest - это xUnit для python.
- nose - тестовый бегун/искатель. У него много вариантов, в том числе
--with-coverage
, который использует coverage, чтобы дать вам покрытие кода
отчетов.
- pylint - это наиболее функциональный инструмент для проверки текста для python. Полезно за
синтаксическая проверка, поскольку она рекомендует использовать неиспользуемые переменные/функции, когда
методы должны быть функциями и т.д.
- pester (тестирование мутаций)
- buildbot (непрерывная интеграция)
Вероятно, вам захочется ссылаться на этот (не совсем полный) список Python
Инструменты тестирования.
Для BDD поле было тонким в последний раз, когда я проверил. Многие из настоящих инструментов BDD
не использовались с носом и/или слишком ограничивались в синтаксисе, который они требовали.
Возможно, вам повезло с spec, который является BDD-подобным носовым плагином.
Просто нашел pyccuracy, который очень похож на огурец, но у меня нет
попробовал.
Для чего стоит, теперь я просто использую nosetests -v
(носовой бегун с
--verbose), который будет использовать первую строку докшлинга в тестовом бегуне
вывод. То есть, учитывая тест, например:
class TestFoo(unittest.TestCase):
def testAnyNameHere(self):
""" Foo should be bar"""
foo = "bar"
self.assertEqual(foo, 'bar')
nosetests будут давать:
$ nosetests -v
Foo should be bar... ok
-----------------------------
Ran 1 tests in 0.002s
OK
Ответ 4
Похоже, еще одна новая опция Agar, которая основана на google.appengine.ext.testbed, часть SDK App Engine. Подробнее см. этот пост в блоге.
Ответ 5
Для тестирования мутации попробуйте mutmut, он доступен на https://github.com/boxed/mutmut/
Это так же просто, как "pip install mutmut", затем "mutmut run", если вы используете pytest.