Meu trabalho atual é principalmente escrever código de teste da GUI para vários aplicativos em que trabalhamos. No entanto, acho que tenho a tendência de copiar e colar muito código nos testes. A razão para isso é que as áreas que estou testando tendem a ser semelhantes o suficiente para precisar de repetição, mas não o bastante para encapsular o código em métodos ou objetos. Acho que, quando tento usar classes ou métodos de forma mais abrangente, os testes se tornam mais difíceis de manter e, às vezes, difíceis de escrever em primeiro lugar.
Em vez disso, costumo copiar um grande pedaço de código de teste de uma seção e colá-lo em outra e fazer pequenas alterações necessárias. Não uso maneiras mais estruturadas de codificação, como usar mais princípios ou funções de OO.
Outros codificadores se sentem assim ao escrever o código de teste? Obviamente, quero seguir os princípios DRY e YAGNI, mas acho que o código de teste (código de teste automatizado para testes de GUI de qualquer maneira) pode dificultar o cumprimento desses princípios. Ou eu só preciso de mais prática de codificação e um sistema geral melhor de fazer as coisas?
EDIT: A ferramenta que estou usando é o SilkTest, que está em uma linguagem proprietária chamada 4Test. Além disso, esses testes são principalmente para aplicativos de área de trabalho do Windows, mas eu também testei aplicativos da web usando essa configuração também.
fonte
Respostas:
Casos de teste colados e depois editados geralmente são bons.
Os testes devem ter o menor número possível de dependências externas e ser o mais direto possível. Os casos de teste tendem a mudar com o tempo, e casos de teste anteriormente quase idênticos podem divergir repentinamente. Atualizar um caso de teste sem ter que se preocupar em quebrar outros casos é uma coisa boa.
Obviamente, o código padrão , que é idêntico em muitos casos de teste e precisa mudar de concerto, pode e deve ser fatorado.
fonte
Repetição é a raiz de todo mal
Isso está certo! A repetição é a raiz de todo mal . Provavelmente foi Knuth dizendo em seu livro "Otimização prematura é a raiz de todo mal", mas acho que é repetição.
Sempre que você olha para um programa ou escreve um e descobre algum tipo de repetição: Remova-o! Mate-o imediatamente ... qualquer coisa, exceto se livrar dele !
Cada vez que introduzi algum tipo de repetição e tive que corrigir um bug, esqueci de corrigir a réplica ... (Donald Knuth) Então, sempre que houver uma repetição, remova-a da melhor maneira possível, não hackear !
Pense em um design enxuto limpo (como encapsular seus blocos de código repetidos nas classes auxiliares) e escreva alguns testes antes de alterar alguma coisa (apenas para ter certeza de que você não quebrou alguma coisa). Isso é verdade para qualquer parte do código gravada e os códigos de teste não são excepção.
Aqui está uma boa leitura do Code Horror que me inspira - Uma Proposta Modesta para a Escola de Reutilização de Copiar e Colar .
fonte
Ainda é muito ruim cortar e colar. Há alguns problemas.
Seus testes podem ser frágeis, porque você está vulnerável a algo que requer uma alteração em todo esse código copiado e colado. Você terá que reescrever todos os testes?
Se você não pode encapsular a lógica em métodos auxiliares fora de seus testes, não poderá escrever testes desses métodos auxiliares. Escrever testes de métodos de teste geralmente é muito difícil de valer a pena, pois você precisa quebrar seu código para testar o teste. Mas você pode métodos auxiliares de teste de unidade.
Pode muito bem tornar os testes menos legíveis. Um grande bloco de código copiado pode ser mais difícil de ler do que um método de chamada para auxiliar com um nome descritivo.
Tudo o que listei é algo que pode ser um problema. Se você achar que nenhum deles é realmente um problema, é claro que tudo bem.
fonte
Eu costumava concordar com você. Mas então, com o tempo, descobri que todas as alterações que eu fazia (principalmente as alterações de DI nos testes de unidade) exigiam vários testes para mudar, o que era complicado. Agora, assino a escola de DRY, mesmo quando faço testes.
Para teste da GUI, convém examinar o padrão PageObject para reduzir o código repetido.
fonte
Eu recomendaria pegar padrões XUnit. Eu costumava ter exatamente o mesmo problema até começar a alavancar esse livro. O padrão Mãe do Objeto parece ser o mais útil para o seu cenário.
Como alguém mencionado, encapsular adequadamente esse código de instalação pode ser oneroso, mas ter que alterá-lo em todos os lugares que você copia e cola é ainda mais.
fonte
Object Mother pattern
código de inicialização comum.As pessoas devem tentar limitar a repetição quando podem - sim. Mas a recompensa depende da situação. Isso poderia voltar ao debate sobre "melhores práticas". Mas a questão é o que é melhor para você nessa situação. Há exceções para todas as regras.
Algumas coisas que eu gostaria de perguntar são: 1) Qual a probabilidade de que essa funcionalidade sendo testada no UAT seja alterada? Se for improvável que isso mude, há menos chances de que você precise atualizar cada um de seus conjuntos de códigos. 2) Se houver uma alteração no UAT, ele sempre afetará cada conjunto do código copiado ou somente um ou dois conjuntos? Se puder ser isolado e exigir apenas uma alteração em um conjunto, pode ser útil separar as coisas. 3) Quão complexo será o método inicial se você tentar fazer com que ele lide com todos os cenários? Você está adicionando muitos if / else / loops aninhados? Se você começar a exagerar toda a ramificação, poderá acabar com um código difícil de compreender. Seria mais fácil fazer a atualização em cada um dos textos copiados do que revisitar toda a lógica de ramificação?
Se você está preso copiar / colar / alterar, acho que você gostaria de adicionar comentários como 'Isso é copiado no método xyz'. Dessa forma, você será lembrado para atualizar todas as versões coladas do código. Ou (vindo de outro usuário do SilkTest), você pode adicionar um arquivo inc separado que se concentre apenas nesse código repetido. Dessa forma, você tem todas as variações em um só lugar e pode ver facilmente os diferentes métodos que exigiriam atualização.
fonte
Um grande procedimento
Um pensamento: parece que você está tentando evitar código cut-n-paste, criando métodos como:
Muitos pequenos procedimentos (kit de ferramentas)
Você também considerou a abordagem oposta? Em vez de passar um milhão de parâmetros para um grande procedimento testScreen (), talvez faça sua própria estrutura ou kit de ferramentas com pequenos procedimentos auxiliares que você escolhe conforme necessário. Gostar:
Você ainda recorta e cola esses procedimentos em todas as telas, mas está recortando e colando pedaços menores de código e criando pedaços comuns que não são recortados e colados (o conteúdo de cada pequeno procedimento).
Copiar e colar
O único momento em que o código recortado e colado não me picou foi quando o código foi jogado fora antes que eu tivesse que alterá-lo. Minha maior preocupação com os testes de interface do usuário é a rapidez com que eles se tornam obsoletos. Se você descobrir que joga todo o seu código fora antes de alterá-lo, talvez tenha encontrado um nicho em que recortar e colar está OK! Além disso, não é tão ruim quando não há código a jusante do código recortado e colado (por exemplo, na interface do usuário de um aplicativo). Se você estiver colando mais de três linhas, eu realmente gostaria de fazer algo sobre isso. Pelo menos tome medidas para minimizá-lo!
Teste de UI automatizado
Caramba, se você puder provar maior produtividade com testes automatizados de interface do usuário do que com testes manuais, usando qualquer técnica (o custo de escrever / manter testes automatizados é menor do que testar manualmente todas as vezes, mas a qualidade é a mesma). Acho que você deveria escrever um artigo. Eu leria! Agora posso ver o título "Recortar e colar código uma vitória líquida para testes de interface do usuário!"
fonte
Realmente não é tão ruim assim. De fato, se você descobrir que certos padrões de código estão sendo usados com muita frequência e as alterações são muito rotineiras (como algumas seqüências de caracteres ou valores de parâmetros), você pode até escrever um gerador de código que gere código de teste repetitivo com base em um pequeno (- ish?) lista de entrada de valores que mudam. Eu fiz isso (código de teste gerado) várias vezes, usando arquivos em lotes, scripts SQLPlus e até macros do Excel (parece feio, mas as variáveis para os diferentes scripts de teste já estavam em uma planilha) e isso pode economizar muito tempo . O fato é que, se alguma coisa mudar na estrutura geral do código do caso de teste repetitivo, você poderá gerar novamente o que precisar.
fonte
É o mesmo que a maioria das outras respostas, mas de uma maneira que um gerente não técnico possa entender.
Imagine o seguinte cenário de erro:
O que você vai fazer?
Da minha experiência:
Ao introduzir testes automatizados, o gerenciamento gosta de "copiar e colar-testes": você realiza muitos testes em pouco tempo.
Após alguns dos "cenários de erro", o gerenciamento prefere (4) porque a correção de "copiar e colar-testes" é muito cara.
Faça certo em primeiro lugar (3) não será tão rápido, mas aumenta as chances de os testes sobreviverem
fonte