Junit4: Führen Sie nur einen Test einer Klasse mit parametrisiertem Läufer aus

Erstellt am 11. Apr. 2013  ·  35Kommentare  ·  Quelle: junit-team/junit4

Bei Verwendung des parametrisierten Runners gibt es keine Möglichkeit, nur eine Testmethode einer Testklasse auszuführen.

Zum Beispiel bei der Ausführung in Maven: mvn test -Dtest=TesClass#testName

Bei Verwendung des parametrisierten Läufers werden keine Tests ausgeführt.

Das wäre toll, diese Funktion zu haben, denn für die Entwicklung ist es üblich, dass die Entwickler versuchen, nur den Test auszuführen, an dem sie gerade arbeiten.

feature parameterized

Hilfreichster Kommentar

@diogoeag
Haben Sie dieses Kapitel in Surefire gelesen?
http://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html#Multiple_Formats_in_One

Das Filtern von parametrisierten Tests funktioniert seit Version 2.19 . In Ihrem Fall ist es -Dtest=TesClass#testName[*] statt -Dtest=TesClass#testName .

Alle 35 Kommentare

Dies zu beheben wäre großartig, da wir am Ende UTs in großen Testklassen kommentieren müssen, was unerwünscht ist.

Das Maven Surefire Plugin erlaubt die Angabe von Globs (siehe http://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html). Hast du das probiert?

Ja, so würden wir es gerne nutzen, aber es funktioniert nicht. Sagen Sie, dass dies ein Problem des todsicheren Plugins ist und nicht von junit?

@diogoeag Ich glaube, es ist ein Problem mit dem Surefire-Plugin. Sie können dies überprüfen, indem Sie eine Klasse mit einer main-Methode schreiben, die JUnitCore verwendet, um die Tests einer Klasse auszuführen, die @Parameterized und Ihre main-Methode einen Filter anwenden lässt, um einen der Tests auszuwählen

Hallo Kevin,

Schauen Sie sich diese beiden Beispiele an:

Erster Test ohne Parametrierung:

package org;

import org.junit.Test;
import org.junit.internal.requests.FilterRequest;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.manipulation.Filter;

public class NoParameterTest {

    public static void main(String[] args) {
        new JUnitCore().run(FilterRequest.aClass(NoParameterTest.class).filterWith(new Filter() {
            <strong i="8">@Override</strong>
            public boolean shouldRun(Description description) {
                System.out.println("Should run test: classname[" + description.getClassName() + "] method name[" + description.getMethodName() + "]");
                return description != null && description.getMethodName() != null && description.getMethodName().equals("test");
            }

            <strong i="9">@Override</strong>
            public String describe() {
                return null;
            }
        }).getRunner());

    }

    <strong i="10">@Test</strong>
    public void test() {
        System.out.println("Running Test: test");
    }

    <strong i="11">@Test</strong>
    public void test2() {
        System.out.println("Running Test: test2");
    }
}

Ausgang

Should run test: classname[org.NoParameterTest] method name[test]
Should run test: classname[org.NoParameterTest] method name[test2]
Running Test: test

Zweiter Test mit parametriertem:

package org;

import org.junit.Test;
import org.junit.internal.requests.FilterRequest;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.RunWith;
import org.junit.runner.manipulation.Filter;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collection;

@RunWith(Parameterized.class)
public class ParameterTest {

    public static void main(String[] args) {
        new JUnitCore().run(FilterRequest.aClass(ParameterTest.class).filterWith(new Filter() {
            <strong i="18">@Override</strong>
            public boolean shouldRun(Description description) {
                System.out.println("Should run test: classname[" + description.getClassName() + "] method name[" + description.getMethodName() + "]");
                return description != null && description.getMethodName() != null && description.getMethodName().equals("test");
            }

            <strong i="19">@Override</strong>
            public String describe() {
                return null;
            }
        }).getRunner());

    }


    @Parameterized.Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[]{"Paramter 1"}, new Object[]{"Parameter 2"});
    }

    private String localParameter;

    public ParameterTest(String parameter) {

        this.localParameter = parameter;
    }

    <strong i="20">@Test</strong>
    public void test() {
        System.out.println("Running Test: test");
        System.out.println("Parameter: " + localParameter);
    }

    <strong i="21">@Test</strong>
    public void test2() {
        System.out.println("Running Test: test2");
        System.out.println("Parameter: " + localParameter);
    }
}

Ausgang

Should run test: classname[[0]] method name[null]
Should run test: classname[[1]] method name[null]

Die vom Parametrierten an den Filter übergebene Beschreibung ist nicht korrekt, oder?

