Повторное использование кода в модульных тестах?

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

Возьмем, например:

def test_some_1():
    ...some code

def test_some_2():
    ...code repeated from test_some_1

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

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

Ребята, что вы думаете?

  • Хорошо ли использовать возможность повторного использования кода в модульных тестах?
  • Если повторное использование может/должно быть использовано, то как преодолеть другую проблему, касающуюся точного определения утверждений?

person andreihondrari    schedule 04.06.2014    source источник
comment
вы знаете о setUp и tearDown? docs.python.org/2/library/unittest.html# unittest.TestCase.setUp   -  person Mihai Zamfir    schedule 04.06.2014
comment
Я знаю, но я не думаю, что они уместны здесь. Я говорил о возможности повторного использования кода. Проверьте ответ @otus.   -  person andreihondrari    schedule 04.06.2014


Ответы (2)


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

Например, в одном пакете, который я написал, у меня была функция:

def _test_vector(self, a, b, c):
    # test the function with parameter values a, b, c
    # several asserts here to verify output of function tested

Это позволило написать все тестовые векторы, например:

def test_vector1(self):
    self._test_vector(a=42, b=5, c="blah)

Это, ИМО, улучшает ясность, потому что отдельные тесты включают только информацию, относящуюся к этому тесту.

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

person otus    schedule 04.06.2014

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

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

person Jordfräs    schedule 04.06.2014