Skip to content

Commit cff6fdb

Browse files
authored
fix: fix JUnit discovery with older Java preview settings (#1938)
* fix: discover JUnit tests with older Java preview settings * Fix Checkstyle errors in preview discovery * Use project compiler options in preview discovery test * Limit preview fallback to discovery and include sibling tests * Exercise preview fallback through public discovery APIs * Resolve sibling test type from its compilation unit * Handle non-class top-level declarations during discovery
1 parent 84fa601 commit cff6fdb

9 files changed

Lines changed: 311 additions & 21 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ All notable changes to the "vscode-java-test" extension will be documented in th
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## Unreleased
8+
* Fix JUnit test discovery for projects using preview features from an older Java release.
9+
710
## 0.46.0
811
## What's Changed
912
* feat - Run multiple selected test methods in a single JVM in https://github.com/microsoft/vscode-java-test/pull/1862
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
4+
<attributes>
5+
<attribute name="test" value="true"/>
6+
</attributes>
7+
</classpathentry>
8+
<classpathentry kind="con"
9+
path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
10+
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
11+
<classpathentry kind="output" path="target/test-classes"/>
12+
</classpath>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>preview-junit</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.jdt.core.javanature</nature>
16+
</natures>
17+
</projectDescription>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package example;
2+
3+
class Helper {
4+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package example;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
public class MiniTest {
6+
@Test
7+
void first() {
8+
}
9+
10+
@Test
11+
void second() {
12+
}
13+
}
14+
15+
enum HelperEnum {
16+
VALUE
17+
}
18+
19+
record HelperRecord(int value) {
20+
}
21+
22+
@interface HelperAnnotation {
23+
}
24+
25+
class SiblingTest {
26+
@Test
27+
void siblingTest() {
28+
}
29+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package example;
2+
3+
import org.junit.jupiter.api.Nested;
4+
import org.junit.jupiter.api.Test;
5+
6+
public class NestedOnlyTest {
7+
@Nested
8+
class Child {
9+
@Test
10+
void nestedTest() {
11+
}
12+
}
13+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.test.plugin.util;
13+
14+
import static org.junit.Assert.assertEquals;
15+
import static org.junit.Assert.assertNotNull;
16+
import static org.junit.Assert.assertNull;
17+
import static org.junit.Assert.assertTrue;
18+
19+
import java.util.Arrays;
20+
import java.util.List;
21+
22+
import org.eclipse.core.resources.IProject;
23+
import org.eclipse.core.runtime.NullProgressMonitor;
24+
import org.eclipse.jdt.core.ICompilationUnit;
25+
import org.eclipse.jdt.core.IJavaProject;
26+
import org.eclipse.jdt.core.IType;
27+
import org.eclipse.jdt.core.JavaCore;
28+
import org.eclipse.jdt.core.compiler.IProblem;
29+
import org.eclipse.jdt.core.dom.AST;
30+
import org.eclipse.jdt.core.dom.ASTParser;
31+
import org.eclipse.jdt.core.dom.CompilationUnit;
32+
import org.eclipse.jdt.core.dom.TypeDeclaration;
33+
import org.junit.Test;
34+
35+
import com.microsoft.java.test.plugin.AbstractProjectsManagerBasedTest;
36+
import com.microsoft.java.test.plugin.model.JavaTestItem;
37+
38+
public class TestSearchUtilsTest extends AbstractProjectsManagerBasedTest {
39+
40+
@Test
41+
public void testDiscoverJUnit5TestsWithOlderPreviewSource() throws Exception {
42+
final IProject project = importProjects("preview-junit").get(0);
43+
final IJavaProject javaProject = JavaCore.create(project);
44+
final IType type = javaProject.findType("example.MiniTest");
45+
assertNotNull(type);
46+
final ICompilationUnit unit = type.getCompilationUnit();
47+
javaProject.setOption(JavaCore.COMPILER_SOURCE, "17");
48+
javaProject.setOption(JavaCore.COMPILER_COMPLIANCE, "17");
49+
javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
50+
51+
final ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
52+
parser.setSource(unit);
53+
parser.setCompilerOptions(javaProject.getOptions(true));
54+
parser.setResolveBindings(true);
55+
final CompilationUnit invalid = (CompilationUnit) parser.createAST(new NullProgressMonitor());
56+
assertTrue(Arrays.stream(invalid.getProblems())
57+
.anyMatch(problem -> problem.getID() == IProblem.PreviewFeaturesNotAllowed));
58+
assertNull(((TypeDeclaration) invalid.types().get(0)).resolveBinding());
59+
60+
final List<JavaTestItem> fileTests = TestSearchUtils.findTestTypesAndMethods(
61+
Arrays.asList(unit.getResource().getLocationURI().toString()), new NullProgressMonitor());
62+
assertEquals(2, fileTests.size());
63+
assertEquals("MiniTest", fileTests.get(0).getLabel());
64+
assertEquals(2, fileTests.get(0).getChildren().size());
65+
assertEquals("SiblingTest", fileTests.get(1).getLabel());
66+
assertEquals(1, fileTests.get(1).getChildren().size());
67+
68+
final ICompilationUnit helper = javaProject.findType("example.Helper").getCompilationUnit();
69+
assertTrue(TestSearchUtils.findTestTypesAndMethods(
70+
Arrays.asList(helper.getResource().getLocationURI().toString()), new NullProgressMonitor()).isEmpty());
71+
72+
final IType nestedType = javaProject.findType("example.NestedOnlyTest");
73+
final List<JavaTestItem> nestedTests = TestSearchUtils.findTestTypesAndMethods(
74+
Arrays.asList(nestedType.getResource().getLocationURI().toString()), new NullProgressMonitor());
75+
assertEquals("Child", nestedTests.get(0).getChildren().get(0).getLabel());
76+
77+
final List<JavaTestItem> packages = TestSearchUtils.findTestPackagesAndTypes(
78+
Arrays.asList(javaProject.getHandleIdentifier()), new NullProgressMonitor());
79+
assertEquals(1, packages.size());
80+
assertEquals(3, packages.get(0).getChildren().size());
81+
assertTrue(packages.get(0).getChildren().stream().anyMatch(item -> "MiniTest".equals(item.getLabel())));
82+
assertTrue(packages.get(0).getChildren().stream().anyMatch(item -> "SiblingTest".equals(item.getLabel())));
83+
assertTrue(packages.get(0).getChildren().stream().anyMatch(item -> "NestedOnlyTest".equals(item.getLabel())));
84+
85+
final List<JavaTestItem> methods = TestSearchUtils.findDirectTestChildrenForClass(
86+
Arrays.asList(type.getHandleIdentifier()), new NullProgressMonitor());
87+
assertEquals(2, methods.size());
88+
final IType siblingType = unit.getType("SiblingTest");
89+
final List<JavaTestItem> siblingMethods = TestSearchUtils.findDirectTestChildrenForClass(
90+
Arrays.asList(siblingType.getHandleIdentifier()), new NullProgressMonitor());
91+
assertEquals(1, siblingMethods.size());
92+
final List<JavaTestItem> nestedChildren = TestSearchUtils.findDirectTestChildrenForClass(
93+
Arrays.asList(nestedType.getHandleIdentifier()), new NullProgressMonitor());
94+
assertEquals("Child", nestedChildren.get(0).getLabel());
95+
assertEquals(JavaCore.ENABLED, javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true));
96+
}
97+
}

‎java-extension/com.microsoft.java.test.plugin/META-INF/MANIFEST.MF‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Require-Bundle: org.eclipse.jdt.core,
5454
Export-Package: com.microsoft.java.test.plugin.launchers;x-friends:="com.microsoft.java.test.plugin.test",
5555
com.microsoft.java.test.plugin.model;x-friends:="com.microsoft.java.test.plugin.test",
5656
com.microsoft.java.test.plugin.searcher;x-friends:="com.microsoft.java.test.plugin.test",
57+
com.microsoft.java.test.plugin.util;x-friends:="com.microsoft.java.test.plugin.test",
5758
com.microsoft.java.test.plugin.coverage;x-friends:="com.microsoft.java.test.plugin.test",
5859
com.microsoft.java.test.plugin.coverage.model;x-friends:="com.microsoft.java.test.plugin.test"
5960
Bundle-ClassPath: .

0 commit comments

Comments
 (0)