2017-01-05 5 views
2

Я пытаюсь реализовать модульные тесты, соблюдая best practices. Одно из правил - использовать только одно «утверждение» методом. Я хотел бы реализовать несколько тестов методом, потому что есть тяжелое лечение, которое производится в начале каждого метода (вставка в базу данных -> 5 секунд).Java JUNIT - несколько тестов со строкой

Я разработал это решение, это хорошая практика?

String failuresMsg = ""; 
if(9 != var1) 
    failuresMsg += "[var1 <9," + var1+">]"; 
if(9 != var2) 
    failuresMsg += "[var2 <9," + var2+">]"; 
if(9 != var3) 
    failuresMsg += "[var3 <9," + var3+">]"; 
if(9 != var4) 
    failuresMsg += "[var4 <9," + var4+">]"; 

assertEquals("", failuresMsg); 

ответ

3

Одним из правил является использование только один «утверждают» методом.

Нет, вы должны ограничить себя испытанием сценария методом тестирования. Это не одно и то же.

String failuresMsg = ""; 
if(9 != var1) 
    failuresMsg += "[var1 <9," + var1+">]"; 
if(9 != var2) 
    failuresMsg += "[var2 <9," + var2+">]"; 
if(9 != var3) 
    failuresMsg += "[var3 <9," + var3+">]"; 
if(9 != var4) 
    failuresMsg += "[var4 <9," + var4+">]"; 

assertEquals("", failuresMsg); 

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

В случае если взять тест, он даст 2 методы испытаний (или больше в зависимости от способа видеть вещи), потому что у меня есть два различных сценария:

  • значение является приемлемым

  • значение не является приемлемым

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

Вот пример кода:

@Test 
public void doMethodWithAcceptableValues(){ 
    int testValue = 0; 
    Assert.assertTrue(objUnderTest.doMethod(testValue)); 
    testValue = 100; // limit value 
    Assert.assertTrue(objUnderTest.doMethod(testValue)); 
    testValue = 50; // middle value 50. it is an example 
    Assert.assertTrue(objUnderTest.doMethod(testValue)); 
} 

@Test 
public void doMethodWithNotAcceptableValues(){ 
    int testValue = -1; 
    Assert.assertFalse("-1 not acceptable", objUnderTest.doMethod(testValue)); 
    testValue = 101; // limit value 
    Assert.assertFalse("101 not acceptable", objUnderTest.doMethod(testValue)); 
} 

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

+0

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

+0

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

+0

ОК, спасибо за этот четкий ответ. –

3

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

Пример:

@RunWith(JUnitParamsRunner.class) 
public class TestSomething{ 

    @Test 
    @Parameters({ "A", "B", "C" }) 
    public void shouldDoSomething(String s){ 

    assertEquals(s, "s"); 
    } 

    //OR 

    @Test 
    @Parameters(method = "data") 
    public void shouldSomething(String a, String b){ 

    assertEquals(a,b); 
    } 

    @SuppressWarnings("unused") 
    private Object[] data() { 
    return $(// 
    $("A", "B") // 
); 
} 
} 

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

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