Перейти к основному содержимому

Как получить имя текущего выполняемого теста в JUnit?

· 4 мин. чтения

Задача: Сумма двух чисел

Напишите функцию twoSum. Которая получает массив целых чисел nums и целую сумму target, а возвращает индексы двух чисел, сумма которых равна target. Любой набор входных данных имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды. Ответ можно возвращать в любом порядке...

ANDROMEDA

1. Обзор

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

В этом кратком руководстве мы рассмотрим, как получить имя текущего тестового примера как в JUnit 4 , так и в JUnit 5 .

2. Подход JUnit 5

Давайте рассмотрим два сценария. Во-первых, мы увидим, как получить доступ к имени одного теста. Это имя обычно предсказуемо, так как это, вероятно, имя функции или значение аннотации @DisplayName . Однако, если мы используем параметризованные тесты или генераторы отображаемых имен , нам может понадобиться знать имя, предоставленное JUnit.

JUnit 5 может внедрить объект TestInfo в наши тесты , чтобы показать нам имя текущего тестового примера.

2.1. Индивидуальный тест

Давайте добавим объект TestInfo в нашу тестовую функцию:

@Test
void givenNumbers_whenOddCheck_thenVerify(TestInfo testInfo) {
System.out.println("displayName = " + testInfo.getDisplayName());
int number = 5;
assertTrue(oddCheck(number));
}

Здесь мы использовали метод getDisplayName интерфейса TestInfo для отображения имени теста . Когда мы запускаем тест, мы получаем имя теста:

displayName = givenNumbers_whenOddCheck_thenVerify(TestInfo)

2.2. Параметризованный тест

Давайте попробуем это с параметризованным тестом . Здесь мы будем использовать поле имени аннотации @ParameterizedTest , чтобы описать JUnit, как создать для нас имя теста:

private TestInfo testInfo;

@BeforeEach
void init(TestInfo testInfo) {
this.testInfo = testInfo;
}

@ParameterizedTest(name = "givenNumbers_whenOddCheck_thenVerify{0}")
@ValueSource(ints = { 1, 3, 5, -3, 15 })
void givenNumbers_whenOddCheck_thenVerify(int number) {
System.out.println("displayName = " + testInfo.getDisplayName());
assertTrue(oddCheck(number));
}

Следует отметить, что, в отличие от отдельного теста, мы не можем внедрить TestInfo в функцию. Это связано с тем, что параметры функции должны относиться к параметризованным данным. Чтобы решить эту проблему, нам нужно сохранить TestInfo в поле тестового класса с помощью метода beforeEach .

Когда мы запускаем тест, мы получаем имена тестов:

displayName = givenNumbers_whenOddCheck_thenVerify5
displayName = givenNumbers_whenOddCheck_thenVerify-3
displayName = givenNumbers_whenOddCheck_thenVerify3
displayName = givenNumbers_whenOddCheck_thenVerify1
displayName = givenNumbers_whenOddCheck_thenVerify15

3. Подход JUnit 4

JUnit 4 может заполнять объект TestName в наших тестах . TestName — это правило JUnit , и правила выполняются как часть выполнения теста JUnit, попутно показывая им детали текущего выполняемого теста.

3.1. Индивидуальный тест

Рассмотрим индивидуальный тест:

@Rule
public TestName name = new TestName();

@Test
public void givenString_whenSort_thenVerifySortForString() {
System.out.println("displayName = " + name.getMethodName());
String s = "abc";
assertEquals(s, sortCharacters("cba"));
}

Как показано выше, мы можем использовать метод getMethodName класса TestName для отображения имени теста .

Запустим тест:

displayName = givenString_whenSort_thenVerifySortForString

3.2. Параметризованный тест

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

@RunWith(Parameterized.class)
public class JUnit4ParameterizedTestNameUnitTest {
}

Затем мы можем реализовать тест как с правилом TestName , так и с полями и конструктором для присвоения значений параметров текущего теста:

@Rule
public TestName name = new TestName();
private String input;
private String expected;
public JUnit4ParameterizedTestNameUnitTest(String input, String expected) {
this.input = input;
this.expected = expected;
}

@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> suppliedData() {
return Arrays.asList(new Object[][] {
{ "abc", "abc" }, { "cba", "abc" }, { "onm", "mno" }, { "a", "a" }, { "zyx", "xyz" }});
}

@Test
public void givenString_whenSort_thenVerifySortForString() {
System.out.println("displayName = " + name.getMethodName());
assertEquals(expected, sortCharacters(input));
}

В этом тесте мы предоставляем набор тестовых данных , который содержит как входные, так и ожидаемые строки. Это делается с помощью поставляемой функции Data, аннотированной аннотацией @Parameterized.Parameters . Эта аннотация также позволяет нам описать имя теста.

Когда мы запускаем тест, правилу TestName присваиваются имена каждого теста, которые мы можем видеть:

displayName = givenString_whenSort_thenVerifySortForString[abc]
displayName = givenString_whenSort_thenVerifySortForString[cba]
displayName = givenString_whenSort_thenVerifySortForString[onm]
displayName = givenString_whenSort_thenVerifySortForString[a]
displayName = givenString_whenSort_thenVerifySortForString[zyx]

4. Вывод

В этой статье мы обсудили, как найти имя текущего теста как в JUnit 4, так и в 5.

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

Как обычно, полный исходный код доступен на GitHub .