Как записать современные тесты Python?

Что последний путь состоит в том, чтобы записать тестам Python? Какие модули/платформы использовать?

И другой вопрос: doctest тесты все еще какого-либо значения? Или все тесты должны быть записаны в более современной среде тестирования?

Спасибо, Boda Cydo.

12
задан bodacydo 28 February 2010 в 20:22
поделиться

5 ответов

Обычный способ - использовать встроенный модуль unittest для создания модульных тестов и объединения их в наборы тестов, которые можно запускать независимо. unittest очень похож на jUnit (и вдохновлен им) и поэтому очень прост в использовании.

Если вас интересуют самые последние изменения, ознакомьтесь с новым докладом о PyCon, написанным Майклом Фурдом:

PyCon 2010: Новые и улучшенные: грядущие изменения в unittest

12
ответ дан 2 December 2019 в 05:27
поделиться

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

Если вы используете setuptools или distribute (вы должны переключиться на распространение), вы можете настроить нос в качестве сборщика тестов по умолчанию, чтобы вы могли запускать тесты с помощью " python setup.py test "

setup(name='foo',
      ...
      test_suite='nose.collector',
      ...

Теперь запуск" python setup.py test "вызовет программу Носа, которая будет сканировать ваш проект в поисках вещей, похожих на тесты, и запускать их, накапливая результаты. Если в вашем проекте также есть доктесты, вы можете запустить тесты с параметром --with-doctest, чтобы включить плагин doctest.

нос также имеет интеграцию с покрытием

nosetests --with-coverage.

. Вы также можете использовать параметры - cover-html --cover-html-dir для создания отчета о покрытии HTML для каждого модуля с каждая строка кода, которая не тестируется, выделяется. Я бы не стал слишком зацикливаться на охвате, чтобы сообщить о 100% тестовом покрытии для всех модулей. Часть кода лучше оставить для интеграционных тестов, о которых я расскажу в конце.

Я стал большим поклонником Minimock, так как он упрощает тестирование кода с множеством внешних зависимостей. Хотя он работает действительно в сочетании с doctest, его можно использовать с любой средой тестирования, использующей класс unittest.TraceTracker .Я бы посоветовал вам избегать его использования для тестирования всего вашего кода, поскольку вы все равно должны попытаться написать свой код так, чтобы каждую единицу перевода можно было тестировать изолированно, без насмешек. Хотя иногда это невозможно.

Вот (непроверенный) пример такого теста с использованием Minimock и unittest:

# tests/test_foo.py
import minimock
import unittest

import foo

class FooTest(unittest2.TestCase):
    def setUp(self):
        # Track all calls into our mock objects. If we don't use a TraceTracker
        # then all output will go to stdout, but we want to capture it.
        self.tracker = minimock.TraceTracker()

    def tearDown(self):
        # Restore all objects in global module state that minimock had
        # replaced.
        minimock.restore()

    def test_bar(self):
        # foo.bar invokes urllib2.urlopen, and then calls read() on the
        # resultin file object, so we'll use minimock to create a mocked
        # urllib2.
        urlopen_result = minimock.Mock('urlobject', tracker=self.tracker)
        urlopen_result.read = minimock.Mock(
            'urlobj.read', tracker=self.tracker, returns='OMG')
        foo.urllib2.urlopen = minimock.Mock(
            'urllib2.urlopen', tracker=self.tracker, returns=urlopen_result)

        # Now when we call foo.bar(URL) and it invokes
        # *urllib2.urlopen(URL).read()*, it will not actually send a request
        # to URL, but will instead give us back the dummy response body 'OMG',
        # which it then returns.
        self.assertEquals(foo.bar('http://example.com/foo'), 'OMG')

        # Now we can get trace info from minimock to verify that our mocked
        # urllib2 was used as intended. self.tracker has traced our calls to
        # *urllib2.urlopen()*
        minimock.assert_same_trace(self.tracker, """\
Called urllib2.urlopen('http://example.com/foo)
Called urlobj.read()
Called urlobj.close()""")

Модульные тесты не должны быть единственными типами тестов, которые вы пишете. Они, безусловно, полезны и чрезвычайно важны, если вы планируете поддерживать этот код в течение длительного периода времени. Они упрощают рефакторинг и помогают выявить регрессии, но на самом деле они не проверяют взаимодействие между различными компонентами и то, как они взаимодействуют (если вы все делаете правильно).

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

Я добился большого успеха в моем текущем проекте. У меня было около 80% покрытия модульными тестами, а остальная часть кода состояла из таких вещей, как синтаксический анализ аргументов, отправка команд и состояние приложения верхнего уровня, которые трудно охватить в модульных тестах. Эта программа имеет множество внешних зависимостей, взаимодействует с десятком различных веб-сервисов и взаимодействует примерно с 6000 машинами в производственной среде, поэтому запускать ее изолированно оказалось довольно сложно.

Я закончил тем, что написал интеграционный тест, который порождает сервер WSGI, написанный с помощью eventlet и webob , который имитирует все сервисы, с которыми моя программа взаимодействует в производственной среде.Затем обезьяна интеграционного теста исправляет нашу клиентскую библиотеку веб-службы , чтобы перехватывать все HTTP-запросы и отправлять их в приложение WSGI. После этого он загружает файл состояния, содержащий сериализованный снимок состояния кластера, и вызывает приложение, вызывая его функцию main (). Теперь все внешние сервисы, с которыми взаимодействует моя программа, смоделированы, так что я могу запускать свою программу так, как если бы она выполнялась в производственной среде, с повторяемостью.

2
ответ дан 2 December 2019 в 05:27
поделиться

При тестировании документов важно помнить, что тесты основаны на сравнении строк, и способ отображения чисел в виде строк будет различаться на разных платформах и даже на разных интерпретаторы Python.

Большая часть моей работы связана с вычислениями, поэтому я использую тесты только для проверки моих примеров и моей строки версии. Я поместил несколько в __init__.py, поскольку он будет отображаться как первая страница моей документации API, созданной с помощью epydoc.

Я использую нос для тестирования, хотя мне очень интересно проверить последние изменения в py.test.

0
ответ дан 2 December 2019 в 05:27
поделиться

Я мало знаю о доктестах, но в моем университете проверка носа проводится и поощряется.

Nose можно установить, выполнив следующую процедуру (я предполагаю, что вы используете ПК - ОС Windows):

  1. установить setuptools
  2. Запустить командную строку DOS (Пуск -> Все программы -> Стандартные -> Командная строка)
  3. Чтобы этот шаг работал, вы должны быть подключены к Интернету. В DOS введите: C: \ Python25 \ Scripts \ easy_install нос

Если вы используете другую ОС, проверьте этот сайт

РЕДАКТИРОВАТЬ :

Прошло два года с тех пор, как я написал эта почта. Теперь я узнал об этом принципе программирования, который называется Дизайн по контракту . Это позволяет программисту определять предусловия, постусловия и инварианты (называемые контрактами) для всех функций в своем коде. В результате возникает ошибка, если какой-либо из этих контрактов нарушается.

Фреймворк DbC, который я бы порекомендовал для Python, называется PyContract . Я успешно использовал его в своей структуре эволюционного программирования

5
ответ дан 2 December 2019 в 05:27
поделиться

Использование встроенного модуля unittest актуально и просто, как никогда. Другие варианты модульного тестирования, py.test , нос и twisted.trial в основном совместимы с unittest .

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

9
ответ дан 2 December 2019 в 05:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: