Comment pouvez-vous TDD pour un bug qui ne peut être testé qu'après avoir été corrigé?


13

Voici un exemple: Mon application Web contient des éléments déplaçables. Lorsque vous faites glisser un élément, le navigateur produit une "image fantôme". Je veux supprimer "l'image fantôme" lors du glissement et j'écris un test pour ce comportement.

Mon problème est qu'au départ, je n'ai aucune idée de la façon de corriger ce bogue et la seule façon dont je peux écrire un test est après l'avoir corrigé.

Dans une fonction simple telle que let sum = (a, b) => a - b, vous pouvez écrire un test expliquant pourquoi sum(1, 2)n'est pas égal 3avant d'écrire du code.

Dans le cas que je décris, je ne peux pas tester, car je ne sais pas ce qu'est la vérification (je ne sais pas ce que doit être l'assertion).

Une solution au problème décrit est:

let dataTransfer = e.dataTransfer
let canvas = document.createElement('canvas');
canvas.style.opacity = '0';
canvas.style.position = 'absolute';
canvas.style.top = '-1000px';
dataTransfer.effectAllowed = 'none';

document.body.appendChild(canvas);
dataTransfer.setDragImage(canvas, 0, 0);

Je n'aurais pas pu savoir que c'était la solution. Je n'aurais même pas pu écrire le test après avoir trouvé la solution en ligne, car la seule façon dont je pouvais savoir si cela fonctionnait vraiment était d'ajouter ce code dans ma base de code et de vérifier avec le navigateur s'il avait l'effet souhaité. Le test devait être écrit après le code, ce qui va à l'encontre de TDD.

Quelle serait l'approche TDD de ce problème? L'écriture du test avant le code est-elle obligatoire ou facultative?


2
Faites alors vos recherches. Trouvez une solution ... puis rédigez votre test, corrigez et refactorisez. Les tests ne sont pas destinés à (seulement) vérifier que votre code fonctionne, mais à pérenniser votre solution complète. Au départ, vous créez votre test pour qu'il échoue, quelle propriété testerez-vous? C'est une façon de commencer.
Juan Carlos Eduardo Romaina Ac

@Kilian Foth: Je vois vos bonnes intentions en changeant le titre de la question, mais votre modification a invalidé certaines parties de ma réponse. De plus, votre nouveau titre ne convenait pas à mon humble avis au corps de la question. J'ai donc fait un retour en arrière, sans offense.
Doc Brown

Réponses:


26

Lorsque je vous ai bien compris, vous ne pouvez même pas écrire un test automatisé fiable pour votre exemple "d'image fantôme" après avoir trouvé une solution, car la seule façon de vérifier le comportement correct est de regarder l'écran et de vérifier s'il n'y a pas d'image fantôme plus. Cela me donne l'impression que votre titre d'origine a posé la mauvaise question. La vraie question devrait être

  • comment tester automatiquement un certain comportement d'une interface utilisateur graphique?

Et la réponse est - pour plusieurs types de problèmes d'interface utilisateur, vous ne le faites pas . Bien sûr, on peut essayer d'automatiser la création de l'interface utilisateur montrant le problème d'une manière ou d'une autre, et essayer d'implémenter quelque chose comme une comparaison de captures d'écran, mais cela est souvent sujet aux erreurs, fragile et peu rentable.

En particulier, la conception d'interface utilisateur de "test de conduite" ou les améliorations d'interface utilisateur par des tests automatisés écrits à l'avance est littéralement impossible. Vous "pilotez" la conception de l'interface utilisateur en faisant une amélioration, montrez le résultat à un humain (vous-même, certains testeurs ou un utilisateur) et demandez des commentaires.

Acceptez donc le fait que TDD ne soit pas une solution miracle, et pour certains types de problèmes, les tests manuels ont plus de sens que les tests automatisés. Si vous avez un processus de test systématique, peut-être avec des testeurs dédiés, la meilleure chose à faire est d'ajouter le cas à leur plan de test.


En général, les tests d'interface utilisateur ne sont pas triviaux; vous pouvez épingler, c'est-à-dire hacher une image générée, vous pouvez simuler / automatiser, vous pouvez enregistrer des macros, vous pouvez utiliser une solution propriétaire, vous pouvez utiliser des tests manuels, cela dépend de la situation et de la nécessité des tests UI automatisés pour votre projet.
esoterik

1
@esoterik: oui, et toutes ces techniques automatisées sont sujettes aux erreurs et fragiles, comme je l'ai déjà écrit. La seule approche non fragile que je connaisse est le test manuel.
Doc Brown

3
Merci de répondre. Je pense que vous avez raison, j'espère à tort trouver une solution miracle au TDD. Il ne semble pas y avoir de moyen efficace de tester ce que je veux tester - la comparaison de captures d'écran et tout ce qui précède ne semble pas donner un retour sur investissement suffisant. La comparaison de captures d'écran en particulier semble prendre beaucoup de temps et, comme vous l'avez dit, source d'erreurs.
maximedupre

1
@maximedupre: a trouvé cette publicité pour un outil qui tente de résoudre le problème, mais néanmoins l'article semble d'accord avec ma réponse en général.
Doc Brown

5

Quelle serait l'approche TDD de ce problème? L'écriture du test avant le code est-elle obligatoire ou facultative?

Une façon consiste à appliquer un analogue d'une solution de pointe .

James Shore l'a décrit ainsi:

Nous effectuons de petites expériences isolées lorsque nous avons besoin de plus d'informations.

