2008-09-26 2 views
21

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

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

Просто интересно, какие у людей взгляды на это?

ответ

16

Это будет официальный способ сделать это:

// Act 
Exception ex = Record.Exception(() => someCode()); 

// Assert 
Assert.Null(ex); 
2

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

2

В целом, я вижу, что это происходит в интеграционном тестировании, только тот факт, что что-то удалось завершить, достаточно хорошо. В этом случае Im прохладно с этим.

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

EDIT: В примере, заданном OP, существует некоторый проверяемый результат (результат файла журнала), поэтому, если не было сделано никаких ошибок, чтобы он работал, он ленив.

17

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

2

Это может быть хорошим прагматичным решением, особенно если альтернатива не является испытанием вообще.

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

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

+1

Я не согласен - это не прагматично, оно лениво;) – ryw 2008-09-26 03:35:46

+0

лень - хорошая мотивация для написания поддерживаемого кода :) – 2016-11-08 08:25:39

0

Должен признать, что я никогда не писал блок-тест, который подтвердил, что я правильно регистрирую. Но я подумал об этом и наткнулся на это discussion, как это можно сделать с JUnit и Log4J. Это не слишком красиво, но похоже, что это сработает.

+0

При использовании сторонней структуры для ведения журнала я склонен проверять, что акт регистрации работал правильно, а не напрямую тестирование выходного файла журнала. Я бы связал структуру регистрации, чтобы я мог подделать ее под испытанием и просто обеспечить правильные методы. – 2008-09-26 02:39:55

5

Такой тест запахов. Он должен проверить, что файл был записан, по крайней мере, что, возможно, было изменено время.

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

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

try 
{ 
    unitUnderTest.DoWork() 
} 
catch 
{ 
    Assert.Fail("code should never throw exceptions but failed with ...") 
} 

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

+0

Я должен согласиться. Я лично соглашаюсь, что вы хотите как-то убедиться, что запись произошла, не обязательно, чтобы запись была правильной. – lomaxx 2008-09-26 02:42:57

0

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

+1

Я думаю, что утверждение «всегда должно что-то утверждать» вводит в заблуждение. Тесты должны всегда «доказывать» что-то, но это не требует утверждения «assert». – codeLes 2008-09-26 03:02:07

0

Мы делаем это все время. Мы издеваемся над нашими зависимостями, используя JMock, поэтому я предполагаю, что в некотором смысле структура JMock делает для нас утверждение ... но это происходит примерно так. У нас есть контроллер, который мы хотим проверить:

Class Controller { 
    private Validator validator; 

    public void control(){ 
    validator.validate; 
    } 

    public setValidator(Validator validator){ this.validator = validator; } 
} 

Теперь, когда мы тестируем контроллер мы «не хотим, чтобы проверить валидатор, потому что у него есть свой собственные тесты. поэтому у нас есть тест с JMock просто чтобы убедиться, что мы называем Validate:

public void testControlShouldCallValidate(){ 
    mockValidator.expects(once()).method("validate"); 
    controller.control; 
} 

И это все, нет «утверждения», чтобы увидеть, но при вызове управления и метод «Validate» не вызывается, то Рамка JMock выдает вам исключение (что-то вроде «ожидаемого метода не вызвано» или что-то еще).

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

1

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

5

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

+0

Это необязательные тесты на дым: http://softwaretestingfundamentals.com/smoke-testing/ – camposer 2016-07-05 07:52:13

11

Если нет утверждения, это не тест.

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

0

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

Эти методы, безусловно, не являются модульными испытаниями (даже если они отмечены атрибутом [Test]) и всегда помечены как игнорируемые и явно документированные, когда они проверены в исходном элементе управления.

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

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

1

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

void TestLogDoesNotThrowException(void) { 
    log("blah blah"); 
} 

Как проверить, зарегистрирован ли журнал без утверждения?

Смежные вопросы