Posso especificar um grupo para toda a classe em um caso de teste TestNG?

StackOverflow https://stackoverflow.com/questions/9044

  •  08-06-2019
  •  | 
  •  

Pergunta

Eu tenho uma classe base que representa um teste de banco de dados no TestNG e quero especificar que todas as classes que se estendem a partir desta classe são de um grupo "db-test", mas descobri que isso não parece possível.Eu tentei a anotação @Test:

@Test(groups = { "db-test" })
public class DBTestBase {
}

No entanto, isso não funciona porque a anotação @Test tentará transformar vários métodos em testes, e avisos/erros aparecerão no Eclipse quando os testes forem executados.

Então tentei desabilitar o teste, para que pelo menos os grupos sejam atribuídos:

@Test(enabled = false, groups = { "db-test" })
public class DBTestBase {
}

mas qualquer @BeforeTest (e outras anotações semelhantes) TAMBÉM será desativada ...o que obviamente não é o que eu quero.

Eu gostaria de anotar uma classe como sendo de um tipo específico de grupo, mas isso não parece possível no TestNG.Alguém tem alguma outra ideia?

Foi útil?

Solução

A resposta é através de um costume org.testng.IMethodSelector:

Isso é includeMethod() podemos excluir qualquer método que desejarmos, como um método público não anotado.

No entanto, para registrar um costume Java MethodSelector, você deve adicioná-lo ao Teste XML instância gerenciada por qualquer TestRunner, o que significa que você precisa do seu próprio TestRunner personalizado.

Mas, para construir um TestRunner personalizado, você precisa registrar um Fábrica de TestRunner, através de -testrunfactory opção.

MAS isso -testrunfactory NUNCA é levado em consideração por TesteNG aula...então você também precisa definir uma classe TestNG personalizada:

  • para substituir o método configure(Map),
  • então você pode realmente definir o TestRunnerFactory
  • TestRunnerFactory que criará um TestRunner personalizado,
  • TestRunner que definirá para a instância XMLTest um XMLMethodSelector personalizado
  • XMLMethodSelector que construirá um IMethodSelector personalizado
  • IMethodSelector que excluirá quaisquer métodos TestNG de sua escolha!

OK...É um pesadelo.Mas também é um desafio de código, então deve ser um pouco desafiador ;)

Todo o código está disponível em Trechos da Zona D.

Como de costume para um desafio de código:

  • uma classe java (e algumas classes internas)
  • copie e cole a classe em um diretório 'source/test' (já que o pacote é 'test')
  • execute-o (não são necessários argumentos)

Atualização de Mike Stone:

Vou aceitar isso porque parece muito próximo do que acabei fazendo, mas resolvi acrescentar o que fiz também.

Basicamente, criei uma anotação Groups que se comporta como a propriedade groups das anotações Test (e outras).

Então, criei um GroupsAnnotationTransformer, que usa IAnnotationTransformer para ver todos os testes e classes de teste que estão sendo definidas, depois modifica o teste para adicionar os grupos, o que funciona perfeitamente com exclusão e inclusão de grupos.

Modifique a construção para usar o novo transformador de anotação e tudo funcionará perfeitamente!

Bem...a única ressalva é que ele não adiciona os grupos a métodos que não sejam de teste...porque na época que fiz isso havia outro transformador de anotação que permite transformar QUALQUER COISA, mas de alguma forma não foi incluído no TestNG que eu estava usando por algum motivo...portanto, é uma boa ideia transformar seus métodos anotados antes/depois em AlwaysRun=true...o que é suficiente para mim.

O resultado final é que posso fazer:

@Groups({ "myGroup1", "myGroup2"})
public class MyTestCase {
    @Test
    @Groups("aMethodLevelGroup")
    public void myTest() {
    }
}

E fiz o transformador funcionar com subclasses e tudo mais.

Outras dicas

TestNG executará todos os métodos públicos de uma classe com uma anotação @Test.Talvez você possa alterar os métodos que não deseja que o TestNG execute para que não sejam públicos

Parece-me o seguinte desafio de código (postagem na wiki da comunidade):

Como poder executar todos os métodos de teste da classe Extended do grupo 'aGlobalGroup' sem:

  • especificando o grupo 'aGlobalGroup' na própria classe Extended?
  • testando métodos públicos não anotados da classe Extended?

A primeira resposta é fácil:
adicione uma classe TestNG(groups = { "aGlobalGroup" }) no nível da classe Base

Esse grupo será aplicado a todos os métodos públicos da classe Base e da classe Estendida.

MAS:mesmo métodos públicos que não sejam de teste (sem anotação TestNG) serão incluídos nesse grupo.

DESAFIO:evite incluir métodos que não sejam TestNG.

@Test(groups = { "aGlobalGroup" })
public class Base {

    /**
     * 
     */
    @BeforeClass
     public final void setUp() {
           System.out.println("Base class: @BeforeClass");
     }


    /**
     * Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
     * Will be executed even if the TestNG class tested is a sub-class.
     */
    @Test(groups = { "aLocalGroup" })
     public final void aFastTest() {
       System.out.println("Base class: Fast test");
     }

    /**
     * Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
     * Will be executed even if the TestNG class tested is a sub-class.
     */
    @Test(groups = { "aLocalGroup" })
     public final void aSlowTest() {
        System.out.println("Base class: Slow test");
        //throw new IllegalArgumentException("oups");
     }

     /**
      * Should not be executed. <br />
      * Yet the global annotation Test on the class would include it in the TestNG methods...
     */
    public final void notATest() {
       System.out.println("Base class: NOT a test");
     }

    /**
     * SubClass of a TestNG class. Some of its methods are TestNG methods, other are not. <br />
     * The goal is to check if a group specify in the super-class will include methods of this class. <br />
     * And to avoid including too much methods, such as public methods not intended to be TestNG methods.
     * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a>
     */
    public static class Extended extends Base
    {
        /**
         * Test not part a 'aGlobalGroup', but still included in that group due to the super-class annotation. <br />
         * Will be executed even if the TestNG class tested is a sub-class.
         */
        @Test
        public final void anExtendedTest() {
           System.out.println("Extended class: An Extended test");
        }

        /**
         * Should not be executed. <br />
         * Yet the global annotation Test on the class would include it in the TestNG methods...
         */ 
        public final void notAnExtendedTest() {
            System.out.println("Extended class: NOT an Extended test");
        }
    }

Não tenho certeza de como funciona a herança de anotação para TestNG, mas isso artigo pode ser de alguma utilidade.

Na verdade, isso pode ajude melhor, veja herdarGroups.

Você pode especificar a anotação @Test no nível do método que permite flexibilidade máxima.

public class DBTestBase {

    @BeforeTest(groups = "db-test")
    public void beforeTest() {
        System.out.println("Running before test");
    }

    public void method1() {
        Assert.fail(); // this does not run. It does not belong to 'db-test' group.
    }

    @Test(groups = "db-test")
    public void testMethod1() {
        Assert.assertTrue(true);
    }
}

Isso funciona para você ou estou faltando alguma coisa na sua pergunta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top