E-Plamtax foi um projeto muito positivo que executamos para a Força Aérea. A equipe do E-Plamtax aprendeu muitas coisas no projeto, mas muitas dessas aprendizagens ficaram guardadas conosco. Uma das mais interessantes é a criação de utilitários de teste.
Utilitários de teste são uma maneira de reaproveitar código em testes unitários. Usualmente, isso é feito utilizando os métodos setUp ou @Before dos casos de teste, mas isso tem algumas desvantagens. Por exemplo, em um caso de teste, podemos ter a seguinte inicialização:
private Address address;
private AddressDAO addressDAO;
@Before
public void setUp() {
address = new Address();
address.setStreet("Rua fulano");
address.setNumber("123/A");
addressDAO = new AddressDAO();
}
Se tivermos um teste com o abaixo essa inicialização funciona bem…
@Test
public void testGetAllAddresses(){
addressDAO.addAddress(address);
List addresses = addressDAO.getAllAddresses();
assertEquals(1, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
Agora, se tivermos o teste abaixo, o objeto criado é desperdiçado:
@Test
public void testGetNoAddress() {
List addresses = addressDAO.getAllAddresses();
assertEquals(0, addresses.size());
}
Se o código for como o seguinte, teremos redundância de código. também temos de decidir SE o outro objeto deve ser criado no @Before também ou no método.
@Test
public void testGetAllAddressesMoreThanOne() {
addressDAO.addAddress(address);
Address address2 = new Address();
address2.setStreet("Outra rua");
address2.setNumber("111");
addressDAO.addAddress(address2);
List addresses = addressDAO.getAllAddresses();
assertEquals(1, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
Esses inconvenientes são menores quando comparados à tarefa de criar as dependências e um objeto para o teste. Por exemplo, para testar uma classe Person que agrega um Address em um outro caso de teste, teremos de ter um @Before semelhante a esse:
private Person person;
private Address address;
private PersonDAO personDAO;
@Before
public void setUp() {
address = new Address();
address.setStreet("Rua fulano");
address.setNumber("123/A");
person = new Person();
person.setName("João");
person.setAddress(address);
personDAO = new PersonDAO();
}
O código para a criação de endereços replicou-se, e é difícil criar as dependências. Nesses exemplos, vemos casos simples, mas é fácil visualizar como a situação irá se complicar.
Nós solucionamos esse problema criando uma classe para criar esses objetos. Essa classe seria algo como isso:
public class TestUtil {
public static Address utilCreateAddress(String street, String number) {
Address address = new Address();
address.setStreet("Rua fulano");
address.setNumber("123/A");
return address;
}
public static Person utilCreatePerson(String name, Address address) {
Person person = new Person();
person.setName(name);
person.setAddress(address);
return person;
}
}
Nossos casos de teste estendiam a TestUtil, facilitando a criação de objetos:
public class TestAddress2 extends TestUtil {
private AddressDAO addressDAO = new AddressDAO();
@Test
public void testGetAllAddresses() {
Address address = utilCreateAddress("Rua fulano", "123/A");
addressDAO.addAddress(address);
List addresses = addressDAO.getAllAddresses();
assertEquals(1, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
@Test
public void testGetNoAddress() {
List addresses = addressDAO.getAllAddresses();
assertEquals(0, addresses.size());
}
@Test
public void testGetAllAddressesMoreThanOne() {
Address address = utilCreateAddress("Rua fulano", "123/A");
Address address2 = utilCreateAddress("Outra rua", "111");
addressDAO.addAddress(address);
addressDAO.addAddress(address2);
List addresses = addressDAO.getAllAddresses();
assertEquals(2, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
}
Como também precisávamos frequentemente de um objeto qualquer, ou que apenas um ou outro parâmetro fosse definido, criávamos variantes dos métodos:
public static Address utilCreateAddress() {
return utilCreateAddress("Qualquer", "Qualquer");
}
public static Person utilCreatePerson() {
return utilCreatePerson("José", utilCreateAddress());
}
O E-Plamtax foi um projeto um tanto complexo, com grandes redes de dependências de objetos. O uso desses utilitários de teste viabilizou a prática de TDD no sistema. Era emocionante descobrir que, para criar aquele documento que dependia de sete outros documentos e uns cinco ou seis usuários, bastava chamar um método :)
Naturalmente, há mais sobre nossos utilitários de teste do que foi escrito aqui, e pode haver mais ainda que sequer fizemos. (Por exemplo, pode ser interessante produzir utilitários de teste para classes específicas, ao invés de um gigantesco utilitário) Entretanto, como a ideia é bem simples, esperamos que esse pontapé inicial lhe motive a pensar sobre o tema. Até mais!






.png)


.jpg)

















.png)




