Concours de tests unitaires

12

Mes employeurs organisent un concours mensuel de tests unitaires. Une journée entière est consacrée à la rédaction des tests unitaires - nous faisons évidemment plus de tests tout au long du mois, mais c'est une journée entière - et le "gagnant" du concours reçoit un prix. Cependant, nous trouvons qu'il est difficile de déterminer qui est le gagnant.

Nous attribuions des points pour chaque cas de test. Donc, si vous avez écrit un test unitaire comme celui-ci ...

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

vous obtiendrez 100 points. Évidemment, il s'agit d'un exemple simpliste, mais il montre les problèmes liés à l'attribution de "points" à chaque scénario de test.

Nous sommes principalement une boutique Java et Javascript. J'ai donc suggéré de compter le nombre de branches de code testées en tant que métrique. Nous pouvons facilement compter les branches testées via un outil de couverture de code (comme EclEmma). Cependant, je ne sais pas comment nous ferions cela avec nos tests Selenium et obtenir une couverture de code sur les sources Javascript (des idées?)

Quelqu'un a-t-il des suggestions sur la façon dont nous pourrions mieux déterminer le gagnant de ce concours?

Éditer

Je sais comment écrire des tests unitaires, je sais comment écrire des tests unitaires efficaces, je n'ai pas besoin d'aide pour déterminer quoi tester. Je n'ai aucun contrôle sur cette compétition - la compétition continuera. Donc, soit j'ajoute une contribution pour l'améliorer, soit je continue à jouer aux tests (oui, je les joue. Bien sûr que je les joue. Il y a des prix à gagner)

Éditer

Cette question ici est évidemment pas un doublon, mais il contient des informations utiles sur la façon de trouver de bons cas de test, il ne fournit pas de mesures utiles pour évaluer la concurrence.

Shaun
la source
Pas assez. Je l'ai réalisé dès le début
Shaun
2
Vous ne semblez pas encore tout à fait réaliser toute l'étendue. Toute mesure de qui a écrit les meilleurs cas de test sera soit complètement subjective ou aura ces problèmes dans une certaine mesure. La métrique qui fonctionnera le mieux dépendra de vos objectifs pour ces compétitions et de la maturité (c'est-à-dire, peu probable d'exploiter le score plutôt que d'écrire les meilleurs tests possibles) des candidats.
Encore une fois, non. J'ai réalisé qu'ils peuvent être joués. Je n'ai aucun contrôle sur cette compétition mais on m'a demandé "comment pouvons-nous faire mieux"
Shaun
13
Serait-ce considéré comme une amélioration pour ne pas en faire un concours? Pourquoi tout doit-il être une compétition? Pourquoi ne pouvez-vous pas collaborer? Il serait peut-être utile de se débarrasser de certains de vos tests unitaires plus inutiles et de créer une belle suite de tests de fumée et de régression utiles.
Thomas Owens
1
Je suis avec Thomas ... le gagnant devrait être la base de code / client car la qualité du code s'est améliorée. Fixez un objectif global / de groupe basé sur la couverture du code des tests unitaires ... + 5% par rapport au courant ou autre. ... et ne jouez pas le système pour les prix ... ce qui est arrivé à un travail bien fait est sa propre récompense?
JeffC

Réponses:

15

Quelqu'un a-t-il des suggestions sur la façon dont nous pourrions mieux déterminer le gagnant de ce concours?

La seule chose qui a du sens pour moi est de voter - chaque développeur peut attribuer certains points au test de chaque autre développeur (sauf le sien). Peut-être 3 points pour le test, il pense que c'est le "plus efficace", 2 points pour le second et un pour le troisième. Le test avec le plus de points gagne. Il peut donner de meilleurs résultats lorsque l'attribution des points est effectuée sans savoir au préalable qui a écrit le test en question.

En prime, vous obtiendrez tous vos tests évalués par les pairs.

Doc Brown
la source
2
C'était aussi ma pensée. Il n'y a pas d'autre moyen de mesurer la valeur des tests.
Eric King
2
Oui, un «bon test» est une chose si subjective qu'il faut en juger, soit par des pairs, soit par des autorités respectées. La poursuite des mesures entraînera juste beaucoup d'efforts gaspillés et peu de valeur réelle. Il pourrait être intéressant d'avoir plusieurs prix: le test le plus imaginatif, le prix "tester quelque chose qui était auparavant considéré comme non testable", le meilleur test de performance, le test le plus efficace, le test le plus obscur, le test le plus intelligent, le test le plus précieux, le test le plus susceptible d'être apprécié par les utilisateurs finaux ...
jeudi
6

Donc, si vous avez écrit un test unitaire comme celui-ci ...

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

vous obtiendrez 100 points.

Je donnerais à cette personne 0 points (même si le test testait quelque chose de réellement pertinent), car les assertions dans une boucle n'ont pas de sens et les tests avec plusieurs assertions (en particulier sous la forme d'une boucle ou d'une carte) sont difficiles à travailler.

