Como escrever um teste de unidade?


135

Eu tenho uma classe Java. Como posso testar a unidade ?


No meu caso, eu tenho classe que faz uma soma binária. Ele pega duas byte[]matrizes, as soma e retorna uma nova matriz binária.


7
Você pode utilizar uma ferramenta como jUnit e escrever casos de teste (métodos de teste) para sua classe java. Em seguida, chame os testes jUnit como parte do processo de construção (ant / maven). O uso do jUnit não é nada difícil, a parte difícil é apresentar o maior número possível de cenários de teste, para que você consiga detectar os bugs cedo e frequentemente.
CoolBeans

Respostas:


133
  1. Defina a saída esperada e desejada para um caso normal, com a entrada correta.

  2. Agora, implemente o teste declarando uma classe, atribua um nome a ela (geralmente algo como TestAddingModule) e adicione o método testAdd a ele (ou seja, como o abaixo):

    • Escreva um método e, acima dele, adicione a anotação @Test.
    • No método, execute sua soma binária e assertEquals(expectedVal,calculatedVal).
    • Teste seu método executando-o (no Eclipse, clique com o botão direito do mouse, selecione Executar como → Teste JUnit).

      //for normal addition 
      @Test
      public void testAdd1Plus1() 
      {
          int x  = 1 ; int y = 1;
          assertEquals(2, myClass.add(x,y));
      }
  3. Adicione outros casos, conforme desejado.

    • Teste se sua soma binária não gera uma exceção inesperada se houver um estouro de número inteiro.
    • Teste se seu método lida com entradas nulas normalmente (exemplo abaixo).

      //if you are using 0 as default for null, make sure your class works in that case.
      @Test
      public void testAdd1Plus1() 
      {
          int y = 1;
          assertEquals(0, myClass.add(null,y));
      }

1. é necessária a notação @Test? 2. por que não testar a entrada nula com assertNotNull? 3. onde são capturados os resultados dos testes de unidade? como os resultados são indicados ao usuário?
user137717

10
Sim, @Testé necessária notação. Isso é feito para sinalizar ao executor de teste de unidade que este método representa um teste de unidade e deve ser executado. Métodos que não são anotados com @Testnão são executados pelo executor de teste.
Ali Shah Ahmed

para o segundo teste - você não deve adicionar um apenas nullpara ydar a você y?
Adjit 27/04

Obrigado! Eu quero saber por que não há necessidade de adicionar staticao modificador do método de teste.
Liang Zhang

104

Eu forneço este post para o IntelliJ e o Eclipse .

Eclipse:

Para fazer o teste de unidade para o seu projeto, siga estas etapas (estou usando o Eclipse para escrever este teste):

1- Clique em Novo -> Projeto Java.

Criar Projeto

2- Anote o nome do seu projeto e clique em Concluir.

Criar Projeto

3- Clique com o botão direito do mouse no seu projeto. Em seguida, clique em Novo -> Classe.

Criar classe

4- Anote o nome da sua turma e clique em Concluir.

Criar classe

Em seguida, conclua a classe assim:

