JUnit

Bom dia pessoal,

Primeiramente, gostaria de explicar que eu sou da engenharia elétrica, mas já estudo programação (C/C++, Assembly e JAVA) há mais de 10 anos e gostaria de pedir desculpa antecipadamente se a pergunta seguinte for muito trivial.

A dúvida é sobre o JUnit. É altamente recomendável que eu utilize essa framework para testar minhas classes? Vocês sempre realizam testes em todas as classes ou essa framework não é tão importante assim? Eu geralmente utilizo a classe Logger para verificação de erros.

Alguém poderia me explicar quanto o JUnit é inevitável? Eu só encontrei na internet apenas exemplos com casos triviais: soma, multiplicação, etc…

Obrigado,
PH

Oi PH, tudo bom?

O JUnit (ou qualquer outro framework de testes) é mto importante em qualquer sistema que esteja sendo desenvolvido. O papel dele é que vc desenvolva classes que possa testar suas classes, assim, evitando eventuais surpresas no futuro com alteracoes de código que vc nao lembraria os locais que a alteracao poderiam impactar.

O Logger eh uma coisa totalmente diferente do JUnit, com funcoes diferentes. O Logger soh pode te dizer o problema depois que ele tenha ocorrido e pra isso vc precisaria executar sua aplicacao, lembrando de ter de acessar a funcionalidade XPTO que impacta na funcionalidade Y, enfim, coisas que vc nao precisa, e nem deve, ficar se lembrando. Com isso, o risco de vc levar um erro para um ambiente de producao cresce consideravelmente. Em um framework de testes vc pode executar semrpre que houver alguma alteracao no seu sistema a sua suite de testes, assim, todos os erros que sua alteracao gerar no comportamento da aplicacao serao pegos bem antes da aplicacao ir para producao.

E o ideal eh que vc tenha uma classe de teste para cada classe do seu sistema. Testando todas as possiveis situacoes que podem ocorrer, desde por exemplo, passar parametro nulo em um metodo e esperar tomar uma excecao ateh testar a execucao correta de um metodo, com parametros validos.

Outra vantagem de escrever classes de testes no seu sistema eh que fica mais facil identificar o comportamento de um metodo, sem precisar ler o codigo do mesmo, vendo apenas o que os metodos de teste fazem e esperam como retorno.

  • JUNIT: É altamente recomendável que eu utilize essa framework para testar minhas classes?

Veja bem, JUnit é um framework para testes unitários. É altamente recomendável que vc pelo menos tente desenvolver alguns testes unitários usando o framework que vc melhor se adaptar. Existe também o TestNG, JBehave e outras abordagens, JUnit é só o mais popular.

Quer um exemplo: Tente fazer uns testes simples em uma classe sua e rode os testes junto com o EMMA para ver a cobertura de código. Provavelmente os seus testes simples vão exercitar uma parte do seu código e provar que ele funciona como vc espera, e haverá uma parte nebulosa, que pode não funcionar como vc espera. É completamente diferente de vc logar erros, pois logar vc sempre deve :wink:

Testes unitários podem mostrar que a sua arquitetura está esquisita demais, como alguns acoplamentos desnecessários, é o preço por começar a desenvolver sem testes. Algumas metodologias pregam que vc deveria criar os testes primeiro e depois criar um código que “passe” em todos (um bom exemplo é o TDD).

Imagine que vc tem um método assim

[code]public class Exemplo{
private RepositorioExemplo repositorio = null;
public Exemplo(){
this.repositorio = new RepositorioExemplo();
}
public Exemplo(RepositorioExemplo repositorio){
this.repositorio = repositorio
}
// Day pode ser um enum, segunda, terça, etc…
public long getTotalByDay(Day day) throws Exception{
if(day == null)
throw new Exception(“Day NULL ?!?!?! WTF???”);
return this.repositorio.anotherGetTotalByCode(day);
}
}

public class MeuRepositorioExemplo {
public long anotherGetTotalByDay(Day day){
// Aqui tenho a lógica de ir no banco de dados
// e fazer as queries malucas
}
}[/code]

Se eu for testar a classe exemplo, eu posso fazer 2 tipos de teste: passando day nulo e não nulo.

Nulo eu devo receber uma exception, não nulo devo receber um long.

Eu posso mockar o repositorio, afinal ele pode ser injetado via construtor, dizendo que , hipoteticamente, se eu chamar anotherGetTotalByDay(segunda) deve retornar 666. Ai eu testo todo o metodo getTotalByDay.

Esta tudo testado? Não… tem a classe Repositorio! Se eu tenho um objeto que TEM outros objetos, eu posso fingir que todos os objetos internos são bem comportados e testar este objeto. Depois eu posso testar se cada objeto é bem comportado. É dificil? Sim, se vc começou fazendo qq outra coisa.

Testes, como são encarados modernamente, estão mais para uma metodologia do que simplesmente ferramentas. Dê uma olhada em Test-Driven Development (TDD). Dentro de TDD, há conceitos como testes de unidade, testes de aceitação, test doubles, etc. Testes de unidade (aqueles auxiliados por ferramentas como JUnit) são o bloco básico de TDD e são, sim, fundamentais.

[quote=pafuncio]Oi PH, tudo bom?

O Logger eh uma coisa totalmente diferente do JUnit, com funcoes diferentes. O Logger soh pode te dizer o problema depois que ele tenha ocorrido e pra isso vc precisaria executar sua aplicacao, lembrando de ter de acessar a funcionalidade XPTO que impacta na funcionalidade Y, enfim, coisas que vc nao precisa, e nem deve, ficar se lembrando. Com isso, o risco de vc levar um erro para um ambiente de producao cresce consideravelmente. Em um framework de testes vc pode executar semrpre que houver alguma alteracao no seu sistema a sua suite de testes, assim, todos os erros que sua alteracao gerar no comportamento da aplicacao serao pegos bem antes da aplicacao ir para producao.
[/quote]

Oi pafuncio,

Eu geralmente utilizo a API Logging para ir lançando em um arquivo o que o software está fazendo para que um certo usuário possa testar o aplicativo e me retornar o log em caso de algum problema. Isso seria um erro ou é normal utilizar o Logger para um certo “debugging”?

Desenvolvo apenas software livre (sou estudante de eng. elétrica). Portanto, não seria um incômodo para o usuário reportar esses logs.

Obrigado,
Pedro Henrique