No meu projeto atual, estou tendo dificuldades para encontrar uma boa solução para criar testes de integração escaláveis que não tenham efeitos colaterais. Um pequeno esclarecimento sobre a propriedade livre de efeitos colaterais: é principalmente sobre o banco de dados; não deve haver nenhuma alteração no banco de dados após a conclusão dos testes (o estado deve ser preservado). Talvez a escalabilidade e a preservação do estado não se combinem, mas eu realmente quero buscar uma solução melhor.
Aqui está um teste de integração típico (esses testes tocam a camada do banco de dados):
public class OrderTests {
List<Order> ordersToDelete = new ArrayList<Order>();
public testOrderCreation() {
Order order = new Order();
assertTrue(order.save());
orderToDelete.add(order);
}
public testOrderComparison() {
Order order = new Order();
Order order2 = new Order();
assertFalse(order.isEqual(order2);
orderToDelete.add(order);
orderToDelete.add(order2);
}
// More tests
public teardown() {
for(Order order : ordersToDelete)
order.delete();
}
}
Como se pode imaginar, essa abordagem produz testes extremamente lentos. E, quando aplicado a todos os testes de integração, leva cerca de 5 segundos para testar apenas uma pequena parte do sistema. Eu posso imaginar esse número aumentando quando a cobertura é aumentada.
Qual seria outra abordagem para escrever esses testes? Uma alternativa em que posso pensar é ter variáveis globais (dentro de uma classe) e todos os métodos de teste compartilham essa variável. Como resultado, apenas alguns pedidos são criados e excluídos; resultando em testes mais rápidos. No entanto, acho que isso apresenta um problema maior; os testes não são mais isolados e fica cada vez mais difícil entendê-los e analisá-los.
Pode ser que os testes de integração não sejam executados com a mesma frequência que os testes de unidade; portanto, baixo desempenho pode ser aceitável para eles. De qualquer forma, seria ótimo saber se alguém encontrou alternativas para melhorar a escalabilidade.