Estou investigando técnicas e estratégias para dimensionar nosso crescente número de testes de integração em nosso produto atual, para que eles possam (humanamente) permanecer parte de nosso desenvolvimento e processo de IC.
Em mais de 200 testes de integração, já estamos atingindo a marca de 1 hora para concluir uma execução de teste completa (em uma máquina de desenvolvimento de desktop), e isso está afetando negativamente a capacidade de um desenvolvedor de tolerar a execução de todo o conjunto como parte dos processos rotineiros de envio. O que está afetando a motivação para ser disciplinado sobre como criá-los bem. Testamos a integração apenas dos principais cenários frente a frente e usamos um ambiente que reflete a produção, construído do zero a cada execução de teste.
Por causa do tempo necessário para executar, está gerando um loop de feedback terrível e muitos ciclos desperdiçados aguardando que as máquinas concluam as execuções de teste, não importa o quão focadas sejam as execuções de teste. Não importa o impacto negativo mais caro no fluxo e progresso, sanidade e sustentabilidade.
Esperamos ter 10 vezes mais testes de integração antes que esse produto comece a desacelerar (não faço ideia, mas não parece que ainda estamos começando em termos de recursos). Temos que esperar razoavelmente estar em algumas centenas ou milhares de testes de integração, eu acho que em algum momento.
Para ser claro, tente impedir que isso se torne uma discussão sobre teste de unidade versus teste de integração (que nunca deve ser negociado). Estamos fazendo os dois testes de unidade com TDD E testes de integração neste produto. De fato, fazemos testes de integração nas várias camadas da arquitetura de serviços que possuímos, onde faz sentido para nós, pois precisamos verificar onde introduzimos alterações de última hora ao alterar os padrões em nossa arquitetura para as outras áreas do sistema.
Um pouco sobre a nossa pilha de tecnologia. Atualmente, estamos testando em um ambiente de emulação (CPU e memória intensiva) para executar nossos testes de ponta a ponta. Que é composto pelos serviços Web REST do Azure que enfrentam um back-end noSql (ATS). Estamos simulando nosso ambiente de produção executando no Emulador da área de trabalho do Azure + IISExpress. Estamos limitados a um emulador e um repositório de back-end local por máquina dev.
Também temos um IC baseado na nuvem, que executa o mesmo teste no mesmo ambiente emulado, e as execuções de teste demoram o dobro do tempo (2 horas +) na nuvem com nosso provedor de IC atual. Atingimos os limites do SLA dos provedores de IC na nuvem em termos de desempenho de hardware e excedemos sua permissão no tempo de execução do teste. Para ser justo com eles, suas especificações não são ruins, mas são tão boas quanto uma máquina de desktop suja interna.
Estamos usando uma estratégia de teste para reconstruir nosso armazenamento de dados para cada grupo lógico de testes e pré-carregar com dados de teste. Embora assegure de maneira abrangente a integridade dos dados, isso aumenta de 5 a 15% o impacto em cada teste. Portanto, achamos que há pouco a ganhar com a otimização dessa estratégia de teste neste momento no desenvolvimento do produto.
O longo e o curto é que: embora possamos otimizar o rendimento de cada teste (mesmo que entre 30% e 50% cada), ainda assim não escalaremos efetivamente no futuro próximo com várias centenas de testes. Hoje, mesmo que ainda exceda em muito o que é humanamente tolerável, precisamos de uma ordem de magnitude e magnitude no processo geral para torná-lo sustentável.
Portanto, estou investigando quais técnicas e estratégias podemos empregar para reduzir drasticamente o tempo de teste.
- Escrever menos testes não é uma opção. Vamos, por favor, não debater esse tópico neste tópico.
- Usar hardware mais rápido é definitivamente uma opção, embora seja muito caro.
- A execução de grupos de testes / cenários em hardware separado em paralelo também é definitivamente uma opção preferida.
- Criar um agrupamento de testes em torno de recursos e cenários em desenvolvimento é plausível, mas, em última análise, não é confiável para provar a cobertura total ou a confiança de que o sistema não é afetado por uma alteração.
- A execução em um ambiente de armazenamento temporário em escala na nuvem, em vez de no emulador de desktop, é tecnicamente possível, apesar de começarmos a adicionar tempos de implantação para as execuções de teste (~ 20 minutos cada no início da execução de teste para implantar o material).
- Dividir os componentes do sistema em partes lógicas independentes é plausível até certo ponto, mas esperamos uma quilometragem limitada, pois é esperado que as interações entre os componentes aumentem com o tempo. (ou seja, é provável que uma mudança afete outras pessoas de maneiras inesperadas - como acontece frequentemente quando um sistema é desenvolvido de forma incremental)
Eu queria ver quais estratégias (e ferramentas) outras pessoas estão usando neste espaço.
(Preciso acreditar que outras pessoas possam estar vendo esse tipo de dificuldade ao usar certos conjuntos de tecnologias.))
[Atualização: 16/12/2016: Acabamos investindo mais em testes paralelos de IC, para uma discussão sobre o resultado: http://www.mindkin.co.nz/blog/2015/12/16/16-jobs]