При использовании параметризованные тесты JUnit в Eclipse у меня возникает проблема, когда я хочу повторно запустить один тест. Сами тесты проходят нормально, и пока я могу перезапускаю первый тест из контекстного меню, перезапускаю второй тест:
терпит неудачу со следующим сообщением:
java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=test[1: A2 --> [Ljava.lang.String;@1e4a7dd4]], {ExactMatcher:fDisplayName=test[1: A2 --> Ljava.lang.String;@1e4a7dd4]] from org.junit.internal.requests.ClassRequest@6c3f5566
Я почти уверен, что это потому, что JUnit «не нравятся» мои массивы; для некоторого контекста: я использую это, чтобы учесть тот факт, что из-за внешних обстоятельств тестируемый код может дать один из двух результатов для конкретного тестового примера.
Вот некоторый код для воспроизведения этого:
package com.stackexchange.toolbox;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class Tester {
public Tester(String source, Object target) {
this.source = source;
this.target = target;
}
private final String source;
private final Object target;
private static final Object[][] testCases = { { "A1", "B1" }, { "A2", new String[] { "B2", "C2" } } };
@Parameters(name = "{index}: {0} --> {1}")
public static Iterable<Object[]> data() throws Exception {
return new ArrayList<>(Arrays.asList(testCases));
}
@Test
public void test() throws Exception {
if (target instanceof String) {
Assert.assertEquals(source.charAt(1), ((String)target).charAt(1));
} else {
for (String target : (String[])this.target) {
Assert.assertEquals(source.charAt(1), target.charAt(1));
}
}
}
}
Есть ли простой способ исправить это, возможно, с помощью List
s или аргументов с переменным числом аргументов? Большинство (более 100) тестовых примеров представляют собой простые «исходные», «целевые» записи, и я хотел бы сохранить краткость { "A1", "B1" }
.
Кажется, это ограничение JUnit4 (по крайней мере, вы получаете ту же ошибку в командной строке).
Самым простым и понятным решением было бы мигрировать из JUnit4 в JUnit5, что также означало бы меньше кода:
package com.stackexchange.toolbox;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class Tester {
private static final Object[][] testCases = { { "A1", "B1" }, { "A2", new String[] { "B2", "C2" } } };
@ParameterizedTest(name = "{index}: {0} --> {1}")
@MethodSource("provideArguments")
void test(String source, Object target) {
if (target instanceof String) {
Assert.assertEquals(source.charAt(1), ((String)target).charAt(1));
} else {
for (String targetElement : (String[])target) {
Assert.assertEquals(source.charAt(1), targetElement.charAt(1));
}
}
}
static Stream<? extends Arguments> provideArguments() throws Exception {
return Arrays.stream(testCases).map(Arguments::of);
}
}
Я вижу, но я не могу придумать решение этой проблемы. К сожалению, это то же самое для динамические испытания. Может быть, вы можете задать это как отдельный вопрос. В качестве обходного пути для общего числа вы можете добавить третий параметр, чтобы вы могли сделать name = "{index}/{2}: {0} --> {1}"
.
Это работает, спасибо! Мне не хватает одной особенности старого сетапа: тогда сразу становилось видно, сколько тестовых случаев (и можно было отменить тест и запустить конкретный). Кажется, прямо сейчас они транслируются и добавляются один за другим. Фактические тесты стоят несколько секунд, так что это не идеально.