or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/maven-org-junit-vintage--junit-vintage-engine

JUnit Vintage Engine provides a TestEngine for running JUnit 3 and 4 based tests on the JUnit Platform.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.junit.vintage/junit-vintage-engine@5.12.x

To install, run

npx @tessl/cli install tessl/maven-org-junit-vintage--junit-vintage-engine@5.12.0

index.mddocs/

JUnit Vintage Engine

JUnit Vintage Engine provides a TestEngine for running JUnit 3 and 4 based tests on the JUnit Platform. This engine allows existing JUnit 3 and 4 tests to be executed in the modern JUnit 5 ecosystem without modification, providing backward compatibility and migration support for legacy test suites.

Package Information

  • Package Name: junit-vintage-engine
  • Package Type: Maven
  • Group ID: org.junit.vintage
  • Artifact ID: junit-vintage-engine
  • Language: Java
  • Installation: Add to Maven dependencies:
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.12.2</version>
    <scope>test</scope>
</dependency>

For Gradle:

testImplementation 'org.junit.vintage:junit-vintage-engine:5.12.2'

Core Imports

import org.junit.vintage.engine.VintageTestEngine;
import org.junit.vintage.engine.Constants;
import org.apiguardian.api.API;

Basic Usage

The JUnit Vintage Engine is automatically discovered by the JUnit Platform when present on the classpath. No explicit configuration is required for basic usage.

// JUnit 4 test example - will be executed by Vintage Engine
import org.junit.Test;
import static org.junit.Assert.*;

public class LegacyJUnit4Test {
    @Test
    public void testSomething() {
        assertEquals("Expected behavior", "actual", "expected");
    }
}

Configuration via system properties:

// Enable parallel execution
System.setProperty(Constants.PARALLEL_EXECUTION_ENABLED, "true");
System.setProperty(Constants.PARALLEL_CLASS_EXECUTION, "true");
System.setProperty(Constants.PARALLEL_POOL_SIZE, "4");

Architecture

The JUnit Vintage Engine operates as a bridge component within the JUnit Platform ecosystem:

  • Service Discovery: Registered via Java Service Loader as a TestEngine implementation
  • Test Discovery: Discovers JUnit 3 and 4 tests using legacy discovery mechanisms
  • Test Execution: Executes legacy tests through JUnit 4's Runner API
  • Platform Integration: Translates JUnit 3/4 execution events to JUnit Platform events
  • Parallel Execution: Optional parallel execution capabilities for improved performance

Capabilities

TestEngine Implementation

Core TestEngine interface implementation that integrates with the JUnit Platform. This class is internal and automatically managed by the JUnit Platform via Service Loader discovery.

@API(status = INTERNAL, since = "4.12")
public final class VintageTestEngine implements TestEngine {
    public String getId(); // Returns "junit-vintage"
    public Optional<String> getGroupId(); // Returns "org.junit.vintage"
    public Optional<String> getArtifactId(); // Returns "junit-vintage-engine"
    public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId);
    public void execute(ExecutionRequest request);
}

Configuration Constants

Configuration properties for controlling engine behavior, particularly parallel execution.

@API(status = STABLE, since = "5.12")
public final class Constants {
    // Parallel execution configuration (EXPERIMENTAL features)
    @API(status = EXPERIMENTAL, since = "5.12")
    public static final String PARALLEL_EXECUTION_ENABLED = "junit.vintage.execution.parallel.enabled";
    
    @API(status = EXPERIMENTAL, since = "5.12")
    public static final String PARALLEL_POOL_SIZE = "junit.vintage.execution.parallel.pool-size";
    
    @API(status = EXPERIMENTAL, since = "5.12")
    public static final String PARALLEL_CLASS_EXECUTION = "junit.vintage.execution.parallel.classes";
    
    @API(status = EXPERIMENTAL, since = "5.12")
    public static final String PARALLEL_METHOD_EXECUTION = "junit.vintage.execution.parallel.methods";
}

Engine Registration

The VintageTestEngine is automatically registered through the Java Service Loader mechanism:

Service Configuration: META-INF/services/org.junit.platform.engine.TestEngine Implementation: org.junit.vintage.engine.VintageTestEngine

Usage Examples

Configuration Examples

Enable parallel execution for improved performance:

