Teste Unitário na mão ou com ajuda do JUnit?

Quem aí acha que compensa criar testes unitários na mão?

Com certeza JUnit. Fica fácil de rodar os testes e verificar que seu sistema continua funcionando. Se houver erro em algum teste fica fácil achar também onde está o problema.

+1 voto para JUnit. Você também pode integrá-lo no build com Maven ou Ant. Dessa maneira seu sistema pode ser testado a cada build.

Hum. Obrigado galera.

Algúem a favor de usar Java puro?

[quote=andredecotia]Hum. Obrigado galera.

Algúem a favor de usar Java puro?[/quote]
Só se for como estudo… ver como funcionam os princípios dos testes unitários, ou até mesmo implementar seu próprio framework de testes (como é feito no livro TDD).

Mas para uso em produção não existe nenhuma vantagem!

O JUnit (especialmente quando integrado com Eclipse) faz um trabalho muito bom em reportar os resultados dos testes, exibir as asserções que deram erro, exibir stacktrace permitindo rápido acesso ao ponto da falha… tudo isso daria um trabalho imenso para se fazer com java puro.

[quote=andredecotia]Hum. Obrigado galera.

Algúem a favor de usar Java puro?[/quote]

JUnit é Java puro :smiley: Não tem nenhuma mágica por trás dele.

para que reiventar a roda, se a mesma ja existe, já funciona e é completo ?! A meu ver, só c for para estudar, caso contrario ñ faz muito sentido…

  • JUnit

Hum. Enxerguei/go o ponto de vista de cada um… Embora a questão que venho pensando é que o JUnit é limitado, posso estar errado, contudo, vejam através de meus olhos:

1 - Digamos que tenha uma massa de dados e peço para que o JUnit verifique, caso ele lança um AssertionError ele irá parar os testes, não!? Se fosse programação Java pura, ao qual eu tivesse programado, eu tiraria essa regra, sendo assim os mesmos continuariam, o teste/bateria de testes com base na a fonte de dados que está sendo consumida (de um Excel, lista etc)…

2 - Mais fácil de gerar relatório, já com JUnit tenho que baixar Ant etc e sinceramente não achei material direto ao ponto… Com Java puro eu poderia fazê-lo gravando em um .TXT

Priuli, rmendes08, gomesrod, e você meu brother RafaelViana o que vocês diriam sobre estes pontos levantados?

Vc só precisa configurar o seu junit para ele continuar em caso de erro. Não entendi essa pergunta.

Testes são escritos em Java assim como a Implementação é esctrita em Java. o JUnit é um bliblioteca que te auxilia a configurar o ambiente de execução.

Quando ocorrer um erro, aquele teste em particular é interrompido. Lembrando que os testes devem ser isolados, ou seja, o resultado de um não influencia no outro. Pode ser que seja um erro na maneira que você está escrevendo os testes… talvez esteja tudo em um único SUPERTESTE, o que não é legal. Se quiser discutir mais a respeito disso, poste um exemplo de seus testes que tem bastante gente que conhece do assunto e está disposta a ajudar.

Usando o JUnit você tem total controle sobre o resultado da sessão de testes que acabou de ser executada, e pode fazer o que quiser com os resultados.

Vou colocar um exemplo rápido que acabei de criar. Veja que estou apenas imprimindo mensagens, mas pode ser feita qualquer coisa, como gravar um log ou até mesmo inserir em um banco de dados.

public static void main(String[] args) {
 // Vamos executar os testes de um jeito um pouco diferente, com um Listener para notificar a cada execução de testes.

		TestResult result = new TestResult();
		
		result.addListener(new TestListener() {
			
			public void startTest(Test test) {
				if (test instanceof TestSuite) {
					TestSuite suite = (TestSuite) test;
					System.out.println("#######################\nIniciando suite de testes\n#######################" + suite.getName());
				} else if (test instanceof TestCase) {
					TestCase tcase = (TestCase) test;
					System.out.println("Iniciando testcase: " + tcase.getName());
				}
			}
			
			public void endTest(Test test) {
				if (test instanceof TestSuite) {
					TestSuite suite = (TestSuite) test;
					System.out.println("\nFinalizando suite de testes: " + suite.getName());
				} else if (test instanceof TestCase) {
					TestCase tcase = (TestCase) test;
					System.out.println("Finalizando testcase: " + tcase.getName());
				}
			}
			
			public void addFailure(Test test, AssertionFailedError t) {
				if (test instanceof TestCase) {
					TestCase tcase = (TestCase) test;
					System.out.println("Falha de assercao! " + tcase.getName());
					System.out.println(t.getMessage());
				}
			}
			
			public void addError(Test test, Throwable t) {
				if (test instanceof TestCase) {
					TestCase tcase = (TestCase) test;
					System.out.println("ERRO! " + tcase.getName());
					System.out.println(t.getMessage());
				}
			}
		});
		
// Agora é só executar a suite de testes usando o result "turbinado"
		MinhaSuiteDeTestes.suite().run(result);
	}

