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

Групповое тестирование с зависимостями между тестами

Как вы проводите модульное тестирование, когда у вас есть

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

Чтобы привести пример, представьте себе тестирование CSV-ридера (я только что сделал запись для демонстрации),

def test_readCsv(): ...

@dependsOn(test_readCsv)
def test_readCsv_duplicateColumnName(): ...

@dependsOn(test_readCsv)
def test_readCsv_unicodeColumnName(): ...

Я ожидаю, что суб-тесты будут выполняться только в случае успешного выполнения родительского теста. Причина этого в том, что выполнение этих тестов требует времени. Многие сообщения об ошибках, которые ссылаются на одну причину, также не будут информативными. Конечно, я мог бы включить все крайние случаи в основной тест, но мне интересно, есть ли более структурированный способ сделать это.

Я нашел эти связанные, но разные вопросы,

UPDATE:

Я обнаружил TestNG, в котором есть отличная встроенная поддержка тестовых зависимостей. Вы можете написать такие тесты,

@Test{dependsOnMethods = ("test_readCsv"))
public void test_readCsv_duplicateColumnName() {
   ...
}
4b9b3361

Ответ 1

Лично я не стал бы беспокоиться о создании зависимостей между модульными тестами. Это звучит как немного запаха кода для меня. Несколько моментов:

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

Ответ 2

Proboscis - это версия python TestNG (которая является библиотекой Java).

См. packages.python.org/proboscis/

Он поддерживает зависимости, например.

@test(depends_on=[test_readCsv])
public void test_readCsv_duplicateColumnName() {
   ...
}

Ответ 3

Я не уверен, на каком языке вы ссылаетесь (поскольку вы конкретно не упоминаете об этом в своем вопросе), но для чего-то вроде PHPUnit существует @depends, который будет запускать только те тесты, если уже пройденный тест уже прошел.

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

Ответ 4

Я реализовал плагин для Nose (Python), который добавляет поддержку тестовых зависимостей и приоритетов тестов.

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

Вы можете найти его здесь: носовой упор.

Минимальный пример:

def test_a:
  pass

@depends(before=test_a)
def test_b:
  pass

Чтобы убедиться, что test_b всегда запускается до test_a.

Ответ 5

Вы можете использовать pytest-зависимость. Согласно их документации, код выглядит элегантно:

import pytest

@pytest.mark.dependency()
@pytest.mark.xfail(reason="deliberate fail")
def test_a():
    assert False

@pytest.mark.dependency()
def test_b():
    pass

@pytest.mark.dependency(depends=["test_a"])
def test_c():
    pass

@pytest.mark.dependency(depends=["test_b"])
def test_d():
    pass

@pytest.mark.dependency(depends=["test_b", "test_c"])
def test_e():
    pass

Обратите внимание, это плагин для pytest, а не unittest, который является частью самого питона. Итак, вам нужно еще 2 зависимости (например, добавить в requirements.txt):

pytest==5.1.1
pytest-dependency==0.4.0

Ответ 6

В соответствии с передовыми методами и принципами модульного тестирования unit test не должен зависеть от других.

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

Тогда, если какой-либо тест не пройдет, вы точно поймете, что с нашим кодом стало не так.