Testng: Los métodos de prueba heredados no obtienen el comportamiento de grupo esperado

Creado en 1 mar. 2012  ·  8Comentarios  ·  Fuente: cbeust/testng

Considere las siguientes clases de prueba:

<strong i="6">@Test</strong>
public abstract class ParentTest {
    public void parentTestMethod() {
    }
}

@Test(groups = "myGroup")
public class ChildTest extends ParentTest {
    public void childTestMethod() {
    }
}

Al ejecutar esta prueba (ChildTest), esperaría que ambos métodos de prueba (childTestMethod y parentTestMethod) pertenezcan al grupo 'myGroup'. Aparentemente, este no es el comportamiento real (probado con la versión 6.4).

Reuní un código para investigar este problema:

TestNGMethodFinder testNGMethodFinder = new TestNGMethodFinder(new RunInfo(), new JDK15AnnotationFinder(new DefaultAnnotationTransformer()));
ITestNGMethod[] testMethods = testNGMethodFinder.getTestMethods(ChildTest.class, new XmlTest());
for (ITestNGMethod testMethod : testMethods) {
    String[] groups = testMethod.getGroups();
    System.out.println(testMethod + " groups:" + Arrays.toString(groups));
}

Resultado de ejecutar este código:

ChildTest.childTestMethod()[pri:0, instance:null] groups:[myGroup]
ParentTest.parentTestMethod()[pri:0, instance:null] groups:[]

Miré el código fuente de TestNG y parece que este comportamiento se origina en el método org.testng.internal.BaseTestMethod # initGroups (Class>). Para ser exactos, creo que la siguiente declaración es la causa de este comportamiento bastante extraño:

ITestOrConfiguration classAnnotation = (ITestOrConfiguration) getAnnotationFinder().findAnnotation(getMethod().getDeclaringClass(), annotationClass);

Para solucionar este problema, esta declaración podría modificarse para:

ITestOrConfiguration classAnnotation = (ITestOrConfiguration) getAnnotationFinder().findAnnotation(getInstance().getClass(), annotationClass);

pero no estoy seguro de si esta sería la forma correcta de resolver el problema. Ni implicaciones eventuales ...

groups inheritance

Todos 8 comentarios

Veo el problema y, lamentablemente, tu sugerencia no funciona del todo. Es un poco complicado de resolver porque las anotaciones se resuelven en la fase de inicio, lo que significa que cuando se analiza la anotación @Test del padre, obviamente no sabe nada sobre el hecho de que la anotación del hijo le agregará más grupos ...

Cedric, gracias por tus prontos comentarios sobre este tema. Dices "es un poco complicado de resolver", ¿significa eso que no crees que este problema tendrá posibilidades de resolverse en un futuro próximo? ¿Puedes pensar en posibles soluciones?

Lo que quise decir fue: cuando se realiza la resolución del grupo, aún no se ha creado una instancia de la clase de prueba, por lo que cuando miro parentTestMethod (), no tengo una instancia de ChildTest que me permita poner ese método en este grupo.

La resolución de grupo es puramente estática, mientras que el ejemplo anterior solo se puede resolver de forma dinámica.

¿Esto tiene sentido?

También he visto este comportamiento. Cuando ejecuto mis pruebas sin un filtro de grupos, todo pasa, pero cuando ejecuto con grupos, las cosas fallan. En algunos casos, se debe a que mi clase de prueba hereda de alguna otra clase de prueba, pero en otros casos tengo clases de prueba POJO y parece que mis métodos @BeforeMethod y @AfterMethod no se invocan correctamente.

Por cierto, mi solución es utilizar grupos excluidos que, por supuesto, no funcionarán en todas las situaciones. @cbeust , ¿se ha trabajado en una solución adecuada para esto?

Más de un año después y esto todavía no funciona.
@cbeust En mi

FWIW, acabo de encontrarme con esto también.

Creé un selector de método personalizado, que usa los grupos de la subclase Test annoation

/* *****************************************************************************
 * Copyright 2017 VMware, Inc.  All rights reserved. VMware Confidential
 * ****************************************************************************/
package com.vmware.cloud.systemtests.util;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.testng.IMethodSelector;
import org.testng.IMethodSelectorContext;
import org.testng.ITestNGMethod;
import org.testng.annotations.Test;
import org.testng.xml.XmlTest;

/**
 * Selector that uses groups in subclass <strong i="6">@Test</strong> annotations to determine if methods should be included
 */
public class SubclassAwareXmlMethodsSelector implements IMethodSelector {
    <strong i="7">@Override</strong>
    public boolean includeMethod(IMethodSelectorContext context, ITestNGMethod method, boolean isTestMethod) {
        XmlTest xmlTest = method.getXmlTest();
        if (xmlTest == null) {
            return method.isAlwaysRun();
        }
        Class realTestClass = isTestMethod ? method.getTestClass().getRealClass() : method.getRealClass();
        Test testClassAnnotation = (Test) realTestClass.getAnnotation(Test.class);
        String[] classAnnotationGroups = testClassAnnotation != null ? testClassAnnotation.groups() : new String[0];
        List<String> groups = Arrays.asList(ArrayUtils.addAll(classAnnotationGroups, method.getGroups()));

        context.setStopped(true);
        if (groups.size() == 0 && xmlTest.getIncludedGroups().isEmpty()) {
            return true;
        } else if (groups.size() > 0 && xmlTest.getExcludedGroups().stream().anyMatch(groups::contains)) {
            return false;
        } else if (groups.size() > 0 && xmlTest.getIncludedGroups().stream().anyMatch(groups::contains)) {
            return true;
        } else {
            return method.isAlwaysRun();
        }
    }

    <strong i="8">@Override</strong>
    public void setTestMethods(List<ITestNGMethod> list) {
    }
}
¿Fue útil esta página
0 / 5 - 0 calificaciones