Teste Unitarios - desenho dos testes

5 respostas
smota

Olá pessoal,

Estou em uma dúvida existencial … vou postar logo abaixo um código de um teste unitário pra ver o quanto vcs xingam :shock:
(minha dúvida é se é assim mesmo, vcs testam o comportamento esperado com entradas corretas e incorretas (incluindo exceções)? varios testes em um método test* mesmo? etc. etc. - comentários e links são bem vindos)

package app.vmanager;

import junit.framework.TestCase;
import app.vmanager.exception.InvalidVariableParameterException;
import app.vmanager.exception.MissingVariableParameterException;
import app.vmanager.exception.VariableException;
import app.vmanager.exception.VariableNotFoundException;

public class VariableManagerTest extends TestCase {
	
	private static final String validConfig = 
		"<variable name=\"test\" type=\"sequence\" />";		
	private static final String invalidConfig = 
		"<variable name=\"test\" />";
	private static final String invalidConfig_type = 
		"<variable name=\"test\" type=\"foo\" />";
	private static final String invalidConfig_root = 
		"<foo name=\"test\" type=\"foo\" />";
	
	private VariableManager vm;
	
	public void setUp() throws VariableException {
		vm = new VariableManager();
	}
	
	public void tearDown() {
		vm = null;
		System.gc();
	}
	
	public void testInvalidAddConfig() {
		boolean failed = true;
		
		try {
			vm.addConfig(invalidConfig);
			failed = false;
		} catch (InvalidVariableParameterException e) {
			assertTrue(false);
			failed = false;
		} catch (MissingVariableParameterException e) {
			assertTrue(true);
		} catch (VariableException e) {
			assertTrue(false);
			failed = false;
		}
		
		try {
			vm.addConfig(invalidConfig_type);
			failed = false;
		} catch (InvalidVariableParameterException e) {
			assertTrue(true);
		} catch (MissingVariableParameterException e) {
			assertTrue(false);
			failed = false;
		} catch (VariableException e) {
			assertTrue(false);
			failed = false;
		}
		
		try {
			vm.addConfig(invalidConfig_root);
			failed = false;
		} catch (InvalidVariableParameterException e) {
			assertTrue(false);
			failed = false;
		} catch (MissingVariableParameterException e) {
			assertTrue(false);
			failed = false;
		} catch (VariableException e) {
			assertTrue(true);
		}
		
		assertTrue(failed);
	}
	
	public void testValidAddConfig() {
		try {
			vm.addConfig(validConfig);
			assertTrue(true);
		} catch (InvalidVariableParameterException e1) {
			assertTrue(false);
		} catch (MissingVariableParameterException e1) {
			assertTrue(false);
		} catch (VariableException e) {
			assertTrue(false);
		}
		
	}

	public void testInvalidAddConfigBlock() {
		try {
			vm.addConfigBlock(
					"<foo>" +
					validConfig   +
					"</foo>");
			assertTrue(false);
		} catch (InvalidVariableParameterException e) {
			assertTrue(false);
		} catch (MissingVariableParameterException e) {
			assertTrue(false);
		} catch (VariableException e) {
			assertTrue(true);
		}
		
		try {
			vm.addConfigBlock(
					"<variables>" +
					invalidConfig   +
					"</variables>");
			assertTrue(false);
		} catch (InvalidVariableParameterException e) {
			assertTrue(false);
		} catch (MissingVariableParameterException e) {
			assertTrue(true);
		} catch (VariableException e) {
			assertTrue(false);
		}
		
		try {
			vm.addConfigBlock(
					"<variables>" +
					invalidConfig_type   +
					"</variables>");
			assertTrue(false);
		} catch (InvalidVariableParameterException e) {
			assertTrue(true);
		} catch (MissingVariableParameterException e) {
			assertTrue(false);
		} catch (VariableException e) {
			assertTrue(false);
		}
	}
	
	public void testValidAddConfigBlock() {
		try {
			vm.addConfigBlock(
					"<variables>" +
					validConfig   +
					"</variables>");
			assertTrue(true);
		} catch (InvalidVariableParameterException e) {
			assertTrue(false);
		} catch (MissingVariableParameterException e) {
			assertTrue(false);
		} catch (VariableException e) {
			assertTrue(false);
		}		
	}

