Статьи

Параметризованный тестовый бегун в JUnit

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

Приведенный ниже код вычисляет ряд Фибоначчи для числа упомянутых элементов:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
 
public class Fibonacci{
 
  public List<Integer> getFiboSeries(int numberOfElements) {
    List<Integer> fiboSeries = new ArrayList<>(numberOfElements);
    for (int i = 0; i < numberOfElements; i++) {
      //First 2 elements are 1,1
      if (i == 0 || i == 1) {
        fiboSeries.add(i, 1);
      } else {
        int firstPrev = fiboSeries.get(i - 2);
        int secondPrev = fiboSeries.get(i - 1);
        int fiboElement = firstPrev + secondPrev;
        fiboSeries.add(i, fiboElement);
      }
    }
    return fiboSeries;
  }
 
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.List;
import org.junit.Test;
import java.util.Arrays;
import static org.junit.Assert.*;
 
public class FibonacciCachedTest {
 
  /**
   * Test of getFiboSeries method, of class Fibonacci.
   */
  @Test
  public void testGetFiboSeries() {
    System.out.println("getFiboSeries");
    int numberOfElements = 5;
    Fibonacci instance = new Fibonacci();
    List<Integer> expResult = Arrays.asList(1, 1, 2, 3, 5);
    List<Integer> result = instance.getFiboSeries(numberOfElements);
    assertEquals(expResult, result);
 
    numberOfElements = 10;
    expResult = Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21, 34, 55);
    result = instance.getFiboSeries(numberOfElements);
    assertEquals(expResult, result);
 
  }
}

Итак, мы смогли протестировать 2 входа, представьте, что вы расширили вышеуказанное для большего количества входов? Ненужное раздувание в тестовом коде.

JUnit предоставляет другой Runner, называемый Parameterized runner, который предоставляет статический метод, аннотированный @Parameters . Этот метод должен быть реализован для возврата входных и ожидаемых выходных данных, которые будут использоваться для запуска теста, определенного в классе. Давайте посмотрим на код, который делает это:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
 
@RunWith(Parameterized.class)
public class ParametrizedFiboTest {
 
  private final int number;
  private final List<Integer> values;
 
  public ParametrizedFiboTest(FiboInput input) {
    this.number = input.number;
    this.values = input.values;
  }
 
  @Parameterized.Parameters
  public static Collection<Object[]> fiboData() {
    return Arrays.asList(new Object[][]{
      {new FiboInput(1, Arrays.asList(1))},
      {new FiboInput(2, Arrays.asList(1, 1))},
      {new FiboInput(3, Arrays.asList(1, 1, 2))},
      {new FiboInput(4, Arrays.asList(1, 1, 2, 3))},
      {new FiboInput(5, Arrays.asList(1, 1, 2, 3, 5))},
      {new FiboInput(6, Arrays.asList(1, 1, 2, 3, 5, 8))}
    });
  }
 
  @Test
  public void testGetFiboSeries() {
    FibonacciUncached instance = new FibonacciUncached();
    List<Integer> result = instance.getFiboSeries(this.number);
    assertEquals(this.values, result);
  }
 
}
 
class FiboInput {
 
  public int number;
  public List<Integer> values;
 
  public FiboInput(int number, List<Integer> values) {
    this.number = number;
    this.values = values;
  }
}

Таким образом, нам просто нужно добавить новый ввод и ожидаемый вывод в fiboData() чтобы это работало!

Ссылка: Параметризованный тестовый тестер в JUnit от нашего партнера JCG Мохамеда Санауллы в блоге Experiences Unlimited