Testng: Os métodos de teste herdados não obtêm o comportamento de grupo esperado

Criado em 1 mar. 2012  ·  8Comentários  ·  Fonte: cbeust/testng

Considere as seguintes classes de teste:

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

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

Ao executar este teste (ChildTest), eu esperaria que ambos os métodos de teste (childTestMethod e parentTestMethod) pertencessem ao grupo 'myGroup'. Aparentemente, este não é o comportamento real (testado com a versão 6.4).

Eu reuni alguns códigos para investigar esse 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 da execução deste código:

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

Eu olhei no código-fonte do TestNG e parece que esse comportamento se origina do método org.testng.internal.BaseTestMethod # initGroups (Class>). Para ser exato, acho que a seguinte declaração é a causa desse comportamento bastante estranho:

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

Para corrigir esse problema, esta declaração pode ser modificada para:

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

mas não tenho certeza se essa seria a maneira correta de resolver o problema. Nem implicações eventuais ...

groups inheritance

Todos 8 comentários

Vejo o problema e sua sugestão não funciona bem, infelizmente. É um pouco complicado de resolver porque as anotações são resolvidas na fase de inicialização, o que significa que quando a anotação @Test do pai é analisada, obviamente não sabe nada sobre o fato de que a anotação filho irá adicionar mais grupos a ela ...

Cedric, obrigado por seus comentários imediatos sobre este problema. Você diz "é um pouco complicado de resolver", isso significa que você não acha que esse problema terá uma chance de ser resolvido em um futuro próximo? Você pode pensar sobre quaisquer soluções alternativas possíveis?

O que eu quis dizer foi: quando a resolução do grupo é executada, nenhuma classe de teste foi instanciada ainda, então quando eu olho para parentTestMethod (), não tenho uma instância de ChildTest que me permitiria colocar esse método neste grupo.

A resolução do grupo é puramente estática, enquanto o exemplo acima só pode ser resolvido dinamicamente.

Isso faz sentido?

Eu também vi esse comportamento. Quando eu executo meus testes sem um filtro de grupos, tudo passa, mas ao executar com grupos, as coisas falham. Em alguns casos, é devido à minha classe de teste herdar de alguma outra classe de teste, mas em outros casos eu tenho classes de teste POJO e parece que meus métodos @BeforeMethod e @AfterMethod não foram chamados corretamente.

BTW, minha solução é usar os grupos excluídos, o que obviamente não funcionará em todas as situações. @cbeust , houve algum trabalho em uma solução adequada para isso?

Mais de um ano depois e isso ainda não funciona.
@cbeust IMHO isso não faz nenhum sentido: uma vez que a classe pai é abstrata, sua resolução de grupo deve ser baseada em uma instância concreta de uma classe de teste.

FWIW, eu também corri para isso.

Eu criei um seletor de método personalizado, que usa os grupos da subclasse 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) {
    }
}
Esta página foi útil?
0 / 5 - 0 avaliações