	public void testValidGetVariable() {
		testValidAddConfig();
		assertNotNull(vm.getVariable("test"));
	}
	
	public void testInvalidGetVariable() {
		testInvalidAddConfig();
		try {
			vm.getVariable("test");
			assertTrue(false);
		} catch (VariableNotFoundException e) {
			assertTrue(true);
		}
	}
	
	public void testSaveAll() {
		//TODO Implement saveAll().
	}

}

5 Respostas

F

SMota,

Boa pergunta, eu costumo cirar varios metodos para teste do mesmo metodo, com as possibilidades corretas e incorretas, validando as exceptions.
Mas tambem nao sei qual a meneira correta e nem a melhor de fazer isso.

]['s

louds

Eu costumo fazer o seguinte quando a saida esperada é uma exception.

public void testNPE() {
  try {
    Object o = null; o.toString();
    fail("NullPointerException expected");
  } catch(NullPointerException e) {
    ; //faz nada
  }
}
jgbt

eu costumo criar varios metodos de test para o mesmo metodo, testando as entradas corretas e incorretas.no caso de exception, testo como o louds, so coloco um assert true dentro do catch(p/ garantir, hehehe).
faço assim pq acho que cada metodo de teste deve testar uma unica condição, para determinada situação.

[]'s

legionarioba

Caro smota,

Pense que se você está construindo um teste de unidade, seus métodos também devem ser"únicos", ou seja, você deve ter uma versão "Ok" e uma versão "falha" pra cada tipo de coisa que você queira testar(cada método no caso). Se você aglomerar vários testes não conseguirá testar todas as situações simultaneamente. O ideal é que você queira gerar testes pra uma classe com um método do tipo setQuantidadeFilhos, ai você estaria testando coisas como:

1) Se o valor passado é não inteiro, lança-se um "ParametroNaoInteiroException", e ai você usa o catch pra pegar essa exception .
2) Se o valor passado é inteiro, teste ok
3) Se o valor passado é negativo, lança-se um "ParametroNaoPositivoException", e ai você usa o catch pra pegar essa exception .
4) Se o valor passado é positivo, teste ok

Pense que a idéia de um método de teste é testar apenas o funcionamento ou não do mesmo pra uma dada situação, não pra todas ao mesmo tempo, você (bom humano que é) acaba se esquecendo de exceções geradas por causas quaisquer como Exceções em tempo de execução ou outras geradas por passagem incorreta de parâmetros, falha em conexão de banco, etc (que nada podem ter a ver diretamente com seu teste)...

Um exemplo bom acho que é mais ou menos assim: (Procure repetir isso pra cada coisa que você queira testar...)

public void testSetQtdeFilhosOk() throws Exception {

 Pai p = null;
 try{	
   p = new Pai();
   p.setQtdeFilhos(3);
   assert(true);
 }
 catch(Exception e){
   fail("Erro nao esperado no método testeQtdeFilhosOk");
 }	
}
public void testSetQtdeFilhosFalho() throws Exception {

 Pai p = null;
 try{	
   p = new Pai();
   p.setQtdeFilhos(-5); //Considerando que na sua classe Pai você lança a exceção ...
   assert(false,"Exceção deveria ser lançada pela classe Pai, mas não foi") ;
 }
 catch(Exception e){
   if (e instanceof ParametroNaoPositivoException){    	
     assert(true,"Exceção esperada no metodo testeQtdeFilhosFalho");	
   else{
     fail("Exceção nao esperada no método testeQtdeFilhosFalho");
   }
 }	

}
É mais trabalhoso, mais teste por teste, cada método seu tem que fazê-lo de forma ÚNICA ;)

[code]

louds

Bom, eu acho que a parte importante é o unit test testar somente a classe que ele se dispoe e teste tudo, o resto é gosto.

Eu costumo também criar testes por cenario quando existe acoplamento temporal entre os métodos.

E testes de integração? Para testar se classes A e B funcionam direito em conjunto? Nomeio a classe AxBTest, os métodos ficam com a mesma forma que os unitarios.

Criado 28 de março de 2005
Ultima resposta 28 de mar. de 2005
Respostas 5
Participantes 5