L'idée de base est que vous déposez les outils de conception pendant que vous déterminez ce qui se passe. Une fois que vous avez pris vos repères, vous reprenez les outils de conception.

L'astuce: vous ramenez les connaissances de votre enquête dans votre base de code de production, mais vous n'apportez pas le code . Au lieu de cela, vous le recréez en utilisant vos techniques de conception disciplinées.

Chevaux de course.

ÉDITER:

Comment automatiser un test si le défaut n'est visible qu'à l'œil nu?

Je voudrais suggérer une orthographe légèrement différente: "Comment pouvez-vous automatiser un test si l'automatisation du test n'est pas rentable?"

La réponse, bien sûr, est "vous ne le faites pas". Au lieu de cela, essayez de séparer votre implémentation en deux parties - une grande partie où les tests sont rentables et une plus petite qui est trop simple à casser.

Il y a deux façons de construire une conception de logiciel: Une façon est de la rendre si simple qu'il n'y a évidemment aucune lacune - CAR Hoare

Ainsi, lorsque vous travaillez avec du code tiers, nous aurons une coque de code très fine qui agit comme un proxy pour la bibliothèque tierce. En test, nous remplaçons ce shell par un "test double", qui vérifie le protocole , sans se soucier qu'il produit les effets désirés.

Pour tester l'intégration de nos codes avec le vrai code tiers, nous nous appuyons sur d'autres techniques (vérification visuelle, appels au support technique, optimisme ....)

Il peut être utile de conserver quelques artefacts de démonstration afin de vérifier que vos hypothèses sont toujours valables lorsque vous mettez à niveau la bibliothèque tierce.


J'adore ce que James Shore a à dire. Je suis actuellement en train de suivre le screencast www.letscodejavascript.com et j'apprends beaucoup. Je vais lire les liens que vous m'avez indiqués.
maximedupre

Vous avez raison, j'ai lu plus sur TDD et les pointes. Vous devez en fait savoir à quoi ressemble le code que vous essayez de vérifier avant d'essayer de le tester. TDD ne peut pas vous enseigner quelque chose que vous ne connaissez pas déjà, mais il peut potentiellement vous montrer certaines choses que vous devez apprendre, en paraphrasant James Shore. Sur cette note, je voudrais proposer une étape d'addition dans TDD: Spike, Test, Fail, Pass, Refactor.
maximedupre

0

Dans une perspective différente, les tests autour de l'interface utilisateur / interface graphique peuvent être un peu mieux réalisés en ce qui concerne les tests d'acceptation (tests centrés sur les fonctionnalités / flux de travail métier).

Pour le Web, je pense que les frameworks comme le webdriver au sélénium ont le potentiel de se rapprocher du bon test, mais la surcharge pour commencer pourrait être un peu trop, et c'est un changement dans le flux vu avec TDD en ce qui concerne les tests unitaires. .

La partie qui aiderait spécifiquement à votre situation est quelque chose appelé Page Object Model ( https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html ). Cela permet un mappage explicite de l'interface graphique d'exécution avec du code, soit en nommant les méthodes / événements / membres de classe.

Les principaux arguments contre cela seraient les frais généraux, et que ces frais généraux pourraient généralement être vus à la fin du cycle de développement. La surcharge étant que les tests nécessitent un wrapper qui semblerait créer un travail dupliqué.

À l'avenir, cela dépendrait des coûts / avantages de l'équipe et de l'entreprise, il pourrait donc être un sujet bénéfique à discuter pour déterminer les attentes et les opinions.


J'essayais en fait des tests e2e / fonctionnels (avec un sélecteur Web au sélénium) dans TDD, mais le temps système est certainement beaucoup trop important comme vous l'avez dit. Vous ne pouvez pas être un développeur efficace et faire du TDD avec des tests e2e. J'utilisais POM, mais le seul avantage qu'il m'a apporté était une architecture améliorée dans ma base de code de test.
maximedupre

Oui, je pense qu'une option plus viable que j'ai vue de différentes entreprises à différentes équipes serait d'incorporer un processus SQA plus manuel, où un membre de l'équipe / équipe est désigné pour ne préformer que les tests manuels de l'interface utilisateur. Les tests ont principalement des captures d'écran et une documentation étape par étape. À tout le moins, quelque chose comme ça produirait des preuves de tests vers une application.
eparham7861

0

À quoi ressemble une image fantôme? Si vous avez créé une interface utilisateur factice d'une couleur connue, où vous placez votre composant glissable? Y aurait-il une couleur spécifique présente s'il y avait une image fantôme.

Ensuite, le test pourrait tester l'absence de la couleur de l'image fantôme.

Un tel test serait raisonnablement durable et réalisable.


Faisable - oui. Durable - dépend. Le simple fait de changer la couleur / le thème de votre interface utilisateur pourrait casser vos tests, ce qui ne me semble pas trop durable.
Sean Burton

1
Vous ne testeriez pas votre interface utilisateur entière. Vous créeriez une interface utilisateur factice pour le composant glisser-déposer.
Esben Skov Pedersen

Je ne sais pas comment accomplir ce que vous proposez. Une image fantôme dans mon cas serait une réplique semi-opaque de l'élément qui est déplacé. L'image fantôme suit le curseur à tout moment pendant le glisser-déposer.
maximedupre

Oui. Vous devrez automatiser le glissement. Ce ne serait pas un test unitaire mais plutôt un test e2e.
Esben Skov Pedersen
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.