Parallelisierte Tests mit jeweils zwei Gruppen in TestNG

29. Oktober 2014 Softwaretest von Eric Kubenka

In meinem Job automatisiere ich funktionale Oberflächentests mit Java. Die Testfälle führe ich mittels des TestNG-Frameworks und Selenium aus. Jeder Testfall ist mittels @Annotation mindestens einer Testgruppe zugeordnet. Die Testfälle werden parallel mit unterschiedlichen Anwendern ausgeführt, da ein Anwender sich zeitgleich nur ein mal am System anmelden kann.

Parallelisiertes Ausführen von Tests mit jeweils zwei Gruppen

Bei der Ausführung eines parallelisierten Smoketest-Sets bin ich dann jedoch ins Stolpern geraten. Ziel ist es Testfälle auszuführen, welcher der Gruppe Group User A und der Gruppe Smoketest zugeordnet sind. Parallel dazu in einem anderen Thread sollen die Testfälle ausgeführt werden, welche der Gruppe Group User B und der Gruppe Smoketest zugeordnet sind. Leider lässt sich das nicht so einfach in der suite.xml definieren, sondern ein eigener Listener muss geschrieben werden.

Lang habe ich versucht es ausschließlich über die suite.xml-Datei zu regeln, jedoch wurden bei mir die Tests dann nie so ausgeführt wie ich es mir vorgestellt habe. Leider war ich mit den erweiteren TestNG-Funktionen nicht so vertraut, weshalb ich einige Recherchezeit benötigte.

Die Suite.xml

Zuerst möchte ich Euch zeigen, wie genau ich meine Test-Suite definiert habe. Der erste test-Block soll die Tests ausführen welche der Gruppe Smoketest und zusätzlich der Gruppe Group User A zugeordnet sind. Der zweite Block ist das Äquivalent dazu mit Anwender B.

Der wichtige Punkt ist in dieser Suite-Definition das Einbinden des listeners-Blocks. Hier können zusätzliche Funktionen programmatisch abgefangen werden. ICh selbst rufe hier den eigens geschriebenen TestGroupInterceptorListener auf.

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Smoketest - Parallel Tests" verbose="10" configfailurepolicy="continue" parallel="tests" thread-count="2">

	<listeners>
         <listener class-name="de.codefever.testautomation.test.utils.TestGroupInterceptorListener"/>
    </listeners>

    <test name="Tests run with group Group User A">
        <groups>
            <run>
                <include name="Group User A"/>
            </run>
        </groups>
        <packages>
            <package name="de.codefever.tests.DE.administration"/>
            <package name="de.codefever.tests.DE.kontakt"/>
            <package name="de.codefever.tests.DE.post"/>
        </packages>
    </test>
	
	<test name="Tests run with group Group User B">
        <groups>
            <run>
                <include name="Group User B"/>
            </run>
        </groups>
        <packages>
            <package name="de.codefever.tests.DE.administration"/>
            <package name="de.codefever.tests.DE.kontakt"/>
            <package name="de.codefever.tests.DE.post"/>
        </packages>
    </test>
</suite>

Der Listener Code

Folgender Listener überschreibt, beziehungsweise implementiert die intercept-Methode des Interfaces IMethodInterceptor. Für jede gefundene Test-Methode mit der Gruppe Group User A oder Group User B wird geprüft ob diese Methoden zusätzlich noch der Gruppe Smoketest angehören. Wenn dies der Fall ist, so wird die gefunde Methode in das Testset aufgenommen.

public class TestGroupInterceptorListener implements IMethodInterceptor {

    @Override
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {

        // Result List
        List<IMethodInstance> result = new ArrayList<IMethodInstance>();

        // For each  test method that matches teh suite definition, run these
        for (IMethodInstance instance : methods) {
            List<String> grps = Arrays.asList(instance.getMethod().getConstructorOrMethod().getMethod()
                    .getAnnotation(Test.class).groups());

            // Check if the test has the Group "Smoketest"
            if (grps.contains("Smoketest")) {
                result.add(instance);
            }
        }
        return result;
    }
}

Zurück