Competição de Teste de Unidade


12

Meus empregadores realizam uma competição mensal de testes unitários. Um dia inteiro é dedicado a escrever testes de unidade - obviamente, fazemos mais testes ao longo do mês, mas este é um dia inteiro - e o "vencedor" da competição recebe um prêmio. No entanto, estamos descobrindo que é difícil determinar quem é o vencedor.

Estávamos atribuindo pontos para cada caso de teste. Então, se você escreveu um teste de unidade como este ...

for (int i = 0; i < 100; i++) {
  assertTrue(i*i, square(i));
}

você receberia 100 pontos. Obviamente, este é um exemplo simplista, mas demonstra os problemas ao atribuir "pontos" a cada caso de teste.

Somos principalmente uma loja Java e Javascript. Então, sugeri contar o número de ramificações de código testadas como uma métrica. Podemos contar facilmente as ramificações testadas por meio de uma ferramenta de cobertura de código (como EclEmma). No entanto, não tenho certeza de como faríamos isso com nossos testes Selenium e obter uma cobertura de código nas fontes Javascript (alguma idéia?)

Alguém tem alguma sugestão sobre como podemos determinar melhor o vencedor desta competição?

Editar

Sei como escrever testes de unidade, sei como escrever testes de unidade eficazes, não preciso de ajuda para determinar o que testar. Não tenho controle sobre essa competição - a competição continuará. Então, ou adiciono alguma informação para melhorar ou continuo jogando os testes (sim, eu jogo com eles. É claro que eu jogo com eles. Há prêmios a serem ganhos)

Editar

Essa pergunta aqui obviamente não é duplicada, embora contenha informações úteis sobre como encontrar bons casos de teste, ela não fornece métricas úteis para avaliar a concorrência.


Nem tanto. Eu percebi que desde o início
Shaun

2
Você ainda não parece ter percebido toda a extensão. Qualquer medida de quem escreveu os melhores casos de teste será completamente subjetiva ou terá esses problemas até certo ponto. Qual métrica funciona melhor dependerá de seus objetivos para essas competições e de quão maduros (isto é, improvável que explorem a pontuação ao invés de escrever os melhores testes que puderem) os competidores são.

Novamente, não. Eu percebi que eles podem ser jogados. Eu não tenho nenhum controle sobre esta competição, mas foi perguntado "como podemos fazer isso melhor"
Shaun

13
Seria uma melhoria não torná-lo uma competição? Por que tudo tem que ser uma competição? Por que você não pode colaborar? Talvez livrar-se de alguns de seus testes de unidade mais inúteis e criar um bom conjunto de testes úteis de fumaça e regressão sejam úteis.
Thomas Owens

1
Estou com Thomas ... o vencedor deve ser o código base / cliente, porque a qualidade do código melhorou. Defina uma meta geral / de grupo com base na cobertura do código dos testes de unidade ... + 5% sobre a corrente ou o que for. ... e não brinque com o sistema de prêmios ... o que aconteceu com um trabalho bem feito é sua própria recompensa?
JeffC

Respostas:


15

Alguém tem alguma sugestão sobre como podemos determinar melhor o vencedor desta competição?

A única coisa que faz sentido para mim é votar - todo desenvolvedor pode atribuir alguns pontos ao teste de qualquer outro desenvolvedor (exceto o seu). Talvez 3 pontos para o teste ele ache que é o "mais eficaz", 2 pontos para o segundo e um para o terceiro. O teste com mais pontos vence. Pode dar melhores resultados quando a atribuição de pontos é feita sem saber de antemão quem escreveu o teste específico.

Como bônus, você receberá todos os seus testes revisados ​​por pares.


2
Este foi o meu pensamento também. Não há outra maneira de medir o valor dos testes.
Eric King

2
Sim, "bom teste" é uma coisa tão subjetiva que precisa ser considerada para julgamento, seja por colegas ou por autoridades respeitadas. A busca de métricas levará a muito esforço desperdiçado e pouco valor real. Pode ser interessante ter vários prêmios: teste mais imaginativo, um prêmio "testando algo anteriormente considerado não testável", teste de melhor desempenho, teste mais eficaz, teste mais obscuro, teste mais inteligente, teste mais valioso, teste que provavelmente será apreciado pelos usuários finais ...
timday

6

Então, se você escreveu um teste de unidade como este ...

for (int i = 0; i < 100; i++) {
 assertTrue(i*i, square(i));
}

você receberia 100 pontos.

Eu daria a essa pessoa 0 pontos (mesmo que o teste estivesse testando algo realmente relevante), porque afirmações dentro de um loop fazem pouco sentido e testes com várias afirmações (especialmente na forma de um loop ou mapa) são difíceis de trabalhar.

O problema é essencialmente ter uma métrica que não pode [facilmente] ser enganada. Uma métrica baseada exclusivamente no número de afirmações é exatamente o mesmo que pagar aos desenvolvedores por LOC gravado. Tal como acontece com o pagamento por LOC, que leva a códigos enormes e impossíveis de manter, a política real da empresa leva a testes inúteis e possivelmente mal escritos.

Se o número de afirmações é irrelevante, o número de testes também é irrelevante. Esse também é o caso de muitas métricas (incluindo as combinadas) que se poderia imaginar para esse tipo de situação.

Idealmente, você aplicaria uma abordagem sistêmica. Na prática, isso quase não funciona na maioria das empresas de desenvolvimento de software. Então, eu posso sugerir algumas outras coisas:

  1. Usando revisões de pares para testes e ter algo semelhante ao número de WTFs por minuto métrica.

  2. Meça o impacto desses testes ao longo do tempo no número de bugs . Isso tem vários benefícios:

    • Parece justo,
    • Na verdade, pode ser medido se você coletar dados suficientes sobre relatórios de bugs e seu destino,
    • Realmente vale a pena!
  3. Use a cobertura da filial , mas combine-a com outras métricas (além de uma revisão). A cobertura das agências tem seus benefícios, mas testar o código CRUD apenas para obter uma nota melhor não é a melhor maneira de gastar o tempo dos desenvolvedores.

  4. Decida todos juntos quais são as métricas que você deseja aplicar no momento (essas decisões podem não ser bem-vindas ou até mesmo possíveis em algumas empresas e equipes). Revise e altere as métricas com frequência, escolhendo aquelas que se tornam mais relevantes e verifique se todos entendem claramente o que é medido e como.


1
+1 para zero pontos. Outras objeções seriam AAA - Organizar, Agir, Afirmar; Testes parametrizados; Nenhuma cópia do código da aplicação ...
thepacker

5

Suponho que seu empregador organize esse dia de testes unitários para incentivar as pessoas a encontrar bugs, obter maior cobertura de código e também acabar tendo mais testes, que serão úteis para sempre.

Então, eu acho que faria sentido que o vencedor fosse o desenvolvedor que encontrar mais erros, ou o desenvolvedor cujos testes obtiverem o maior aumento na cobertura do código.

Um teste lhe dará um ponto se fizer com que uma nova entrada seja aberta no seu sistema de rastreamento de problemas / bugs / defeitos. Se uma entrada já estiver aberta para esse problema, ela não conta. Além disso, conforme sugerido nos comentários, erros no seu próprio código não contam; apenas erros no código de outras pessoas devem contar. Infelizmente, essa abordagem não oferece gratificação instantânea, pois pode levar alguns dias até que todos os testes com falha sejam analisados ​​e os problemas correspondentes sejam abertos. Além disso, isso nem sempre funciona; À medida que o sistema amadurece, pode começar a se tornar extremamente raro descobrir erros adicionando testes.

O aumento na cobertura do código pode fornecer uma medida mais objetiva da melhoria representada pelos novos testes. Primeiro, a cobertura total do código deverá ser registrada no dia anterior à competição. Em seguida, cada desenvolvedor precisará mostrar, de alguma forma, o aumento na cobertura de código resultante apenas de seus testes, sem levar em conta o aumento na cobertura de código resultante de testes escritos por outros desenvolvedores. Isso significa que você provavelmente precisará de um árbitro que irá à máquina de cada desenvolvedor e registrará a nova cobertura de código antes que os testes sejam realizados.

Aliás, levar em consideração a cobertura do código oferece uma recompensa justa para as pessoas que escrevem testes reais, em vez de fazer coisas tolas como o exemplo que você forneceu na pergunta.


2
Parece promissor ... mas o comportamento de "jogar o sistema" se transforma em uma bela coleção de bugs conhecidos apenas por você para serem "descobertos" na próxima competição de testes ... dilbert.com/strip/1995-11 -13
timday 02/06

3
Uma opção é atribuir pontos apenas por erros no código que outra pessoa escreveu.
Cel Skeggs


@ col6y você está certo, isso é muito importante também. Infelizmente, ainda existem maneiras de manipular o sistema. Por exemplo, se o seu código chama o meu código para concluir seu trabalho, ele pode garantir que seu código sofra um "acidente".
precisa

3
Discordo. Os testes de unidade, quando recém-gravados, não são para encontrar bugs , isso é uma falácia. Eles podem encontrar regressões semanas ou meses após serem escritos, mas provavelmente é tarde demais para fornecer uma métrica útil para a competição. Você normalmente escreve um teste de unidade após a ocorrência de um bug específico para garantir que não receberá o mesmo tipo de bug posteriormente no futuro.
Doc Brown
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.