Это - плохая практика, чтобы иметь больше чем одно утверждение в модульном тесте? [закрытый]

Почему написали "#" после где комната? может быть, это ошибка

43
задан Dave Schweisguth 8 May 2014 в 16:58
поделиться

8 ответов

Иногда у меня есть ровно одно утверждение на тестовый случай, но я думаю, что чаще у меня несколько assert высказываний.

Я видел случай, к которому @Arkain ускользает, когда очень большой кусок кода имеет один набор модульных тестов с несколькими тестовыми примерами, и все они помечены testCase1 , testCase2 и т. Д., И в каждом тестовом примере есть сотни подтверждений. И даже лучше, каждое условие обычно зависит от побочных эффектов предыдущего выполнения. Всякий раз, когда сборка завершается неудачей, неизменно в таком модульном тесте, требуется довольно много времени, чтобы определить, где была проблема.

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

Например, если вы написали java.lang.Integer , у вас могут быть такие случаи, которые выглядят следующим образом:

public void testValueOf() {
    assertEquals(1, Integer.valueOf("1").intValue());
    assertEquals(0, Integer.valueOf("0").intValue());
    assertEquals(-1, Integer.valueOf("-1").intValue());
    assertEquals(Integer.MAX_VALUE, Integer.valueOf("2147483647").intValue());
    assertEquals(Integer.MIN_VALUE, Integer.valueOf("-2147483648").intValue());
    ....
}

public void testValueOfRange() {
    assertNumberFormatException("2147483648");
    assertNumberFormatException("-2147483649");
    ...
}

public void testValueOfNotNumbers() {
    assertNumberFormatException("");
    assertNumberFormatException("notanumber");
    ...
}
private void assertNumberFormatException(String numstr) {
    try {
        int number = Integer.valueOf(numstr).intValue();
        fail("Expected NumberFormatException for string \"" + numstr +
             "\" but instead got the number " + number);
    } catch(NumberFormatException e) {
        // expected exception
    }
}

Вот несколько простых правил, которые я могу придумать, сколько assert'ов добавить в тестовый пример:

  • Не иметь более одного assert , которое зависит от побочных эффектов предыдущего выполнения.
  • Группа объявляет вместе , которые тестируют одну и ту же функцию / функцию или ее фасет - нет необходимости в накладных расходах для нескольких модульных тестовых случаев, когда в этом нет необходимости.
  • Любое из приведенных выше правил должно быть переопределено практичностью и здравым смыслом. Вам, вероятно, не нужна тысяча тестовых случаев с одним утверждением в каждом (или даже несколькими утверждениями), и вам не нужен один тестовый случай с сотнями операторов assert .
42
ответ дан 26 November 2019 в 22:53
поделиться

«Модульный тест» должен тестировать 1 единицу, поэтому должен быть как можно меньше и проверять только 1 определенную вещь. Я бы посоветовал иметь только 1 утверждение

, НО я думаю, что это нормально иметь 2 утверждения, если они не расположены одно за другим.

Плохой пример

public void ValidateRulesEntry_Valid_ValidConditionsFromFile()
{
    string condition = "Target.HasValue";
    string returnMessage;

    bool successFul = CodeParserTryParseCondition(condition, out returnMessage);


    Assert.IsTrue(successFul);
    Assert.IsFalse(string.IsNullOrEmpty(returnMessage));
    Assert.IsTrue(returnMessage == "OK");

}
0
ответ дан 23 September 2019 в 03:54
поделиться

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

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

17
ответ дан 26 November 2019 в 22:53
поделиться

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

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

var result = controller.Action() as ViewResult;

Assert.IsNotNull( result );
Assert.AreEqual( viewName, result.ViewName );

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

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

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

10
ответ дан 26 November 2019 в 22:53
поделиться

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

Подумайте:

assert(list.isEmpty());

FetchValues(list);

assert(list.count == expectedItemCount);

AssertValuesMatch(list,expectedValues);

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

6
ответ дан 26 November 2019 в 22:53
поделиться

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

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

2
ответ дан 26 November 2019 в 22:53
поделиться

Вставьте все утверждения в том, что вы хотите. Серьезно.

Я стараюсь утверждать каждый шаг на пути к включению и включению конкретной цели моего теста.

1
ответ дан 26 November 2019 в 22:53
поделиться

Это не имеет значения. Единственное, что имеет значение, это то, что ваши юнит-тесты покроют все возможные ошибки.

Это пример «переосмысления».

0
ответ дан 26 November 2019 в 22:53
поделиться
Другие вопросы по тегам:

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