Подтвердить что ты не робот

Заказ Unittest tests

Как я могу быть уверен в порядке метода unittest? Правильны ли алфавитные или числовые префиксы?

class TestFoo(TestCase):
    def test_1(self):
        ...
    def test_2(self):
        ...

или

class TestFoo(TestCase):
    def test_a(self):
        ...
    def test_b(self):
        ...
4b9b3361

Ответ 1

Вы можете отключить его, установив для параметра sortTestMethodsUsing значение None: http://docs.python.org/2/library/unittest.html#unittest.TestLoader.sortTestMethodsUsing

Для чистых единоборств вы правы; но для тестирования компонентов и тестов интеграции... Я не согласен с тем, что вы ничего не должны принимать в отношении государства. Что делать, если вы проверяете состояние. Например, ваш тест подтверждает, что услуга автоматически запускается после установки. Если в вашей настройке вы запустите службу, затем выполните утверждение, то вы больше не проверяете состояние, но вы проверяете функциональность "запуск службы".

Другим примером является то, что ваша установка занимает много времени или требует много места, и просто становится непрактичным часто выполнять настройку.

Многие разработчики склонны использовать "unittest" фреймворки для тестирования компонентов... так что перестаньте и спросите себя, я делаю unittesting или тестирование компонентов.

Ответ 2

Нет причин, по которым вы не можете опираться на то, что было сделано в предыдущем тесте, или должны перестроить все это с нуля для следующего теста. По крайней мере, нет причин, по которым обычно предлагают, но люди просто уверенно говорят "не стоит". Это не помогает.

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

Это в сторону, если вы читаете say loadTestsFromTestCase и то, что он вызывает, в конечном счете сканирует методы с некоторым шаблоном имени в любом порядке, в котором они встречаются в словаре методов классов, поэтому в основном в порядке ключа. Он принимает эту информацию и делает testuite для сопоставления ее с классом TestCase. Предоставляя ему вместо этого список, который вы хотите заказать, это один из способов сделать это. Я не уверен в самом эффективном/чистом способе сделать это, но это действительно работает.

Ответ 3

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

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

Ответ 4

Если вы используете "нос", и вы записываете свои тестовые примеры как функции (а не как методы какого-либо производного класса TestCase), "нос" не возится с порядком, а использует порядок функций, определенный в файл. Чтобы методы assert_ * были удобными без необходимости подкласса TestCase, я обычно использую модуль тестирования из numpy. Пример:

from numpy.testing import *

def test_aaa():
    assert_equal(1, 1)

def test_zzz():
    assert_equal(1, 1)

def test_bbb():
    assert_equal(1, 1)

Запуск с помощью '' nosetest -vv '' дает:

test_it.test_aaa ... ok
test_it.test_zzz ... ok
test_it.test_bbb ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.050s
OK

Обратите внимание на всех тех, кто утверждает, что модульные тесты не должны быть заказаны: хотя верно, что модульные тесты должны быть изолированы и могут выполняться независимо, ваши функции и классы обычно не являются независимыми. Они скорее наращивают друг друга от более простых/низкоуровневых функций до более сложных/высокоуровневых функций. Когда вы начинаете оптимизировать свои низкоуровневые функции и беспорядок (со своей стороны, я делаю это часто, а если нет, вам, вероятно, не понадобится unit test;-), тогда это намного лучше для диагностики причины, когда сначала выполняются тесты для простых функций и тесты для функций, которые позже зависят от этих функций. Если тесты сортируются в алфавитном порядке, реальная причина обычно затухает среди сто неудачных утверждений, которых нет, потому что у тестируемой функции есть ошибка, но поскольку низкоуровневая функция, на которую она опирается, имеет.

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

Ответ 5

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

Ответ 6

Я почти согласен с идеей, что тесты не могут быть заказаны. В некоторых случаях это помогает (проще, черт возьми!) Иметь их в порядке... после всего, что причина "единицы" в UnitTest.

Тем не менее, одна из альтернатив заключается в использовании макетных объектов для mockout и исправления элементов, которые должны выполняться перед тестированием этого конкретного кода. Вы также можете поместить туда фиктивную функцию, чтобы обезопасить свой код. Для получения дополнительной информации ознакомьтесь с Mock, который теперь является частью стандартной библиотеки. Mock

Вот несколько видеороликов YouTube, если вы еще не использовали Mock раньше.

Видео 1

Видео 2

Видео 3

В большей степени попробуйте использовать методы класса для структурирования вашего кода, а затем поместите все методы класса в один основной метод тестирования.

import unittest
import sqlite3

class MyOrderedTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.create_db()
        cls.setup_draft()
        cls.draft_one()
        cls.draft_two()
        cls.draft_three()

    @classmethod
    def create_db(cls):
        cls.conn = sqlite3.connect(":memory:")

    @classmethod
    def setup_draft(cls):
        cls.conn.execute("CREATE TABLE players ('draftid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 'first', 'last')")

    @classmethod
    def draft_one(cls):
        player = ("Hakeem", "Olajuwon")
        cls.conn.execute("INSERT INTO players (first, last) VALUES (?, ?)", player)

    @classmethod
    def draft_two(cls):
        player = ("Sam", "Bowie")
        cls.conn.execute("INSERT INTO players (first, last) VALUES (?, ?)", player)

    @classmethod
    def draft_three(cls):
        player = ("Michael", "Jordan")
        cls.conn.execute("INSERT INTO players (first, last) VALUES (?, ?)", player)

    def test_unordered_one(self):
        cur = self.conn.execute("SELECT * from players")
        draft = [(1, u'Hakeem', u'Olajuwon'), (2, u'Sam', u'Bowie'), (3, u'Michael', u'Jordan')]
        query = cur.fetchall()
        print query
        self.assertListEqual(query, draft)

    def test_unordered_two(self):
        cur = self.conn.execute("SELECT first, last FROM players WHERE draftid=3")
        result = cur.fetchone()
        third = " ".join(result)
        print third
        self.assertEqual(third, "Michael Jordan")

Ответ 7

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

Ответ 8

Хорошо, может быть немного позже, но в любом случае...

Вам следует попробовать proboscis библиотеку. Это позволит вам сделать заказ на тестирование, а также настроить любые тестовые зависимости. Я использую его, и эта библиотека действительно потрясающая.

Например, если test case #1 от module A должно зависеть от test case #3 от module B вы CAN задаете это поведение с помощью библиотеки.

Ответ 9

Существуют сценарии, в которых порядок может быть важен, и где setUp и Teardown входят в число ограниченных. Там только один метод setUp и tearDown, который является логичным, но вы можете размещать в них столько информации, пока не выясните, что может делать setUp или tearDown.

В качестве примера возьмем этот интеграционный тест:

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

Разделение кода на эти логические части имеет несколько преимуществ.

Не может быть лучшим решением, но я часто использую один метод, который запускает фактические тесты.

def test_registration_login_flow(self):
    _test_registration_flow()
    _test_login_flow()

Ответ 10

http://docs.python.org/library/unittest.html

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

Если вам нужно установить порядок явно, используйте монолитный тест.

class Monolithic(TestCase):
  def step1(self):
      ...

  def step2(self):
      ...

  def steps(self):
    for name in sorted(dir(self)):
      if name.startswith("step"):
        yield name, getattr(self, name) 

  def test_steps(self):
    for name, step in self.steps():
      try:
        step()
      except Exception as e:
        self.fail("{} failed ({}: {})".format(step, type(e), e)

Подробнее post.

Ответ 11

Простым методом для упорядочения тестов "unittest" является следовать за механизмом init.d предоставления им числовых имен:

def test_00_createEmptyObject(self):
    obj = MyObject()
    self.assertIsEqual(obj.property1, 0)
    self.assertIsEqual(obj.dict1, {})

def test_01_createObject(self):
    obj = MyObject(property1="hello", dict1={"pizza":"pepperoni"})
    self.assertIsEqual(obj.property1, "hello")
    self.assertIsDictEqual(obj.dict1, {"pizza":"pepperoni"})

def test_10_reverseProperty(self):
    obj = MyObject(property1="world")
    obj.reverseProperty1()
    self.assertIsEqual(obj.property1, "dlrow")

Однако в таких случаях вам может потребоваться структурировать ваши тесты по-разному, чтобы вы могли основываться на предыдущих случаях строительства. Например, в вышесказанном, может иметь смысл иметь функцию "construct и veirfy", которая строит объект и проверяет его назначение параметров.

def make_myobject(self, property1, dict1):  # Must be specified by caller
    obj = MyObject(property1=property1, dict1=dict1)
    if property1:
        self.assertEqual(obj.property1, property1)
    else:
        self.assertEqual(obj.property1, 0)
    if dict1:
        self.assertDictEqual(obj.dict1, dict1)
    else:
        self.assertEqual(obj.dict1, {})
    return obj

def test_00_createEmptyObject(self):
    obj = self.make_object(None, None)

def test_01_createObject(self):
    obj = self.make_object("hello", {"pizza":"pepperoni"})

def test_10_reverseProperty(self):
    obj = self.make_object("world", None)
    obj.reverseProperty()
    self.assertEqual(obj.property1, "dlrow")

Ответ 12

См. пример WidgetTestCase в http://docs.python.org/library/unittest.html#organizing-test-code, он говорит, что

Теперь экземпляры классов будут запускать один из методов проверки _ *(), при этом self.widget будет создан и уничтожен отдельно для каждого экземпляра.

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

Ответ 13

Вопреки сказанному здесь: - тесты должны выполняться изолированно (порядок для этого не имеет значения) А ТАКЖЕ - упорядочение их важно, потому что они описывают, что система делает и как разработчик реализует ее.

IOW, каждый тест предоставляет вам информацию о системе и логике разработки.

Итак, если эти данные не упорядочены, что может затруднить понимание вашего кода.

Ответ 14

Я согласен с утверждением, что наложение "не делай этого" ответ - плохой ответ.

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

Мое решение состояло в том, чтобы использовать переменные среды операционной системы на моем сервере Bamboo...

(1) Тест для функции "очистки данных" начинается с цикла while, который проверяет состояние переменной среды "BLOCK_DATA_PURGE". Если переменная "BLOCK_DATA_PURGE" больше нуля, цикл будет записывать запись журнала о том, что он спал 1 секунду. После того, как "BLOCK_DATA_PURGE" имеет нулевое значение, выполнение продолжается, чтобы проверить функциональность очистки.

(2) Любой unit test, который нуждается в данных в таблице, просто увеличивает "BLOCK_DATA_PURGE" в начале (в настройке()) и уменьшает одну и ту же переменную в режиме teardown().

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

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

Счастливое кодирование!

- Сэм Колдуэлл

Ответ 15

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

Однако, если вы все еще обнаружите, что вам нужны тесты в определенном порядке (поскольку это жизнеспособно), вы можете попробовать проверить ответ на Python unittest.TestCase порядок выполнения.