Child pages
  • Testes automáticos
Skip to end of metadata
Go to start of metadata

Dicas e Conceitos para Testes Automáticos

  • Testes Unitários são testes automatizados que buscam testar os métodos de uma única classe; recomenda-se que eles estejam no mesmo pacote da classe sendo testada, para poder ter acesso não só aos métodos públicos como também aos de pacote. Exemplo: para uma classe com.abc.Bla, teríamos uma classe com.abc.BlaTest para testar seus métodos.
  • Nos projetos da Logística, ainda não estamos realizando testes unitários, mas sim Testes de Integração: a classe chamada para executar os testes (conhecida como suite de testes) instancia um servidor e um cliente, e todos os testes até o momento testam chamadas aos serviços do servidor, do ponto de vista do cliente.
  • Organização das classes: como estamos criando testes de integração e não unitários, não é obrigatório manter todos os métodos de teste relativos a um mesmo serviço dentro de uma mesma classe de testes. Classes de testes muito grandes podem trazer algumas conseqüências indesejadas, como: alta probabilidade de duas ou mais pessoas editarem a classe ao mesmo tempo, demora desnecessária para o desenvolvedor que deseja testar apenas uma pequena mudança e é obrigado a aguardar todos os testes daquela classe. A diretriz é o bom senso: partindo-se da separação inicial por serviço, caso uma mesma classe de testes comece a crescer significativamente, pode ser uma boa idéia quebrá-la em uma ou mais classes, seguindo um novo critério de organização. A título de exemplo, poderíamos ter vários critérios de separação para os métodos de teste relativos ao serviço de cenários (ScenariumService):
  1. Uma classe para métodos que alteram as pastas, outra para métodos que alteram os cenários;
  2. Uma classe para métodos de criação, outra para atualização, outra para remoção;
  3. Uma classe por cada método da interface.
    Não existe uma restrição nem uma solução geral; deve-se analisar caso a caso, discutindo-se com os colegas para encontrar o melhor custo-benefício.
  • A classe logistic.test.unit.TestUtil contém métodos utilitários para a construção de testes.
  • Se você precisar de objetos que serão reutilizados por uma ou mais classes de testes, existem duas classes criadas para esse fim: "logistic.test.unit.setuptask.SetupTaskPerformer" e "logistic.logic.scenariumservice.CommonScenarium.TestDataRepository". A primeira representa tarefas que você precisa executar antes de cada teste (logo após a instanciação do servidor) e a segunda é um repositório singleton de objetos que você pode usar para compartilhar objetos entre os testes. O passo-a-passo é o seguinte:
  1. Crie uma ou mais classes que estendam logistic.test.unit.setuptask.SetupTaskPerformer;
  2. Nessas classes, implemente o método performSetupTask, criando os objetos que você deseja compartilhar (por exemplo, cenários ou pastas);
  3. Recupere a instância única de logistic.logic.scenariumservice.CommonScenarium.TestDataRepository e nela armazene os objetos que você criou (você poderá ter de criar métodos "get/set" adicionais);
  4. Implemente também o undoSetupTask para desfazer o que o performSetupTask fez (executado ao fim dos testes, necessário para o banco retornar ao seu estado inicial);
  5. Crie uma classe estendendo logic.test.unit.LogisticTestCase e sobrescreva o método getTaskPerformers;
  6. Nesse método, crie e retorne uma lista contendo a(s) classe(s) filhas de logistic.test.unit.setuptask.SetupTaskPerformer que você criou;
  7. Suas classes de teste deverão então estender esta última classe, e para recuperar os objetos armazenados basta invocar a instância de logistic.logic.scenariumservice.CommonScenarium.TestDataRepository e obter os objetos através do método "get" apropriado.

Debug dos Testes automáticos no Eclipse

É possível usar o Eclipse para debug dos testes automáticos, não só na parte cliente dos testes, mas também no servidor. A única diferença do debug cliente/servidor normalmente feito no desenvolvimento é que os testes disparam, na inicialização, um servidor por conta própria, chamado por linha de comando em outra JVM.

Para desabilitar essa chamada e rodar um servidor que possa ser monitorado, basta fazer o seguinte:

  • Entre no método setUp da LogisticTestSetup;
  • Comente três linhas que dizem respeito à thread do servidor:

    // Thread thread = new StartServer();
    // thread.start();
    // Thread.sleep(SLEEP_TIME);

  • Dispare então um servidor manualmente em modo debug;
  • É necessário incluir o parâmetro-TestMode true* na lista de argumentos para a execução do servidor. Caso não seja fornecido este argumento, o MockClient irá logar e, imediatamente, deslogar sem executar os testes.
  • Dispare os testes em modo debug.

Com isso, posicionando breakpoints tanto nos testes quanto no servidor, você poderá acompanhar o comportamento dos testes em toda sua extensão (com exceção do PL/SQL, é claro).

Execução de um Único Caso de Testes ou Método

É possível a execução de um único caso de testes no Logistic, ou mesmo de um método apenas. Essa funcionalidade é bastante útil para quem desenvolve testes.

Nos projetos Logistic deve existir uma classe que represente um ponto de entrada para os testes, estendendo a LogisticTestSuite, com um método suite() que invoque o método createSingleTestCase() da LogisticTestSuite (no caso do Bandeira Brasil, é a bandeirabr.BandeiraSingleTest; no caso do Alope, é a alope.AlopeSingleTest; no caso do Planref, é a planref.PlanrefSingleTest). Essa classe esperará receber duas variáveis de sistema: test.class (o nome "full" da classe de testes, obrigatória) e test.method (o nome de um único método a ser executado, opcional).

Devem ser passadas para a JVM, as seguintes variáveis, da seguinte forma(exemplo):

  • -Dtest.class=bandeirabr.access.scenariumservice.ScenariumServiceTest -Dtest.method=testCreateScenariumFromOtherScenarium

Se a variável "test.method" não for especificada, todos os testes da classe serão executados.

A execução pode ser feita pelo Eclipse ou pelo Ant. Se for via Eclipse, as duas variáveis poderão ser incluídas na aba "Arguments", campo "VM Arguments" da configuração de runtime da classe. Se for via Ant, basta chamar o "ant execSingleTest" seguido das duas variáveis.

IMPORTANTE: para permitir a execução de um único método, a classe de teste deve obrigatoriamente ter dois construtores: um padrão e outro recebendo uma String, que será o nome do método a ser executado.

  • No labels