Skip to content

Commit

Permalink
Fix FP on S2187 in Cucumber tests with JUnit5.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasz-tylenda-sonarsource committed Dec 24, 2024
1 parent 71f25f0 commit 15d752b
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
17 changes: 17 additions & 0 deletions java-checks-test-sources/default/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,23 @@
<artifactId>jspecify</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.20.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit-platform-engine</artifactId>
<version>7.20.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package checks.tests;

import static io.cucumber.junit.platform.engine.Constants.*;

import org.junit.platform.suite.api.*;

@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("com.project.class.path")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value="com.project.class.path")
public class NoTestInTestClassCheckCucumberTest {}

@Suite
@org.junit.platform.suite.api.IncludeEngines("cucumber")
@SelectClasspathResource("com.project.class.path")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value="com.project.class.path")
class NoTestInTestClassCheckCucumberFQTest {}

@Suite
@IncludeEngines("bellpepper")
@SelectClasspathResource("com.project.class.path")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value="com.project.class.path")
class NoTestInTestClassCheckBellPepperTest {} // Noncompliant
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ private static boolean containsJUnit3Tests(List<Symbol> members) {

private void checkJunit4AndAboveTestClass(IdentifierTree className, Symbol.TypeSymbol symbol, List<Symbol> members) {
addUsedAnnotations(symbol);
if (!runWithCucumberOrSuiteOrTheoriesRunner(symbol)
&& members.stream().noneMatch(this::isTestFieldOrMethod)) {

if (!runWithCucumberOrSuiteOrTheoriesRunner(symbol) && members.stream().noneMatch(this::isTestFieldOrMethod)) {
reportClass(className);
}
}
Expand All @@ -170,7 +170,8 @@ private void addUsedAnnotations(Symbol.TypeSymbol classSymbol) {
}

private static boolean runWithCucumberOrSuiteOrTheoriesRunner(Symbol.TypeSymbol symbol) {
return checkRunWith(symbol, "Cucumber", "Suite", "Theories");
return annotatedIncludeEnginesCucumber(symbol)
|| checkRunWith(symbol, "Cucumber", "Suite", "Theories");
}

private static boolean runWithZohhak(Symbol.TypeSymbol symbol) {
Expand Down Expand Up @@ -199,6 +200,32 @@ private static boolean checkRunWithType(Symbol.TypeSymbol value, String... runne
return false;
}

/**
* True is the symbol is annotated {@code @IncludeEngines("cucumber")}.
*/
private static boolean annotatedIncludeEnginesCucumber(Symbol.TypeSymbol symbol) {
SymbolMetadata metadata = symbol.metadata();

List<SymbolMetadata.AnnotationInstance> annotations = metadata.annotations();
for (SymbolMetadata.AnnotationInstance annotation: annotations) {
if (annotation.symbol().type().fullyQualifiedName().endsWith("IncludeEngines")) {
// values are not available in automatic analysis, so assume "cucumber" is there
if (annotation.values().isEmpty()) {
return true;
}
// otherwise check the list
boolean containsCucumber = annotation.values().stream().anyMatch(annotationValue ->
annotationValue.value() instanceof Object[] vals
&& vals.length == 1
&& "cucumber".equals(vals[0]));
if (containsCucumber) {
return true;
}
}
}
return false;
}

private boolean isTestFieldOrMethod(Symbol member) {
return member.metadata().annotations().stream().anyMatch(input -> {
Type type = input.symbol().type();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,22 @@ void testNg() {
.withCheck(new NoTestInTestClassCheck())
.verifyIssues();
}

@Test
void testCucumber() {
CheckVerifier.newVerifier()
.onFile(testCodeSourcesPath("checks/tests/NoTestInTestClassCheckCucumberTest.java"))
.withCheck(new NoTestInTestClassCheck())
.verifyIssues();
}

@Test
void testCucumberWithoutSemantic() {
CheckVerifier.newVerifier()
.onFile(testCodeSourcesPath("checks/tests/NoTestInTestClassCheckCucumberTest.java"))
.withCheck(new NoTestInTestClassCheck())
.withoutSemantic()
// Note, that the sample file contains a noncompliant test, but we are fine with FN in automatic analysis
.verifyNoIssues();
}
}

0 comments on commit 15d752b

Please sign in to comment.