Mon travail actuel consiste principalement à écrire du code de test GUI pour diverses applications sur lesquelles nous travaillons. Cependant, je trouve que j'ai tendance à copier et coller beaucoup de code dans les tests. La raison en est que les zones que je teste ont tendance à être assez similaires pour nécessiter une répétition mais pas assez similaires pour encapsuler du code dans des méthodes ou des objets. Je trouve que lorsque j'essaie d'utiliser plus largement les classes ou les méthodes, les tests deviennent plus lourds à maintenir et parfois carrément difficiles à écrire en premier lieu.
Au lieu de cela, je copie généralement un gros morceau de code de test d'une section et le colle dans une autre, et j'apporte les modifications mineures dont j'ai besoin. Je n'utilise pas de méthodes de codage plus structurées, telles que l'utilisation de plus de principes ou de fonctions OO.
Les autres codeurs se sentent-ils ainsi lors de l'écriture du code de test? Évidemment, je veux suivre les principes DRY et YAGNI, mais je trouve que le code de test (code de test automatisé pour les tests GUI de toute façon) peut rendre ces principes difficiles à suivre. Ou ai-je juste besoin de plus de pratique de codage et d'un meilleur système global de faire les choses?
EDIT: L'outil que j'utilise est SilkTest, qui est dans un langage propriétaire appelé 4Test. De plus, ces tests concernent principalement les applications de bureau Windows, mais j'ai également testé des applications Web à l'aide de cette configuration.
la source
Réponses:
Les scénarios de test copiés-collés puis modifiés sont souvent corrects.
Les tests doivent avoir le moins de dépendances externes possible et être aussi simples que possible. Les cas de test ont tendance à changer avec le temps et des cas de test auparavant presque identiques peuvent soudainement diverger. Mettre à jour un cas de test sans avoir à se soucier de casser d'autres cas est une bonne chose.
Bien sûr, le code passe-partout qui est identique dans de nombreux cas de test et doit changer de concert peut et doit être éliminé.
la source
La répétition est la racine de tout mal
C'est vrai! La répétition est la racine de tout mal . C'était probablement Knuth qui disait dans son livre «L'optimisation prématurée est la racine de tout mal», mais je pense que c'est la répétition.
Chaque fois que vous regardez un programme ou que vous en écrivez un et que vous découvrez une sorte de répétition: supprimez-le! Tuez-le immédiatement… peu importe, mais débarrassez-vous-en !
Chaque fois que j'introduisais une sorte de répétition et que je devais corriger un bogue là-dedans, j'oubliais de corriger la réplique ... (Donald Knuth) Donc, chaque fois qu'il y a une répétition, supprimez-la du mieux que vous pouvez, ne piratez pas !
Pensez à une conception allégée propre (comme encapsuler vos blocs de code répétitifs dans des classes d'assistance) et écrivez quelques tests avant de changer quelque chose (juste pour être sûr que vous n'avez pas cassé quelque chose). Cela est vrai pour tout morceau de code écrit et les codes de test ne font pas exception.
Voici une bonne lecture de Code Horror qui m'inspire - Une proposition modeste pour l'école du copier-coller de la réutilisation du code .
la source
Il est encore assez mal de couper et coller. Il y a quelques problèmes.
Vos tests peuvent être fragiles, car vous êtes vulnérable à quelque chose qui nécessite une modification de tout ce code copié-collé. Aurez-vous à réécrire tous les tests?
Si vous ne pouvez pas encapsuler la logique dans des méthodes d'assistance en dehors de vos tests, vous ne pouvez pas écrire les tests de ces méthodes d'assistance elles-mêmes. Il est généralement difficile de rédiger des tests de méthodes de test, car vous devez casser votre code pour tester le test. Mais vous pouvez tester les méthodes auxiliaires de test unitaire.
Cela pourrait bien rendre les tests moins lisibles. Un gros bloc de code copié peut être plus difficile à lire qu'un appel à la méthode d'assistance avec un nom descriptif.
Tout ce que j'ai énuméré peut être un problème. Si vous trouvez aucun d'entre eux en fait sont un problème, bien sûr , il va bien.
la source
J'étais d'accord avec toi. Mais ensuite, au fil du temps, j'ai trouvé que chaque changement que j'apportais (en particulier les changements DI dans les tests unitaires) nécessitait de nombreux tests pour changer et c'était lourd. Maintenant je m'inscris à l'école de DRY, même lors des tests.
Pour les tests GUI, vous souhaiterez peut-être examiner le modèle PageObject pour réduire le code répété.
la source
Je recommanderais de choisir des modèles XUnit. J'ai eu exactement le même problème jusqu'à ce que je commence à tirer parti de ce livre. Le motif Object Mother semble être le plus utile pour votre scénario.
Comme quelqu'un d'autre l'a mentionné, l'encapsulation correcte de ce code d'installation peut être onéreuse, mais devoir le changer à tous les endroits que vous copiez et collez l'est encore plus.
la source
Object Mother pattern
code d'initialisation commun.Les gens devraient-ils essayer de limiter la répétition quand ils le peuvent - oui. Mais le gain dépend de la situation. Cela pourrait revenir au débat sur les «meilleures pratiques». Mais la question est de savoir ce qui vous convient le mieux dans cette situation. Il existe des exceptions à chaque règle.
Voici quelques questions que je poserais: 1) Quelle est la probabilité que cette fonctionnalité testée dans l'UAT change? S'il est peu probable que cela change, il y a moins de chances que vous deviez mettre à jour chacun de vos ensembles de code. 2) S'il y a un changement dans l'UAT, cela aura-t-il toujours un impact sur chaque ensemble du code copié ou pourrait-il seulement avoir un impact sur un ou deux ensembles? S'il peut être isolé et ne nécessiter qu'une modification d'un seul ensemble, il peut être utile de séparer les éléments. 3) Quelle sera la complexité de la méthode initiale si vous essayez de la faire gérer tous les scénarios? Ajoutez-vous beaucoup de boucles imbriquées if / else /? Si vous commencez à faire trop de branchements, vous risquez de vous retrouver avec du code difficile à comprendre. Serait-il plus facile de faire la mise à jour dans chacun des textes copiés que de revoir toute la logique de branchement?
Si vous êtes bloqué copier / coller / modifier, je pense que vous voudriez ajouter des commentaires tels que «Ceci est copié dans la méthode xyz». De cette façon, vous serez rappelé de mettre à jour toutes les versions collées du code. Ou (venant d'un autre utilisateur SilkTest) pourriez-vous ajouter un fichier inc distinct qui se concentrerait uniquement sur ce code répété. De cette façon, vous avez toutes les variations en un seul endroit et pouvez facilement voir les différentes méthodes qui nécessiteraient une mise à jour.
la source
Une grande procédure
Une pensée: on dirait que vous essayez d'éviter le code couper-coller en créant des méthodes comme:
Beaucoup de petites procédures (boîte à outils)
Avez-vous également envisagé l'approche inverse? Au lieu de passer un million de paramètres à une grande procédure testScreen (), créez peut-être votre propre cadre ou une trousse d'outils de petites procédures d'assistance que vous élaborez selon vos besoins. Comme:
Vous coupez et collez toujours ces procédures dans chaque écran, mais vous coupez et collez de plus petits morceaux de code et vous découpez des morceaux communs qui ne sont pas coupés et collés (le contenu de chaque petite procédure).
Couper et coller
Le seul moment où le code coupé-collé ne m'a pas mordu, c'est quand le code a été jeté avant que je ne doive le changer. Ma plus grande préoccupation avec les tests d'interface utilisateur est la rapidité avec laquelle ils deviennent obsolètes. Si vous trouvez que vous jetez tout votre code avant de le changer, alors vous avez peut-être trouvé un créneau où couper et coller est OK! De plus, ce n'est pas si mal quand il n'y a pas de code en aval du code coupé-collé (par exemple dans l'interface utilisateur d'une application). Si vous collez plus de 3 lignes, j'aimerais vraiment faire quelque chose. Prenez au moins des mesures pour le minimiser!
Test d'interface utilisateur automatisé
Heck, si vous pouvez prouver une plus grande productivité avec des tests d'interface utilisateur automatisés que des tests manuels en utilisant n'importe quelle technique (le coût d'écriture / maintenance des tests automatisés est inférieur à celui des tests manuels à chaque fois, mais la qualité est la même), je pense que vous devriez écrire un document. Je le lirais! Je peux voir le titre maintenant, "Coupez et collez un code Net Win pour les tests d'interface utilisateur!"
la source
Ce n'est vraiment pas si mal. En fait, si vous trouvez que certains modèles de code sont utilisés très souvent et que les changements sont très routiniers (comme quelques chaînes ou valeurs de paramètres), vous pouvez même écrire un générateur de code qui génère du code de test répétitif basé sur un petit (- ish?) entrez la liste des valeurs qui changent. J'ai fait cela (code de test généré) plusieurs fois, en utilisant des fichiers batch, des scripts SQLPlus, même des macros Excel (cela semble moche, mais les variables pour les différents scripts de test étaient déjà dans une feuille de calcul) et cela peut être un excellent gain de temps . Le fait est que si quelque chose change dans la structure globale du code de cas de test répétitif, vous pouvez simplement régénérer tout ce dont vous avez besoin.
la source
C'est la même chose que la plupart des autres réponses, mais d'une manière qu'un responsable non technique peut comprendre.
Imaginez le scénario d'erreur suivant:
Que vas-tu faire?
Selon mon expérience:
Lors de l'introduction de la gestion automatisée des tests, comme les «copier-coller»: vous obtenez de nombreux tests en peu de temps.
Après certains des "scénarios d'erreur", la gestion préfère (4) parce que la fixation de "copier-coller-tests" est si chère.
Le faire correctement en premier lieu (3) ne sera pas si rapide mais augmente les chances de survie des tests
la source