Mais uma vez: para funcionar legal é preciso que os testes estejam bem divididos.

Os testes tem que ser auto explicativos vc deve olhar os métodos e conseguir perceber o que o teste faz/testa so de olhar o metodo. a melhor maneira(minha opinião) de se testar é criar métodos especifico(nada de testar mais de uma coisa em um método @Test) para cada teste e com um belo nome que se auto-explica. Tambem é interessante que os testes ñ alterem dados do banco, e se possivel não usar chamadas IO nos teste de unidades, o legal é vc usar mocks(objetos fakes, existem algumas libs pra isso como EasyMock, Mokito…) em todas as chamadas de IO, c vc conseguir utilizar os mocks corretamente seu codigo vai estar com um baixo acoplamento e bem limpo.

Segue um exemplo, basico: vc quer testar, usando teste de unidade, a sua classe de negocio que faz cadastro de usuario… intão ficaria ± assim:

/**
Classe que realiza o cadastro, edição,exclusão de usuario
*/
public class CadastroDeUsuarioBO{

public void salva(Usuario usuario) throw ValidacaoDeCadastroException {
    
    if(usuario.getNome() == null || usuario.getNome().isEmpty()){
             throw new ValidacaoDeCadastroException ("Usuario esta sem nome, Campo Obrigatorio");
    }

    meuDao.save(usuario);
}
//....
}
/**
Teste de unidade para a classe CadastroDeUsuarioBO
*/
public CadastroDeUsuarioBOTest{

  private CadastroDeUsuarioBO usuarioBO;  

 public void setUp(){
  usuarioBO = new CadastroDeUsuarioBO();

}

 @Test
 public void naoDeveCadastrarUsuarioSemNome(){
     Usuario u = new Usuario();
     try{
   
            usuarioBO.salvar(u);
            fail("Teste falhou, usuario esta sem o nome, não pode cadastrar");
    
 }catch(ValidacaoDeCadastroException e){
         //OK TESTE PASSOU
     }catch(Exception e){
          fail("Exceção invalida);
     }

 @Test
 public void naoDeveCadastrarUsuarioComNomeIguais(){}
 @Test
 public void deveCadastrarUsuarioSemEndereco(){}

 @Test
 public void naoDeveCadastrarUsuarioComEmailIguais(){}

 @Test
 public void cadastroNaoPodeLancarErro(){}

@Test
 public void aoAtualizarUmUsuarioDeveGardarUmHistorico(){
 //otimo exemplo para usar Mock no dao que devera salvar o log e validar as chamadas deste mock(Dao)
}
//Sem medo da quantidade de testes, o importante é que fiquem livres, sem referencia um do outro e sem problemas de ordem de execução
}

Não, no máximo 1 dos testes os outros continuam. O modelo de teste que estamos falando é de teste de unidade, o nome já diz: teste unico, no JUnit vc testa cada evento que vc ache q pode acontecer separadamente(exemplo acima q mostrei UsuarioBO), porem 1 por vez, criando quantos métodos de teste vc quizer. Caso vc testar e der erro no teste ira dar erro em 1 teste e os outros continuaram a ser rodados, desde q vc ñ coloque tudo em um método só…
O ideal é que o código da sua implementação sempre tenha um método que ira cadastrar um objeto por vez e não uma lista, para q vc consegua testar os diferentes casos separadamente, um a um…

O JUnit é só para testar o seu codigo antes do mesmo ir para produção, ele ñ foi feito para tirar/forneceer relatorio de dados, neste caso vc deve preocupar outras libs e/ou modelos de teste diferente para isso.

Não se c vc já usou Mocks, mas eles são incríveis vc consegue testar muito mais com eles do que só com o JUnit, c vc entender tudo vc ñ vai nem querer em pensar em fazer seus testes na unha!! rss

Com toda certeza do mundo JUnit!

Tem razão quanto a isso, uma barra vermelha deve se transformar em uma correção e não em um relatório para o gerente!