JUnit Platform Engine API - Core engine API for implementing custom test engines in the JUnit Platform ecosystem
—
Comprehensive test discovery system that enables test engines to find tests using selectors and refine results with filters. The discovery system supports various test sources including classes, methods, packages, files, and URIs.
Provides test engines with discovery configuration including selectors, filters, and configuration parameters.
/**
* Discovery request providing selectors, filters, and configuration for test discovery.
*/
public interface EngineDiscoveryRequest {
/**
* Get all discovery selectors of the specified type.
* @param selectorType the type of selectors to retrieve
* @return list of selectors of the specified type
*/
<T extends DiscoverySelector> List<T> getSelectorsByType(Class<T> selectorType);
/**
* Get all discovery filters of the specified type.
* @param filterType the type of filters to retrieve
* @return list of filters of the specified type
*/
<T extends DiscoveryFilter<?>> List<T> getFiltersByType(Class<T> filterType);
/**
* Get configuration parameters for the discovery request.
* @return configuration parameters
*/
ConfigurationParameters getConfigurationParameters();
/**
* Get the discovery listener for reporting discovery events.
* @return discovery listener
*/
EngineDiscoveryListener getDiscoveryListener();
/**
* Get the output directory provider.
* @return output directory provider
*/
OutputDirectoryProvider getOutputDirectoryProvider();
}Factory class providing static methods for creating various types of discovery selectors.
/**
* Factory for creating discovery selectors of various types.
*/
public final class DiscoverySelectors {
// URI-based selectors
public static UriSelector selectUri(URI uri);
public static UriSelector selectUri(String uri);
// File-based selectors
public static FileSelector selectFile(String path);
public static FileSelector selectFile(File file);
public static FileSelector selectFile(String path, FilePosition position);
public static FileSelector selectFile(File file, FilePosition position);
// Directory selectors
public static DirectorySelector selectDirectory(String path);
public static DirectorySelector selectDirectory(File directory);
// Classpath selectors
public static List<ClasspathRootSelector> selectClasspathRoots(Set<Path> classpathRoots);
public static ClasspathResourceSelector selectClasspathResource(String classpathResourceName);
public static ClasspathResourceSelector selectClasspathResource(String classpathResourceName, FilePosition position);
public static ClasspathResourceSelector selectClasspathResource(Set<Resource> classpathResources);
// Module selectors
public static ModuleSelector selectModule(String moduleName);
public static List<ModuleSelector> selectModules(Set<String> moduleNames);
// Package selectors
public static PackageSelector selectPackage(String packageName);
// Class selectors
public static ClassSelector selectClass(Class<?> clazz);
public static ClassSelector selectClass(String className);
public static ClassSelector selectClass(ClassLoader classLoader, String className);
// Method selectors
public static MethodSelector selectMethod(Class<?> javaClass, Method method);
public static MethodSelector selectMethod(Class<?> javaClass, String methodName);
public static MethodSelector selectMethod(Class<?> javaClass, String methodName, String parameterTypeNames);
public static MethodSelector selectMethod(Class<?> javaClass, String methodName, Class<?>... parameterTypes);
public static MethodSelector selectMethod(String className, String methodName);
public static MethodSelector selectMethod(String className, String methodName, String parameterTypeNames);
public static MethodSelector selectMethod(String className, String methodName, Class<?>... parameterTypes);
public static MethodSelector selectMethod(String fullyQualifiedMethodName);
public static MethodSelector selectMethod(ClassLoader classLoader, String fullyQualifiedMethodName);
public static MethodSelector selectMethod(ClassLoader classLoader, String className, String methodName);
public static MethodSelector selectMethod(ClassLoader classLoader, String className, String methodName, String parameterTypeNames);
// Nested class selectors
public static NestedClassSelector selectNestedClass(List<Class<?>> enclosingClasses, Class<?> nestedClass);
public static NestedClassSelector selectNestedClass(List<String> enclosingClassNames, String nestedClassName);
public static NestedClassSelector selectNestedClass(ClassLoader classLoader, List<String> enclosingClassNames, String nestedClassName);
// Nested method selectors
public static NestedMethodSelector selectNestedMethod(List<Class<?>> enclosingClasses, Class<?> nestedClass, Method method);
public static NestedMethodSelector selectNestedMethod(List<Class<?>> enclosingClasses, Class<?> nestedClass, String methodName);
public static NestedMethodSelector selectNestedMethod(List<Class<?>> enclosingClasses, Class<?> nestedClass, String methodName, String parameterTypeNames);
public static NestedMethodSelector selectNestedMethod(List<Class<?>> enclosingClasses, Class<?> nestedClass, String methodName, Class<?>... parameterTypes);
public static NestedMethodSelector selectNestedMethod(List<String> enclosingClassNames, String nestedClassName, String methodName);
public static NestedMethodSelector selectNestedMethod(List<String> enclosingClassNames, String nestedClassName, String methodName, String parameterTypeNames);
public static NestedMethodSelector selectNestedMethod(List<String> enclosingClassNames, String nestedClassName, String methodName, Class<?>... parameterTypes);
public static NestedMethodSelector selectNestedMethod(ClassLoader classLoader, List<String> enclosingClassNames, String nestedClassName, String methodName);
public static NestedMethodSelector selectNestedMethod(ClassLoader classLoader, List<String> enclosingClassNames, String nestedClassName, String methodName, String parameterTypeNames);
// Unique ID selectors
public static UniqueIdSelector selectUniqueId(UniqueId uniqueId);
public static UniqueIdSelector selectUniqueId(String uniqueId);
// Iteration selectors (for parameterized tests)
public static IterationSelector selectIteration(DiscoverySelector parentSelector, int... iterationIndices);
// Parsing methods
public static Optional<? extends DiscoverySelector> parse(String identifier);
public static Optional<? extends DiscoverySelector> parse(DiscoverySelectorIdentifier identifier);
public static Stream<? extends DiscoverySelector> parseAll(String... identifiers);
public static Stream<? extends DiscoverySelector> parseAll(Collection<DiscoverySelectorIdentifier> identifiers);
}Usage Example:
import org.junit.platform.engine.discovery.*;
// Discover all tests in specific classes
List<ClassSelector> classSelectors = Arrays.asList(
DiscoverySelectors.selectClass(MyTestClass.class),
DiscoverySelectors.selectClass("com.example.AnotherTestClass")
);
// Discover specific test methods
MethodSelector methodSelector = DiscoverySelectors.selectMethod(
MyTestClass.class, "testSomething"
);
// Discover tests in packages
PackageSelector packageSelector = DiscoverySelectors.selectPackage("com.example.tests");
// Process selectors in engine
@Override
public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
EngineDescriptor engineDescriptor = new EngineDescriptor(uniqueId, "My Engine");
// Process class selectors
for (ClassSelector selector : discoveryRequest.getSelectorsByType(ClassSelector.class)) {
Class<?> testClass = selector.getJavaClass();
// Create descriptors for discovered tests
}
// Process method selectors
for (MethodSelector selector : discoveryRequest.getSelectorsByType(MethodSelector.class)) {
Method testMethod = selector.getJavaMethod();
// Create descriptors for specific methods
}
return engineDescriptor;
}Filters for refining discovery results by including or excluding tests based on class names, package names, and other criteria.
/**
* Base interface for discovery filters.
* @param T the type being filtered
*/
public interface DiscoveryFilter<T> extends Filter<T> {
// Inherits apply method from Filter interface
}
/**
* Abstract base class for class name filters.
*/
public abstract class ClassNameFilter implements DiscoveryFilter<Class<?>> {
protected ClassNameFilter(String pattern);
protected ClassNameFilter(String... patterns);
protected ClassNameFilter(List<String> patterns);
}
/**
* Include filter for class names using regex patterns.
*/
public class IncludeClassNameFilter extends ClassNameFilter {
public IncludeClassNameFilter(String pattern);
public IncludeClassNameFilter(String... patterns);
public IncludeClassNameFilter(List<String> patterns);
}
/**
* Exclude filter for class names using regex patterns.
*/
public class ExcludeClassNameFilter extends ClassNameFilter {
public ExcludeClassNameFilter(String pattern);
public ExcludeClassNameFilter(String... patterns);
public ExcludeClassNameFilter(List<String> patterns);
}
/**
* Abstract base class for package name filters.
*/
public abstract class PackageNameFilter implements DiscoveryFilter<String> {
protected PackageNameFilter(String pattern);
protected PackageNameFilter(String... patterns);
protected PackageNameFilter(List<String> patterns);
}
/**
* Include filter for package names using regex patterns.
*/
public class IncludePackageNameFilter extends PackageNameFilter {
public IncludePackageNameFilter(String pattern);
public IncludePackageNameFilter(String... patterns);
public IncludePackageNameFilter(List<String> patterns);
}
/**
* Exclude filter for package names using regex patterns.
*/
public class ExcludePackageNameFilter extends PackageNameFilter {
public ExcludePackageNameFilter(String pattern);
public ExcludePackageNameFilter(String... patterns);
public ExcludePackageNameFilter(List<String> patterns);
}Specific selector implementations for different types of test sources.
/**
* Selector for class-based test discovery.
*/
public class ClassSelector implements DiscoverySelector {
public Class<?> getJavaClass();
public String getClassName();
public ClassLoader getClassLoader();
}
/**
* Selector for method-based test discovery.
*/
public class MethodSelector implements DiscoverySelector {
public Class<?> getJavaClass();
public Method getJavaMethod();
public String getClassName();
public String getMethodName();
public String getMethodParameterTypes();
public ClassLoader getClassLoader();
}
/**
* Selector for package-based test discovery.
*/
public class PackageSelector implements DiscoverySelector {
public String getPackageName();
}
/**
* Selector for URI-based test discovery.
*/
public class UriSelector implements DiscoverySelector {
public URI getUri();
}
/**
* Selector for file-based test discovery.
*/
public class FileSelector implements DiscoverySelector {
public Path getPath();
public File getFile();
public Optional<FilePosition> getPosition();
}
/**
* Selector for directory-based test discovery.
*/
public class DirectorySelector implements DiscoverySelector {
public Path getPath();
public File getDirectory();
}
/**
* Selector for unique ID-based test discovery.
*/
public class UniqueIdSelector implements DiscoverySelector {
public UniqueId getUniqueId();
}Represents positions within files for precise test location.
/**
* Position within a file (line and column numbers).
*/
public class FilePosition {
/**
* Create a file position from line number.
* @param line the line number (1-based)
* @return FilePosition instance
*/
public static FilePosition from(int line);
/**
* Create a file position from line and column numbers.
* @param line the line number (1-based)
* @param column the column number (1-based)
* @return FilePosition instance
*/
public static FilePosition from(int line, int column);
/**
* Get the line number.
* @return line number (1-based)
*/
public int getLine();
/**
* Get the column number.
* @return optional column number (1-based)
*/
public Optional<Integer> getColumn();
}Interface for receiving discovery events and issues during the discovery process.
/**
* Listener for discovery events.
*/
public interface EngineDiscoveryListener {
/**
* Called when a selector is skipped during discovery.
* @param selector the skipped selector
* @param reason the reason for skipping
*/
void selectorProcessed(DiscoverySelector selector);
/**
* Called when an issue is encountered during discovery.
* @param issue the discovery issue
*/
void discoveryIssue(DiscoveryIssue issue);
}
/**
* Represents an issue encountered during discovery.
*/
public interface DiscoveryIssue {
/**
* Get the issue message.
* @return the issue message
*/
String getMessage();
/**
* Get the associated throwable.
* @return optional throwable
*/
Optional<Throwable> getThrowable();
}Install with Tessl CLI
npx tessl i tessl/maven-org-junit-platform--junit-platform-engine