@diogoeag Danke für das Codebeispiel. Mit welcher JUnit-Version hast du das probiert? Ich denke, wir haben ein verwandtes Problem in 4.12 behoben, aber ich bin mir nicht sicher.

@kcooney , ich habe mit dem aktuellen Master 4.12-SNAPSHOT getestet und auch mit 4.11. Beide haben das gleiche Problem.

Vielen Dank. Um dies zu beheben, wären Änderungen erforderlich, die nicht abwärtskompatibel sind. Meilenstein auf 5.0 setzen

Nur um dies zu verdeutlichen, müsste dies nur zu BlockJUnit4ClassRunnerWithParameters gehen und die Überschreibung der #testName-Methode entfernen. Das ersetzt die Standardeinstellung

    protected String testName(FrameworkMethod method) {
        return method.getName();
    }

von

    <strong i="9">@Override</strong>
    protected String testName(FrameworkMethod method) {
        return method.getName() + getName();
    }

Und die Konsequenz wäre, dass das Reporting der Tests nicht den Parameternamen im testHeader hätte (zumindest waren nur diese Tests fehlgeschlagen)?

@diogoeag, aber möchten wir nicht den Parameternamen in der Beschreibung?

Ich denke, die Korrekturen würden am besten auf dem Beschreibungs-Builder vorgenommen, an dem wir für JUnit 5.0 arbeiten.

@kcooney Ja, um richtig zu sein, sollten wir den Parameternamen in der Beschreibung haben, aber die Beschreibung sollte den

Haben Sie Schätzungen zum Zieldatum bis 5.0?

Ich habe nach der Verwendung von getDisplayName gesucht, um mit dem Fix einen Pull-Request an 5.0 zu senden, es wird jedoch 23-mal im Projekt verwendet (Quellen und Tests) und ich habe nicht die ausreichenden Kenntnisse der JUnit-Quelle, um eine solche Änderung vorzunehmen. In der Zwischenzeit werde ich eine Gabel für meinen persönlichen Gebrauch mit dieser Zwischenlösung für mich machen. Die Parameternamen zu haben ist nicht entscheidend, aber die Möglichkeit, einzelne Tests auszuführen, spart uns viele Stunden bei vielen Entwicklern, die Tests in unserer Quelle ausführen.

Vielen Dank

Wenn jemand Zugriff auf diesen temporären Fix haben muss: https://github.com/feedzai/junit/commit/be41d2980227d86915d9c8b6f800070a0ef1ff7a

@diogoeag
Sieh dir das an. Würde es in todsicheren 2.18 helfen?
https://github.com/apache/maven-surefire/pull/46

@ Tibor17 Ich bin mir nicht sicher. Denn shoudlRun wird die Beschreibung auch verwenden. Ich kenne die Codebasis nicht genug, um zu wissen, ob es funktioniert. Teste es nur. Mein Beispielcode kann auch einer der Tests für Ihren Fix sein. Bei parametrisierten Tests besteht das Problem, den Testnamen zu ändern.

@diogoeag
In todsicherem MethodFilter sollten Sie in der Lage sein, eine Bedingung wie folgt anzugeben:

String filterBy = JunitVersion < 5.0 & <strong i="7">@RunWith</strong> = Parameterized.class ? methodName + className : methodName

Wenn Sie die JUnit-Probleme tolerieren möchten, können Sie Hotfix im Maven Surefire-Projekt selbst festlegen.

@diogoeag Wir haben noch kein Zieldatum für JUnit 5.0, aber es wäre wahrscheinlich die Veröffentlichung nach dem 4.12. Wir konzentrieren uns derzeit darauf, 4.12 aus der Tür zu bekommen

@kcooney danke. Wir werden in der Zwischenzeit unsere interne Version verwenden.

Hallo, was ist mit diesem Problem? Gibt es eine Problemumgehung für die Verwendung von Parameterized.class und die Möglichkeit, einen einzelnen Test mit Maven Surefire auszuführen? Oder müssen wir die 5.0-Version darauf warten?

@Fanch - es gibt keinen aktuellen Fix. Wir dachten, wir würden dies auch bei der ImmutableDescription-Arbeit beheben, an der wir arbeiteten, aber diese Bemühungen wurden aufgegeben.

screen shot 2016-11-16 at 17 42 48

Ich denke, es wäre in Ordnung, getName() aus testName() zu entfernen, weil es sowieso überflüssig ist.

@junit-team/junit-committers Was denkst du?

Solange alle Description Instanzen für einen partameterisierten Test eindeutig sind.

Wir könnten die eindeutige ID in der Beschreibung festlegen, um sie eindeutig zu machen. Ich frage mich jedoch, ob / warum sie im gesamten Unterbaum eindeutig sein müssen?

