/*
* Copyright 2015-2017 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.junit.jupiter.params;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.junit.jupiter.params.provider.ObjectArrayArguments.arguments;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectMethod;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.displayName;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.event;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.finishedWithFailure;
import static org.junit.platform.engine.test.event.ExecutionEventConditions.test;
import static org.junit.platform.engine.test.event.TestExecutionResultConditions.message;
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.ContainerExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.engine.JupiterTestEngine;
import org.junit.jupiter.params.converter.ArgumentConversionException;
import org.junit.jupiter.params.converter.ArgumentConverter;
import org.junit.jupiter.params.converter.ConvertWith;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.test.event.ExecutionEvent;
import org.junit.platform.engine.test.event.ExecutionEventRecorder;
/**
* @since 5.0
*/
class ParameterizedTestIntegrationTests {
@Test
void executesWithSingleArgumentsProviderWithMultipleInvocations() {
List<ExecutionEvent> executionEvents = execute(
selectMethod(TestCase.class, "testWithTwoSingleStringArgumentsProvider", String.class.getName()));
assertThat(executionEvents) //
.haveExactly(1, event(test(), displayName("[1] foo"), finishedWithFailure(message("foo")))) //
.haveExactly(1, event(test(), displayName("[2] bar"), finishedWithFailure(message("bar"))));
}
@Test
void executesWithStringSource() {
List<ExecutionEvent> executionEvents = execute(
selectMethod(TestCase.class, "testWithStringSource", String.class.getName()));
assertThat(executionEvents) //
.haveExactly(1, event(test(), displayName("[1] foo"), finishedWithFailure(message("foo")))) //
.haveExactly(1, event(test(), displayName("[2] bar"), finishedWithFailure(message("bar"))));
}
@Test
void executesWithCustomName() {
List<ExecutionEvent> executionEvents = execute(
selectMethod(TestCase.class, "testWithCustomName", String.class.getName() + "," + Integer.TYPE.getName()));
assertThat(executionEvents) //
.haveExactly(1, event(test(), displayName("foo and 23"), finishedWithFailure(message("foo, 23")))) //
.haveExactly(1, event(test(), displayName("bar and 42"), finishedWithFailure(message("bar, 42"))));
}
@Test
void executesWithExplicitConverter() {
List<ExecutionEvent> executionEvents = execute(
selectMethod(TestCase.class, "testWithExplicitConverter", Integer.TYPE.getName()));
assertThat(executionEvents) //
.haveExactly(1, event(test(), displayName("[1] O"), finishedWithFailure(message("length: 1")))) //
.haveExactly(1, event(test(), displayName("[2] XXX"), finishedWithFailure(message("length: 3"))));
}
@Test
void executesLifecycleMethods() {
// reset static collections
LifecycleTestCase.lifecycleEvents.clear();
LifecycleTestCase.testMethods.clear();
List<ExecutionEvent> executionEvents = execute(selectClass(LifecycleTestCase.class));
assertThat(executionEvents) //
.haveExactly(1, event(test("test1"), displayName("[1] foo"), finishedWithFailure(message("foo")))) //
.haveExactly(1, event(test("test1"), displayName("[2] bar"), finishedWithFailure(message("bar"))));
List<String> testMethods = new ArrayList<>(LifecycleTestCase.testMethods);
// @formatter:off
assertThat(LifecycleTestCase.lifecycleEvents).containsExactly(
"beforeAll:ParameterizedTestIntegrationTests$LifecycleTestCase", //
"providerMethod",
"constructor:ParameterizedTestIntegrationTests$LifecycleTestCase",
"beforeEach:[1] foo",
testMethods.get(0) + ":[1] foo",
"afterEach:[1] foo",
"constructor:ParameterizedTestIntegrationTests$LifecycleTestCase",
"beforeEach:[2] bar",
testMethods.get(0) + ":[2] bar",
"afterEach:[2] bar",
"providerMethod",
"constructor:ParameterizedTestIntegrationTests$LifecycleTestCase",
"beforeEach:[1] foo",
testMethods.get(1) + ":[1] foo",
"afterEach:[1] foo",
"constructor:ParameterizedTestIntegrationTests$LifecycleTestCase",
"beforeEach:[2] bar",
testMethods.get(1) + ":[2] bar",
"afterEach:[2] bar",
"afterAll:ParameterizedTestIntegrationTests$LifecycleTestCase");
// @formatter:on
}
private List<ExecutionEvent> execute(DiscoverySelector... selectors) {
return ExecutionEventRecorder.execute(new JupiterTestEngine(), request().selectors(selectors).build());
}
static class TestCase {
@ParameterizedTest(name = " \t ")
@ArgumentsSource(TwoSingleStringArgumentsProvider.class)
void testWithTwoSingleStringArgumentsProvider(String argument) {
fail(argument);
}
@ParameterizedTest
@CsvSource({ "foo", "bar" })
void testWithStringSource(String argument) {
fail(argument);
}
@ParameterizedTest(name = "{0} and {1}")
@CsvSource({ "foo, 23", "bar, 42" })
void testWithCustomName(String argument, int i) {
fail(argument + ", " + i);
}
@ParameterizedTest
@ValueSource(strings = { "O", "XXX" })
void testWithExplicitConverter(@ConvertWith(StringLengthConverter.class) int length) {
fail("length: " + length);
}
}
static class LifecycleTestCase {
private static final List<String> lifecycleEvents = new ArrayList<>();
private static final Set<String> testMethods = new LinkedHashSet<>();
public LifecycleTestCase(TestInfo testInfo) {
lifecycleEvents.add("constructor:" + testInfo.getDisplayName());
}
@BeforeAll
static void beforeAll(TestInfo testInfo) {
lifecycleEvents.add("beforeAll:" + testInfo.getDisplayName());
}
@AfterAll
static void afterAll(TestInfo testInfo) {
lifecycleEvents.add("afterAll:" + testInfo.getDisplayName());
}
@BeforeEach
void beforeEach(TestInfo testInfo) {
lifecycleEvents.add("beforeEach:" + testInfo.getDisplayName());
}
@AfterEach
void afterEach(TestInfo testInfo) {
lifecycleEvents.add("afterEach:" + testInfo.getDisplayName());
}
@ParameterizedTest
@MethodSource("providerMethod")
void test1(String argument, TestInfo testInfo) {
performTest(argument, testInfo);
}
@ParameterizedTest
@MethodSource("providerMethod")
void test2(String argument, TestInfo testInfo) {
performTest(argument, testInfo);
}
private void performTest(String argument, TestInfo testInfo) {
String testMethod = testInfo.getTestMethod().get().getName();
testMethods.add(testMethod);
lifecycleEvents.add(testMethod + ":" + testInfo.getDisplayName());
fail(argument);
}
static Stream<String> providerMethod() {
lifecycleEvents.add("providerMethod");
return Stream.of("foo", "bar");
}
}
private static class TwoSingleStringArgumentsProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ContainerExtensionContext context) throws Exception {
return Stream.of(arguments("foo"), arguments("bar"));
}
}
private static class StringLengthConverter implements ArgumentConverter {
@Override
public Object convert(Object input, ParameterContext context) throws ArgumentConversionException {
return String.valueOf(input).length();
}
}
}