Le problème est essentiellement d'avoir une métrique qui ne peut pas [facilement] être trichée. Une métrique qui est exclusivement basée sur le nombre d'assertions est exactement la même que les développeurs payants par LOC écrit. Comme avec le paiement par LOC qui conduit à un code énorme et impossible à maintenir, la politique actuelle de votre entreprise conduit à des tests inutiles et éventuellement mal écrits.

Si le nombre d'assertions n'est pas pertinent, le nombre de tests l'est également. C'est également le cas pour de nombreuses métriques (y compris les métriques combinées) que l'on pourrait imaginer pour ce genre de situations.

Idéalement, vous appliqueriez une approche systémique. En pratique, cela peut difficilement fonctionner dans la plupart des sociétés de développement de logiciels. Je peux donc suggérer quelques autres choses:

  1. Utiliser des revues de paires pour les tests et avoir quelque chose de similaire au nombre de WTF par minute métrique.

  2. Mesurez l'impact de ces tests au fil du temps sur le nombre de bugs . Cela présente plusieurs avantages:

    • Semble juste,
    • Peut en fait être mesuré si vous collectez suffisamment de données sur les rapports de bogues et leur sort,
    • Ça vaut vraiment le coup!
  3. Utilisez la couverture des succursales , mais combinez-la avec d'autres mesures (ainsi qu'une révision). La couverture des succursales a ses avantages, mais tester le code CRUD juste pour obtenir une meilleure note n'est pas la meilleure façon de passer le temps des développeurs.

  4. Décidez ensemble quelles sont les mesures que vous souhaitez appliquer pour le moment (de telles décisions peuvent ne pas être les bienvenues ou même être possibles dans certaines entreprises et équipes). Examinez et modifiez souvent les mesures, en sélectionnant celles qui deviennent plus pertinentes et assurez-vous que tout le monde comprend clairement ce qui est mesuré et comment.

Arseni Mourzenko
la source
1
+1 pour zéro point. D'autres objections seraient AAA - Arrange, Act, Assert; Tests paramétrés; Pas de copie du code de l'implémentation ...
thepacker
5

Je suppose que votre employeur organise cette journée de tests unitaires afin d'inciter les gens à trouver des bogues, à obtenir une plus grande couverture de code et à finir par avoir plus de tests, qui sont utiles pour toujours.

Donc, je pense qu'il serait logique que le gagnant soit le développeur qui trouve le plus de bogues ou le développeur dont les tests atteignent la plus grande augmentation de la couverture de code.

Un test vous rapportera un point s'il entraîne l'ouverture d'une nouvelle entrée dans votre système de suivi des problèmes / bogues / défauts. Si une entrée est déjà ouverte pour ce problème, elle ne compte pas. De plus, comme suggéré dans les commentaires, les bogues dans votre propre code ne comptent pas; seuls les bogues dans le code des autres devraient compter. Malheureusement, cette approche ne fournit pas de satisfaction instantanée car cela peut prendre quelques jours avant que tous les tests ayant échoué soient passés au crible et que les problèmes correspondants soient ouverts. En outre, cela peut ne pas toujours fonctionner; à mesure que votre système mûrit, il peut devenir extrêmement rare de découvrir des bogues en ajoutant des tests.

L'augmentation de la couverture du code pourrait fournir une mesure plus objective de l'amélioration représentée par les nouveaux tests. Tout d'abord, la couverture totale du code devra être enregistrée la veille de la compétition. Ensuite, chaque développeur devra montrer en quelque sorte l'augmentation de la couverture de code qui résulte de ses seuls tests, sans tenir compte de l'augmentation de la couverture de code résultant des tests écrits par d'autres développeurs. Cela signifie que vous aurez probablement besoin d'un arbitre qui se rendra sur la machine de chaque développeur et enregistrera la nouvelle couverture de code avant que les tests de quiconque ne soient validés.

Soit dit en passant, la prise en compte de la couverture du code offre une récompense équitable aux personnes qui écrivent de vrais tests, au lieu de faire des choses idiotes comme l'exemple que vous avez fourni dans la question.

Mike Nakis
la source
2
Cela semble prometteur ... mais le comportement de "jouer au système" se transforme en vous alignant une belle collection de bugs connus de vous-mêmes à "découvrir" lors de la prochaine compétition de tests ... dilbert.com/strip/1995-11 -13
jeudi
3
Une option consiste à attribuer uniquement des points pour les bogues dans le code que quelqu'un d'autre a écrit.
Cel Skeggs
@ col6y vous avez raison, c'est très important aussi. Malheureusement, il existe encore des moyens de truquer le système. Par exemple, si votre code invoque mon code pour faire son travail, mon code pourrait faire en sorte que votre code subisse un "accident".
Mike Nakis
3
Je ne suis pas d'accord. Les tests unitaires, lorsqu'ils sont nouvellement écrits, ne sont pas destinés à trouver des bogues en premier lieu , c'est une erreur. Ils peuvent trouver des régressions des semaines ou des mois après avoir été écrits, mais c'est probablement trop tard pour fournir des mesures utiles pour la compétition. Vous écrivez généralement un test unitaire après qu'un bug spécifique s'est produit pour vous assurer que vous n'obtiendrez pas le même type de bug plus tard dans le futur.
Doc Brown