public class Math {
    int a, b;
    Math(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int add() {
        return a + b;
    }
}

5- Clique em Arquivo -> Novo -> Caso de Teste JUnit.

Criar teste JUnite

6- Marque setUp () e clique em Concluir. SetUp () será o local em que você inicializou seu teste.

Marque SetUp ()

7- Clique em OK.

Adicionar JUnit

8- Aqui, simplesmente adiciono 7 e 10. Portanto, espero que a resposta seja 17. Conclua sua classe de teste assim:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MathTest {
    Math math;
    @Before
    public void setUp() throws Exception {
        math = new Math(7, 10);
    }
    @Test
    public void testAdd() {
        Assert.assertEquals(17, math.add());
    }
}

9- Escreva, clique na sua classe de teste no explorador de pacotes e clique em Executar como -> Teste JUnit.

Execute o teste JUnit

10- Este é o resultado do teste.

Resultado do Teste

IntelliJ: Observe que eu usei a comunidade IntelliJ IDEA 2020.1 para as capturas de tela. Além disso, você precisa configurar seu jre antes dessas etapas. Estou usando o JDK 11.0.4.

1- Clique com o botão direito na pasta principal do seu projeto-> novo -> diretório. Você deve chamar isso de 'teste'. insira a descrição da imagem aqui 2- Clique com o botão direito do mouse na pasta de teste e crie o pacote adequado. Sugiro criar os mesmos nomes de embalagem que a classe original. Em seguida, clique com o botão direito do mouse no diretório de teste -> marque o diretório como -> raiz de fontes de teste. insira a descrição da imagem aqui 3- No pacote correto no diretório de teste, você precisa criar uma classe Java (sugiro usar Test.java). insira a descrição da imagem aqui 4- Na classe criada, digite '@Test'. Em seguida, entre as opções fornecidas pelo IntelliJ, selecione Adicionar 'JUnitx' ao caminho de classe. 5- Escreva seu método de teste em sua classe de teste. A assinatura do método é como:insira a descrição da imagem aqui insira a descrição da imagem aqui

@Test
public void test<name of original method>(){
...
}

Você pode fazer suas afirmações como abaixo:

Assertions.assertTrue(f.flipEquiv(node1_1, node2_1));

Estas são as importações que adicionei:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

insira a descrição da imagem aqui

Este é o teste que escrevi: insira a descrição da imagem aqui

Você pode verificar seus métodos como abaixo:

Assertions.assertEquals(<Expected>,<actual>);
Assertions.assertTrue(<actual>);
...

Para executar seus testes de unidade, clique com o botão direito do mouse no teste e clique em Executar. insira a descrição da imagem aqui

Se o seu teste for aprovado, o resultado será o seguinte: insira a descrição da imagem aqui

Espero que ajude. Você pode ver a estrutura do projeto no GitHub https://github.com/m-vahidalizadeh/problem_solving_project .


12
Ame sua resposta, é o melhor "como fazer"!
Alisa

4
Fico feliz que minha resposta tenha sido útil. Obrigado pelo seu comentário.
Mohammad

1
É assim que os tutoriais devem ser; exemplo limpo, conciso e completo. Muito bom.
Jack Of Blades

1
Muito obrigado Jack. Fico feliz que você tenha achado útil.
Mohammad

18

Essa é uma pergunta muito genérica e há várias maneiras de ser respondida.

Se você deseja usar o JUnit para criar os testes, é necessário criar sua classe testcase e, em seguida, criar métodos de teste individuais que testem a funcionalidade específica da sua classe / módulo em testes (as classes únicas do testcase geralmente são associadas a uma única classe de "produção" que está sendo testado) e, dentro desses métodos, executa várias operações e compara os resultados com o que seria correto. É especialmente importante tentar cobrir o maior número possível de caixas de esquina.

No seu exemplo específico, você pode, por exemplo, testar o seguinte:

  1. Uma adição simples entre dois números positivos. Adicione-os e verifique se o resultado é o que você esperaria.
  2. Uma adição entre um número positivo e um número negativo (que retorna um resultado com o sinal do primeiro argumento).
  3. Uma adição entre um número positivo e um número negativo (que retorna um resultado com o sinal do segundo argumento).
  4. Uma adição entre dois números negativos.
  5. Uma adição que resulta em um estouro.

Para verificar os resultados, você pode usar vários métodos assertXXX da classe org.junit.Assert (por conveniência, você pode 'importar estática org.junit.Assert. *'). Esses métodos testam uma condição específica e falham no teste, se não validar (com uma mensagem específica, opcionalmente).

Exemplo de classe testcase no seu caso (sem o conteúdo dos métodos definido):

import static org.junit.Assert.*;

public class AdditionTests {
    @Test
    public void testSimpleAddition() { ... }


    @Test
    public void testPositiveNegativeAddition() { ... }


    @Test
    public void testNegativePositiveAddition() { ... }


