Benutzerdefinierte JUnit 4-Testläufer

Benutzerdefinierte JUnit 4-Testläufer

1. Überblick

In diesem kurzen Artikel konzentrieren wir uns darauf, wie JUnit-Tests mit benutzerdefinierten Testläufern ausgeführt werden.

Einfach ausgedrückt, um den benutzerdefinierten Läufer anzugeben, müssen wir die Annotation@RunWithverwenden.

2. Vorbereitung

Beginnen wir mit dem Hinzufügen der Standardabhängigkeit vonJUnitzu unserenpom.xml:


  junit
  junit
  4.12

3. Implementieren eines benutzerdefinierten Läufers

Im folgenden Beispiel zeigen wir, wie Sie unsere eigenen benutzerdefiniertenRunner schreiben und mit @RunWith ausführen.

A JUnit Runner is a class that extends JUnit’s abstract Runner class and it is responsible for running JUnit tests, typischerweise unter Verwendung von Reflexion.

Hier implementieren wir abstrakte Methoden der KlasseRunner:

public class TestRunner extends Runner {

    private Class testClass;
    public TestRunner(Class testClass) {
        super();
        this.testClass = testClass;
    }

    @Override
    public Description getDescription() {
        return Description
          .createTestDescription(testClass, "My runner description");
    }

    @Override
    public void run(RunNotifier notifier) {
        System.out.println("running the tests from MyRunner: " + testClass);
        try {
            Object testObject = testClass.newInstance();
            for (Method method : testClass.getMethods()) {
                if (method.isAnnotationPresent(Test.class)) {
                    notifier.fireTestStarted(Description
                      .createTestDescription(testClass, method.getName()));
                    method.invoke(testObject);
                    notifier.fireTestFinished(Description
                      .createTestDescription(testClass, method.getName()));
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Die MethodegetDescription wird vonDescribable geerbt und gibtDescription zurück, die die Informationen enthält, die später exportiert werden und von verschiedenen Tools verwendet werden können.

In der Implementierung vonrunrufen wir die Zieltestmethoden mithilfe von Reflektion auf.

Wir haben einen Konstruktor definiert, der das ArgumentClassverwendet. Dies ist eine Anforderung von JUnit. Zur Laufzeit übergibt JUnit die Zieltestklasse an diesen Konstruktor.

RunNotifier wird zum Auslösen von Ereignissen verwendet, die Informationen zum Testfortschritt enthalten.

Verwenden wir den Läufer in unserer Testklasse:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

@RunWith(TestRunner.class)
public class CalculatorTest {
    Calculator calculator = new Calculator();

    @Test
    public void testAddition() {
        Syste.out.println("in testAddition");
        assertEquals("addition", 8, calculator.add(5, 3));
    }
}

Das Ergebnis erhalten wir:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.junit.CalculatorTest
running the tests from MyRunner: class com.example.junit.CalculatorTest
in testAddition
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

4. Spezialisierte Läufer

Anstatt die KlasseRunnerauf niedriger Ebene zu erweitern, wie wir es im letzten Beispiel getan haben,we can extend one of the specialized subclasses of Runner: ParentRunner or BlockJUnit4Runner.

Die abstrakteParentRunner-Klasse führt die Tests hierarchisch aus.

BlockJUnit4Runner ist eine konkrete Klasse. Wenn wir bestimmte Methoden anpassen möchten, werden wir diese Klasse wahrscheinlich erweitern.

Sehen wir uns das anhand eines Beispiels an:

public class BlockingTestRunner extends BlockJUnit4ClassRunner {
    public BlockingTestRunner(Class klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected Statement methodInvoker(FrameworkMethod method, Object test) {
        System.out.println("invoking: " + method.getName());
        return super.methodInvoker(method, test);
    }
}

Wenn Sie eine Klasse mit@RunWith(JUnit4.class) versehen, wird immer der Standard-JUnit 4-Runner in der aktuellen Version von JUnit aufgerufen. Diese Klasse aliasiert den aktuellen Standard-JUnit 4-Klassenläufer:

@RunWith(JUnit4.class)
public class CalculatorTest {
    Calculator calculator = new Calculator();

    @Test
    public void testAddition() {
        assertEquals("addition", 8, calculator.add(5, 3));
    }
}

5. Fazit

JUnit Runners sind äußerst anpassungsfähig und ermöglichen es dem Entwickler, das Testausführungsverfahren und den gesamten Testprozess zu ändern.

Wenn wir nur geringfügige Änderungen vornehmen möchten, ist es eine gute Idee, sich die geschützten Methoden vonBlockJUnit4Class Runner anzusehen.

Einige beliebte Implementierungen von Läufern zur Verwendung durch Drittanbieter umfassenSpringJUnit4ClassRunner, MockitoJUnitRunner, HierarchicalContextRunner,Cucumber Runner und vieles mehr.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie inGitHub project - dies ist ein Maven-Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.