// Set system properties programmatically
System.setProperty(Constants.PARALLEL_EXECUTION_ENABLED, "true");
System.setProperty(Constants.PARALLEL_CLASS_EXECUTION, "true");
System.setProperty(Constants.PARALLEL_METHOD_EXECUTION, "false");
System.setProperty(Constants.PARALLEL_POOL_SIZE, "8");

Via JVM arguments:

-Djunit.vintage.execution.parallel.enabled=true
-Djunit.vintage.execution.parallel.classes=true
-Djunit.vintage.execution.parallel.pool-size=4

Legacy Test Compatibility

The engine supports all standard JUnit 3 and 4 features:

// JUnit 3 style test
import junit.framework.TestCase;

public class LegacyJUnit3Test extends TestCase {
    public void testOldStyle() {
        assertEquals("JUnit 3 works", 2, 1 + 1);
    }
}

// JUnit 4 with annotations and rules
import org.junit.Test;
import org.junit.Rule;
import org.junit.rules.ExpectedException;

public class LegacyJUnit4Test {
    @Rule
    public ExpectedException thrown = ExpectedException.none();
    
    @Test
    public void testWithRule() {
        thrown.expect(IllegalArgumentException.class);
        throw new IllegalArgumentException("Expected");
    }
}

Engine Information Access

The engine provides identification information through the TestEngine interface (note: direct instantiation is not recommended as the engine is managed by the platform):

// Engine identification (accessible via TestEngine interface)
String engineId = "junit-vintage";
Optional<String> groupId = Optional.of("org.junit.vintage");
Optional<String> artifactId = Optional.of("junit-vintage-engine");

// Engine discovery and execution are automatically handled by JUnit Platform
// through Service Loader mechanism when vintage engine is on the classpath

Integration Requirements

Required Dependencies

Minimum JUnit 4 Version: The Vintage Engine requires JUnit 4.12 or later. Version compatibility is automatically checked at runtime.

<!-- JUnit 4 for legacy test execution (minimum 4.12) -->
<dependency>
    <groupId>junit</groupId>  
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
</dependency>

<!-- JUnit Platform Engine for integration -->
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-engine</artifactId>
    <version>1.12.2</version>
</dependency>

Module System Support

For Java 9+ module system:

module my.test.module {
    requires org.junit.vintage.engine;
    requires junit; // JUnit 4
    requires org.junit.platform.engine;
}

Error Handling

The engine handles various error scenarios gracefully:

  • Missing JUnit 4: Throws JUnitException with clear error message suggesting to remove vintage engine or add junit:junit dependency
  • Incompatible JUnit 4 Version: Throws JUnitException if JUnit version is below 4.12
  • Invalid Tests: Properly reports discovery and execution failures through platform events
  • Platform Integration: Translates legacy JUnit 3/4 exceptions to JUnit Platform events
  • Version Compatibility: Automatic runtime validation using junit.runner.Version.id()

Migration Support

The Vintage Engine facilitates gradual migration from JUnit 4 to JUnit 5:

  1. Phase 1: Add JUnit Platform + Vintage Engine, run existing JUnit 4 tests
  2. Phase 2: Gradually migrate tests to JUnit 5 (Jupiter) annotations
  3. Phase 3: Remove Vintage Engine dependency when migration complete

This enables incremental adoption without requiring wholesale test rewrites.

Types

// Core API status annotations (from org.apiguardian.api)
@interface API {
    Status status() default Status.INTERNAL;
    String since() default "";
    
    enum Status {
        INTERNAL, DEPRECATED, EXPERIMENTAL, MAINTAINED, STABLE
    }
}

// Core JUnit Platform interfaces used by the engine
interface TestEngine {
    String getId();
    Optional<String> getGroupId(); 
    Optional<String> getArtifactId();
    TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId);
    void execute(ExecutionRequest request);
}

interface EngineDiscoveryRequest {
    // Discovery request configuration containing selectors and filters
}

interface ExecutionRequest {
    TestDescriptor getRootTestDescriptor();
    EngineExecutionListener getEngineExecutionListener();
}

interface TestDescriptor {
    UniqueId getUniqueId();
    String getDisplayName();
    Set<TestTag> getTags();
    Optional<TestSource> getSource();
    // Methods for test hierarchy management
}

// Exception thrown for JUnit-related failures
class JUnitException extends RuntimeException {
    public JUnitException(String message);
    public JUnitException(String message, Throwable cause);
}