    @Test
    public void testNegativeAddition() { ... }


    @Test
    public void testOverflow() { ... }
}

Se você não está acostumado a escrever testes de unidade, mas sim testar seu código escrevendo testes ad-hoc que validam "visualmente" (por exemplo, você escreve um método principal simples que aceita argumentos inseridos usando o teclado e imprime os resultados - e, em seguida, você continua inserindo valores e se validando se os resultados estiverem corretos), iniciando escrevendo esses testes no formato acima e validando os resultados com o método assertXXX correto, em vez de fazê-lo manualmente. Dessa forma, você pode executar o teste muito mais facilmente do que se tivesse que fazer testes manuais.


8

Como o @CoolBeans mencionado, dê uma olhada no jUnit . Aqui está um pequeno tutorial para você começar também com o jUnit 4.x

Finalmente, se você realmente quiser aprender mais sobre testes e desenvolvimento orientado a testes (TDD), recomendo que você dê uma olhada no seguinte livro de Kent Beck: Desenvolvimento orientado a testes por exemplo .


6

Outras respostas mostraram como usar o JUnit para configurar as classes de teste. JUnit não é a única estrutura de teste Java. Concentrar-se nos detalhes técnicos do uso de uma estrutura, no entanto, diminui os conceitos mais importantes que devem orientar suas ações; portanto, falarei sobre eles.

  • O teste (de todos os tipos de coisas) compara o comportamento real de algo (O Sistema em Teste, SUT) com o comportamento esperado .

  • O teste automatizado pode ser feito usando um programa de computador. Como essa comparação está sendo feita por um programa de computador inflexível e não inteligente, o comportamento esperado deve ser conhecido de maneira precisa e inequívoca.

  • O que um programa ou parte de um programa (uma classe ou método) deve fazer é sua especificação . Portanto, o teste de software exige que você tenha uma especificação para o SUT. Pode ser uma descrição explícita ou uma especificação implícita em sua cabeça do que é esperado.

  • Portanto, o teste de unidade automatizado requer uma especificação precisa e inequívoca da classe ou método que você está testando.

  • Mas você precisou dessa especificação quando decidiu escrever esse código. Portanto, parte do que é o teste realmente começa antes de você escrever uma única linha do SUT. A técnica de teste do Test Driven Development (TDD) leva essa ideia ao extremo e você deve criar o código de teste de unidade antes de escrever o código a ser testado.

  • Estruturas de teste de unidade testam seu SUT usando asserções . Uma asserção é uma expressão lógica (uma expressão com um booleantipo de resultado; um predicado ) que deve ser truese o SUT estiver se comportando corretamente. A especificação deve, portanto, ser expressa (ou reexpressa) como asserções.

  • Uma técnica útil para expressar uma especificação como asserções é a programação por contrato . Essas especificações são em termos de pós-condições . Uma pós-condição é uma afirmação sobre o estado publicamente visível do SUT após o retorno de um método ou construtor. Alguns métodos têm pós-condições que são invariantes , que são predicados verdadeiros antes e após a execução do método. Também se pode dizer que uma classe possui invariantes, que são pós-condições de todos os construtores e métodos da classe e, portanto, sempre devem ser verdadeiros. Pós-condições (e invariantes) são expressas apenas em termos de publicidade Estado visível: publice protectedcampos, os valores retornados por retornados porpublice protectedmétodos (como getters) e o estado publicamente visível dos objetos transmitidos (por referência) aos métodos.


Muitos iniciantes postam perguntas aqui perguntando como eles podem testar algum código, apresentando o código, mas sem especificar a especificação para esse código. Como mostra essa discussão, é impossível alguém dar uma boa resposta a essa pergunta, porque na melhor das hipóteses os respondentes em potencial precisam adivinhar a especificação e podem fazê-lo incorretamente. O autor da pergunta evidentemente não entende a importância de uma especificação e, portanto, é um novato que precisa entender os fundamentos que descrevi aqui antes de tentar escrever algum código de teste.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.