Move likely test method logic to library

This commit is contained in:
Tamas Vajk
2025-03-14 11:31:53 +01:00
parent 05502bc74e
commit 9662b47464
3 changed files with 46 additions and 59 deletions

View File

@@ -66,6 +66,19 @@ class TestClass extends Class {
}
}
/**
* A class that is likely a test class. That is either a definite test class, or
* a class whose name, package, or location suggests that it might be a test class.
*/
class LikelyTestClass extends Class {
LikelyTestClass() {
this instanceof TestClass or
this.getName().toLowerCase().matches("%test%") or
this.getPackage().getName().toLowerCase().matches("%test%") or
this.getLocation().getFile().getAbsolutePath().matches("%/src/test/java%")
}
}
/**
* A test method declared within a JUnit 3.8 test class.
*/
@@ -185,6 +198,37 @@ class TestMethod extends Method {
}
}
/**
* Any method that is likely a test method.
*/
class LikelyTestMethod extends Method {
LikelyTestMethod() {
this.getDeclaringType() instanceof LikelyTestClass
or
this instanceof TestMethod
or
this instanceof LikelyJunitTest
}
}
/**
* A `Method` that is public, has no parameters,
* has a "void" return type, AND either has a name that starts with "test" OR
* has an annotation that ends with "Test"
*/
class LikelyJunitTest extends Method {
LikelyJunitTest() {
this.isPublic() and
this.getReturnType().hasName("void") and
this.hasNoParameters() and
(
this.getName().matches("JUnit%") or
this.getName().matches("test%") or
this.getAnAnnotation().getType().getName().matches("%Test")
)
}
}
/**
* A TestNG annotation used to mark a method that runs "before".
*/

View File

@@ -16,59 +16,7 @@
import java
/**
* Represents a likely a test method, which is either a method that is already
* recognized as a `TestMethod` or something that is likely a JUnit test or
* something in the expected test path for Java tests.
*/
class LikelyTestMethod extends Method {
LikelyTestMethod() {
this.getDeclaringType() instanceof TestClass
or
this instanceof TestMethod
or
this instanceof LikelyJunitTest
or
//standard Maven/Gradle test file discovery filepath
this.getFile().getAbsolutePath().matches("%src/test/java%")
or
this.getDeclaringType() instanceof SurefireTest
}
}
/**
* Classes that are likely part of junit tests (more general than `TestMethod` from `UnitTest.qll`)
* A `Method` that is public, has no parameters,
* has a "void" return type, AND either has a name that starts with "test" OR
* has an annotation that ends with "Test"
*/
class LikelyJunitTest extends Method {
LikelyJunitTest() {
this.isPublic() and
this.getReturnType().hasName("void") and
this.hasNoParameters() and
(
this.getName().matches("JUnit%") or
this.getName().matches("test%") or
this.getAnAnnotation().getType().getName().matches("%Test")
)
}
}
/**
* Maven surefire patterns to consider which files are testcases:
* https://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html
*/
class SurefireTest extends Class {
SurefireTest() {
this.getFile().getAbsolutePath().matches("%src/test/java%") and
this.getFile()
.getBaseName()
.matches(["Test%.java", "%Test.java", "%Tests.java", "%TestCase.java"])
}
}
/**
* A `Method` from source that is not abstract
* A `Method` from source that is not abstract, and likely not a test method
*/
class NonAbstractSource extends Method {
NonAbstractSource() {

View File

@@ -10,9 +10,4 @@ import java
* c) in a test class whose name has the word `test`
* d) in a test class implementing a test framework such as JUnit or TestNG
*/
predicate isTestMethod(Method m) {
m.getDeclaringType().getName().toLowerCase().matches("%test%") or // Simple check to exclude test classes to reduce FPs
m.getDeclaringType().getPackage().getName().toLowerCase().matches("%test%") or // Simple check to exclude classes in test packages to reduce FPs
exists(m.getLocation().getFile().getAbsolutePath().indexOf("/src/test/java")) or // Match test directory structure of build tools like maven
m instanceof TestMethod // Test method of a test case implementing a test framework such as JUnit or TestNG
}
predicate isTestMethod(LikelyTestMethod m) { any() }