Skip to content

Commit

Permalink
Add test class JUnit5TestFinderJupiterTest
Browse files Browse the repository at this point in the history
The class contains some tests that cover the current capabilities of
JUnit5TestFinder and it was missing from the tests.
This class does NOT resemble the other 2 existing classes:
JUnit3TestFinder and JUnit4TestFinder
  • Loading branch information
fedejeanne committed Dec 5, 2023
1 parent 6276394 commit 4d7f291
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 1 deletion.
3 changes: 2 additions & 1 deletion org.eclipse.jdt.ui.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ Require-Bundle:
Bundle-RequiredExecutionEnvironment: JavaSE-17
Eclipse-BundleShape: dir
Bundle-ActivationPolicy: lazy
Import-Package: org.junit.jupiter.api,
Import-Package: org.assertj.core.api;version="3.24.2",
org.junit.jupiter.api,
org.junit.platform.suite.api,
org.junit.platform.suite.commons;status=INTERNAL,
org.junit.platform.suite.engine;status=INTERNAL
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestTemplate;

import junit.framework.TestCase;

/**
* This class contains some internal classes that should be found/not found by the
* JUnit5TestFinder.<br/>
* <br/>
* The names of the classes give a hint about whether or not the class should be found and the
* reason for that. In order to be discovered, a class needs to fulfill these requirements:
* <ul>
* <li>It should be visible (it can <strong>not</strong> be <code>private</code>)</li>
* <li>It must have tests in it.</li>
* </ul>
*
* Whether or not the class can be instantiated (<i>i.e.</i> if they have a non-private empty
* constructor) does not play a role in the discoverability, but running tests on that class will
* throw an exception,
*/
class JupiterTests {
/**
* Methods using this annotation are also considered tests
*/
@Test
@Retention(RetentionPolicy.RUNTIME)
@interface CustomTestAnnotation {}

static class FoundStatic {
@Test void myTest() {}
}

static class FoundStaticCustomTestAnnotation {
@CustomTestAnnotation void myTest() {}
}

private static class NotFoundPrivate {
@CustomTestAnnotation void myTest() {}
}

static class NotFoundHasNoTests {}

static class FoundExtendsTestCase extends TestCase {
@Test void myTest() {}
}

static class FoundExtendsTestCaseCustomTestAnnotation extends TestCase {
@CustomTestAnnotation public void myTest() {}
}

private static class NotFoundPrivateExtendsTestCase extends TestCase {
@Test public void myTest() {}
}

static class FoundTestTemplateClass {
@TestTemplate void myTestTemplate() {}
}

static abstract class NotFoundAbstractWithInnerClass {
class NotFoundInnerInstanceClassWithTest {
@Test void myTest() {}
}
}

static class NotFoundExtendsAbstractWithInnerWithTest extends NotFoundAbstractWithInnerClass {}

static class FoundHasInnerClassWithNested {
@Nested class FoundExtendsAbstractWithNested extends NotFoundAbstractWithInnerClass {
@Test void myTest() {}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*******************************************************************************
* Copyright (c) 2023 Vector Informatik GmbH and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Vector Informatik GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.junit.tests;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import org.eclipse.jdt.junit.JUnitCore;
import org.eclipse.jdt.testplugin.JavaProjectHelper;

import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.junit.launcher.JUnit5TestFinder;


/**
* Test if the <code>JUnit5TestFinder</code> can find tests annotated with the API of JUnit5
* (Jupiter)
*/
@RunWith(Parameterized.class)
public class JUnit5TestFinderJupiterTest {

record TestScenario(String testClass, int testTypesCount) {
}

private static final String JAVA_CLASS_NAME= "JupiterTests";

private static final String JAVA_FILE_NAME= JAVA_CLASS_NAME + ".java";

private static final Path TEST_CLASS_FILE= Path.of("testresources").resolve("testClasses").resolve(JAVA_FILE_NAME);

private static IJavaProject javaProject;

@Parameters(name= "{0}")
public static Collection<TestScenario> getCompilationUnits() {

// These are the current "valid" results
return List.of(new TestScenario(JAVA_CLASS_NAME, 7), //
new TestScenario("CustomTestAnnotation", 0), // Not a test class
new TestScenario("FoundStatic", 1), //
new TestScenario("FoundStaticCustomTestAnnotation", 1), //
new TestScenario("NotFoundPrivate", 0), // private class
new TestScenario("NotFoundHasNoTests", 0), // empty class (no tests)
new TestScenario("FoundExtendsTestCase", 1), //
new TestScenario("FoundExtendsTestCaseCustomTestAnnotation", 1), //
new TestScenario("NotFoundPrivateExtendsTestCase", 0), // private class
new TestScenario("FoundTestTemplateClass", 1), //
new TestScenario("NotFoundAbstractWithInnerClass", 0), // can't be instantiated
new TestScenario("NotFoundExtendsAbstractWithInnerWithTest", 0), // FIXME: why isn't this one found even though it can be instantiated?
new TestScenario("FoundHasInnerClassWithNested", 1), //
new TestScenario("NotFoundInnerInstanceClassWithTest", 0), // has test but it can't be instantiated (needs enclosing instance)
new TestScenario("FoundExtendsAbstractWithNested", 1) //
);

}

@Parameter
public TestScenario scenario;

private static ICompilationUnit compilationUnit;

@BeforeClass
public static void beforeClass() throws Exception {
javaProject= JavaProjectHelper.createJavaProject("TestProject", "bin");
JavaProjectHelper.addRTJar(javaProject);
IClasspathEntry cpe= JavaCore.newContainerEntry(JUnitCore.JUNIT5_CONTAINER_PATH);
JavaProjectHelper.addToClasspath(javaProject, cpe);
JavaProjectHelper.set18CompilerOptions(javaProject);

IPackageFragmentRoot root= JavaProjectHelper.addSourceContainer(javaProject, "src");
IPackageFragment packageFragment= root.createPackageFragment("somepackage", true, null);

compilationUnit= createCompilationUnit(packageFragment);
}

@AfterClass
public static void afterClass() throws Exception {
JavaProjectHelper.delete(javaProject);
}

@Test
public void testFindTestsInContainer() throws Exception {
IType type= findTypeWithName(scenario.testClass());
Set<IType> foundTestTypes= new HashSet<>();

JUnit5TestFinder objectUnderTest= new JUnit5TestFinder();
objectUnderTest.findTestsInContainer(type, foundTestTypes, null);

assertThat(foundTestTypes).hasSize(scenario.testTypesCount());
}


private IType findTypeWithName(String name) throws JavaModelException {
for (IType type : compilationUnit.getAllTypes()) {
if (type.getElementName().equals(name))
return type;
}
return null;
}

private static ICompilationUnit createCompilationUnit(IPackageFragment packageFragment) throws IOException {
String content= Files.readString(TEST_CLASS_FILE);

try {
return packageFragment.createCompilationUnit(JAVA_FILE_NAME, content, false, null);
} catch (JavaModelException e) {
// let the test fail
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
JUnit3TestFinderTest.class,
JUnit4TestFinderTest.class,
JUnit4TestFinderTest16.class,
JUnit5TestFinderJupiterTest.class,

TestSorting.class
//LegacyTestRunListenerTest.class
Expand Down

0 comments on commit 4d7f291

Please sign in to comment.