Групповое тестирование с зависимостями между тестами
Как вы проводите модульное тестирование, когда у вас есть
- некоторые общие юнит-тесты
- более сложные тесты, проверяющие крайние случаи, в зависимости от общих
Чтобы привести пример, представьте себе тестирование 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() {
...
}
Ответы
Ответ 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 не должен зависеть от других.
Каждый тестовый пример должен проверять конкретное изолированное поведение.
Тогда, если какой-либо тест не пройдет, вы точно поймете, что с нашим кодом стало не так.