Ja, Description Instanzen müssen eindeutig sein. Das ist alles, was an den Listener übergeben wird, um auf einen Testbeginn und -ende zu verweisen. Um einen Baum, wie Sie ihn gezeigt haben, zu erstellen und ihn während des Testlaufs zu aktualisieren, müssen Sie wissen, welcher Test gestartet wurde.

Punkt genommen. Ich denke, wir sollten Description eine neue Factory-Methode hinzufügen, die eine Testbeschreibung mit einer eindeutigen eindeutigen ID erstellt. Wir könnten dann den aktuellen Namen als eindeutige ID übergeben und nur den Namen der Methode als Anzeigenamen verwenden. Was denken Sie?

@marcphilipp es gibt bereits eine Methode in Description zum Erstellen einer Testbeschreibung mit einer bestimmten eindeutigen ID: https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/runner/ Beschreibung.java#L109

Ich glaube nicht, dass Description eindeutige IDs _generieren_ sollte. Könnte Parameterized keinen deterministischen Wert an Description.createTestDescription() ?

In Description gibt es bereits eine Methode zum Erstellen einer Testbeschreibung mit einer bestimmten eindeutigen ID: https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/runner/Description. java#L109

Ja, aber dieser hat keinen Klassenparameter. Wir brauchen also einen anderen.

Ich glaube nicht, dass Description eindeutige IDs _generieren_ sollte. Könnte Parameterized keinen deterministischen Wert an Description.createTestDescription() ?

Das meinte ich nicht. Ich meinte, dass Parameterized method.getName() + getName() als eindeutige ID und method.getName() als Namen _pass_ sollte.

SGTM.

Auch wenn wir die Idee, unveränderliche Beschreibungsinstanzen für JUnit 4 zu haben, aufgegeben haben, sollten wir einen Builder hinzufügen, um so viele statische Erstellungsmethoden zu vermeiden?

Sicher! 👍

Gibt es Schätzungen wann es behoben wird?
Dieser Fehler blockiert einen verwandten Fehler von JUnit5
https://github.com/junit-team/junit5/issues/549

@SqAutoTestTeam daran arbeitet niemand aktiv. Ich habe den Beschreibungs-Builder-Zweig kürzlich aktualisiert, damit ein ehrgeiziger Mitwirkender von dort aus beginnen kann. Alternativ könnten wir Description weitere statische Methode hinzufügen.

Um dies zu beheben, wären neue APIs in der Beschreibung erforderlich. Wir möchten nicht, dass JUnit 5 diese neuen APIs benötigt (derzeit würde JUnit 5 auf fast jeder Version von JUnit 4.x funktionieren).

@diogoeag
Haben Sie dieses Kapitel in Surefire gelesen?
http://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html#Multiple_Formats_in_One

Das Filtern von parametrisierten Tests funktioniert seit Version 2.19 . In Ihrem Fall ist es -Dtest=TesClass#testName[*] statt -Dtest=TesClass#testName .

@kcooney und @marcphilipp ,

Was halten Sie davon, den _fix_ in https://github.com/junit-team/junit5/pull/1018/files#diff -42ed8b618527eb1521dbe3cd9100e949R48 auf JUnit 4 "zurückzuportieren"?

@sbrannen das sieht nach einer vernünftigen Änderung aus. Ich möchte nur sicherstellen, dass wir, wenn wir diese Änderungen zurückportieren, JUnit 4.13 nicht mit JUnit 5 inkompatibel machen oder Projekte mit JUnit 4-Stil-Tests auf 4.13 aktualisieren müssen, bevor sie ihre JUnit 4-Stil-Tests mit dem ausführen können JUnit 5-Runner-APIs.

@kcooney ,

das sieht nach einer vernünftigen änderung aus.

👍

Ich möchte nur sicherstellen, dass wir, wenn wir diese Änderungen zurückportieren, JUnit 4.13 nicht mit JUnit 5 inkompatibel machen oder Projekte mit JUnit 4-Stil-Tests auf 4.13 aktualisieren müssen, bevor sie ihre JUnit 4-Stil-Tests mit dem ausführen können JUnit 5-Runner-APIs.

In JUnit 4 würde die Änderung nur auf eine einzige Zeile in Filter#matchMethodDescription(Description) , und wir können den gleichen _fix_ in JUnit Vintage beibehalten wie jetzt, so dass VintageTestEngine weiterhin mit JUnit 4.12 funktionieren würde .

Also, es sei denn, ich übersehe etwas, das sollte Kompatibilitätsprobleme vermeiden.

Was denken Sie?

@sbrannen SGTM

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen