есть ли способ добавить зависимости между unittests в python с помощью модуля unittest? [Дубликат]

matches пытается сопоставить выражение со всей строкой и неявно добавить ^ в начале и $ в конце вашего шаблона, то есть не будет искать подстроку. Следовательно, выход этого кода:

public static void main(String[] args) throws ParseException {
    Pattern p = Pattern.compile("\\d\\d\\d");
    Matcher m = p.matcher("a123b");
    System.out.println(m.find());
    System.out.println(m.matches());

    p = Pattern.compile("^\\d\\d\\d$");
    m = p.matcher("123");
    System.out.println(m.find());
    System.out.println(m.matches());
}

/* output:
true
false
true
true
*/

123 является подстрокой a123b, поэтому метод find() выводит true. matches() только «видит» a123b, который не совпадает с 123 и, следовательно, выводит false.

31
задан 0xc0de 27 June 2012 в 15:11
поделиться

15 ответов

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

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

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

Многие разработчики, как правило, используют «unittest» рамки для тестирования компонентов ... так что остановитесь и спросите себя, я делаю unittesting или компонентного тестирования.

50
ответ дан max 19 August 2018 в 12:13
поделиться
  • 1
    +1 для этого: «Что делать, если вы тестируете состояние». Бывает довольно часто при тестировании методов, например, с использованием бэкэнда БД. Не будьте догматичны, там являются законными исключениями в отношении разумного правила, делающего каждый отдельный тест изолированным. – Laryx Decidua 22 July 2014 в 10:39

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

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

0
ответ дан carrvo 19 August 2018 в 12:13
поделиться

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 .

3
ответ дан Community 19 August 2018 в 12:13
поделиться

Если вы используете «нос», и вы пишете свои тестовые примеры как функции (а не как методы какого-либо производного класса 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

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

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

12
ответ дан Elmar Zander 19 August 2018 в 12:13
поделиться
  • 1
    У меня есть набор из нескольких сотен тестовых примеров, и я, к сожалению, не могу сказать, что это правда. Его также не избегают нарочно, иногда это действительно было в этом порядке. Также я не уверен, что он где-то настраивается в нос, но прокручивая справку, я тоже не могу разобрать вариант. – erikbwork 26 March 2015 в 11:16
  • 2
    Ваш пример работает, но это не работает в моем случае, поскольку тесты все еще выполняются в алфавитном порядке, но, прочитав другие ответы, я понял, что мне нужно изолировать мои тесты правильно – danidee 12 December 2016 в 11:21

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

6
ответ дан eradman 19 August 2018 в 12:13
поделиться
  • 1
    Полностью согласен. – Purrell 13 May 2011 в 22:46
  • 2
    Извините, но я склонен не согласиться. Единичные тесты не должны зависеть друг от друга, но они все еще часто имеют большой смысл, если они выполняются в том порядке, в котором они были указаны. Скажем, у вас есть две функции a, а b и b - a. Тогда гораздо лучше, если test_a выполняется до test_b, потому что если a содержит ошибку, вы увидите это намного раньше, вместо того, чтобы пытаться найти ошибку в b. – Elmar Zander 13 March 2012 в 18:30
  • 3
    @ElmarZander - если test_b работает также a, тогда у вас может возникнуть проблема с вашей тестовой структурой, так как test_b завершит тестирование не одной единицы b, а двух: b и a. Вероятно, вы должны издеваться над результатом a в своем test_b. Единичные тесты ≠ интеграционные тесты. – mac 23 December 2013 в 15:29
  • 4
    @mac Спасибо, но я знаю, какие интеграционные тесты есть. То, что я написал, не имело ничего общего с этим, и нет, у меня нет проблем с моей тестовой структурой. Я просто придерживаюсь какого-то структурированного подхода к дизайну, где я сочиняю более сложные функции из более простых, и не было бы ни смысла, ни возможности фальсифицировать каждую пятистрочную функцию другой функцией с пятью строками, но она делает много смысла, чтобы протестировать более простые перед сложной функцией, построенной сверху. – Elmar Zander 16 October 2015 в 16:20

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

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

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

6
ответ дан gahcep 19 August 2018 в 12:13
поделиться

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

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

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

0
ответ дан gregorySalvan 19 August 2018 в 12:13
поделиться
  • 1
    Существуют некоторые сценарии, в которых тесты нуждаются для запуска в определенном порядке. Например: у меня есть обертка API, которая регистрируется на внешнем сервере. Вход требуется , чтобы произойти до любого другого unittest. – Steven Vascellaro 6 November 2017 в 20:11
  • 2
    Тесты @StevenVascellaro. Те тесты, которые вы описываете, - это не модульные тесты, а тема об модульном тестировании, и у вас НИКОГДА не возникает сценарий, когда тесты должны выполняться в определенном порядке. Это запах кода о плохом дизайне или неправильных тестах. Если вы пишете такие тесты, лучше проанализировать то, что вы знаете о тестировании, потому что для меня тесты, которые вы описываете, бесполезны и затрудняют изменение кода. Подумайте об этом, вы говорите, чтобы протестировать внешнюю систему, которая уже должна быть проверена. Сосредоточьтесь на ВАШЕЙ системе, это то, что вы тестируете. – gregorySalvan 8 November 2017 в 21:55
  • 3
  • 4
    :)))) ОК, просто этот «QA Test Automation engineer», достаточно, чтобы быть уверенным, что мы никогда не сможем обсуждать вместе, и что ваш код для меня полный беспорядок. сожалею – gregorySalvan 28 December 2017 в 21:37

Я согласен с тем, что тесты не могут быть заказаны. В некоторых случаях это помогает (проще, черт возьми!) Иметь их в порядке ... в конце концов, это причина для «единицы» в 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
ответ дан Jason Wirth 19 August 2018 в 12:13
поделиться

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

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

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

1
ответ дан jiakai 19 August 2018 в 12:13
поделиться

Простым методом для упорядочения тестов «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")
3
ответ дан kfsone 19 August 2018 в 12:13
поделиться

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

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

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

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

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

def test_registration_login_flow(self):
    _test_registration_flow()
    _test_login_flow()
4
ответ дан Rob Hunter 19 August 2018 в 12:13
поделиться

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

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

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

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

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

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

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

2
ответ дан Rob Rose 19 August 2018 в 12:13
поделиться
  • 1
    Престижность для первого абзаца. & quot; Не делайте этого & quot; всегда исходит из какой-то неопытности, то есть разработчика, которому никогда не приходилось автоматизировать интеграцию или приемочное тестирование пользователей. – pmneve 12 December 2017 в 18:50

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

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

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

60
ответ дан Seren Seraph 19 August 2018 в 12:13
поделиться
  • 1
    Я согласен с вашими замечаниями о бесполезных "не делайте этого & quot; комментарии без объяснений, но, сказав, что являются подлинными причинами, почему нецелесообразно иметь зависимости между тестами. Главный из них - это хорошо, что тесты терпят неудачу, потому что определенная вещь сломалась, а не потому, что есть некоторая неясная, недокументированная связь между тестом, в котором вы работаете, и другим тестом, который вы нет. Если вы никогда не запускаете изолированные тесты, тогда все в порядке, но возможность выполнения отдельных тестов полезна при некоторых обстоятельствах, и это невозможно, если они зависят друг от друга. – JimmidyJoo 10 March 2015 в 16:24
  • 2
    Ответ заключается в том, что модульные тесты должны быть независимыми друг от друга, чтобы вы могли запускать и отлаживать их изолированно. – JeremyP 10 September 2015 в 12:46
  • 3
    – Rob Hunter 12 April 2016 в 18:04
  • 4
    Можете ли вы привести пример того, как установить порядок выполнения теста? – Steven Vascellaro 6 November 2017 в 20:08

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

9
ответ дан user 19 August 2018 в 12:13
поделиться

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

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

13
ответ дан zoul 19 August 2018 в 12:13
поделиться
  • 1
    Возможно, будет сложно запустить их параллельно, если они обращаются к базе данных (что в основном относится к django) – Antoine Pelisse 4 November 2010 в 10:38
  • 2
    Каждый тест является продолжением предыдущего. Вот простой пример порядка тестирования. тестирование подписки пользователей, тестирование отказа от подписки, тестирование отписки подписки и подписки с отключением. Я должен сделать все, что было проверено в предыдущем тесте, если тесты не упорядочены. Это неправильно? – nmb.ten 4 November 2010 в 10:51
  • 3
    @MitchellModel Django использует транзакции для отката изменений в базе данных между тестами. Второй тест не должен видеть изменений в базе данных, созданной в первом тесте. (Если вы, ваше мнение, вероятно, использует транзакции - вы должны использовать TransactionTestCase Django вместо TestCase для этого представления) – Izkata 28 November 2011 в 21:50
  • 4
    Одна из причин, о которой я могу думать, - это когда два теста не зависят друг от друга, но те компоненты, которые они тестируют. Представьте, что вы тестируете класс B, который является подклассом A. Если у A есть проблемы, это также не даст тестов B. Было бы лучше получить ошибки, связанные с тестом сначала. Но в целом, это не должно иметь большого значения. – Mansour 6 February 2012 в 19:02
  • 5
    Для отладки имеет смысл иметь (независимые) тесты, заказанные от простого до сложного. – Michael Clerx 22 October 2012 в 12:27
Другие вопросы по тегам:

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