Comment puis-je tester une interface graphique?
Les calculs dans mon code sont bien testés, mais parce qu'il y a tellement de code GUI, ma couverture globale du code est inférieure à ce que je voudrais. Existe-t-il des directives sur le code GUI de test unitaire? Est-il encore un sens?
Par exemple, il y a des graphiques dans mon application. Je n'ai pas été capable de comprendre comment automatiser les tests des graphiques. Il faut un œil humain, AFAIK, pour vérifier si le graphique est correct.
(J'utilise Java Swing)
12 réponses
Les conceptions comme MVP et MVC essaient généralement d'abstraire autant de logique que possible de l'interface graphique réelle. Un article très populaire à ce sujet est "The Humble Dialog Box" par Michael Feathers. Personnellement, j'ai eu des expériences mitigées en essayant de sortir la logique de l'interface utilisateur - parfois cela a très bien fonctionné, et à d'autres moments, cela a été plus difficile que ça ne vaut la peine. C'est un peu en dehors de mon domaine d'expertise cependant.
Bien sûr, la réponse est d'utiliser MVC et de déplacer autant de logique hors de l'interface graphique que possible.
Cela étant dit, j'ai entendu un collègue il y a longtemps que lorsque SGI portait OpenGL sur un nouveau matériel, ils avaient un tas de tests unitaires qui dessinaient un ensemble de primatives à l'écran puis calculaient une somme MD5 du tampon de trame. Cette valeur pourrait ensuite être comparée à de bonnes valeurs de hachage connues pour déterminer rapidement si L'API est précise par pixel.
Voici quelques conseils:
Essayez de supprimer le plus de code possible de l'interface graphique (avoir un contrôleur et un objet modèle) de cette façon, vous pourrez les tester sans L'interface graphique.
Pour le graphique, vous devez tester la valeur que vous fournissez au code qui génère le graphique.
Vous pouvez essayer d'utiliser Cucumber etSwinger pour écrire des tests d'acceptation fonctionnelle en anglais simple pour les applications Swing GUI. Swinger utilise la bibliothèque Jemmy de Netbeans sous le capot pour conduire l'application.
Le concombre vous permet d'écrire des tests comme ceci:
Scenario: Dialog manipulation
Given the frame "SwingSet" is visible
When I click the menu "File/About"
Then I should see the dialog "About Swing!"
When I click the button "OK"
Then I should not see the dialog "About Swing!"
Jetez un oeil à cette Échangiste vidéo démo pour le voir en action.
Il y a Selenium RC , qui automatisera le test d'une interface utilisateur web. Il enregistrera les actions et les rejouera. Vous aurez toujours besoin de parcourir les interactions avec votre interface utilisateur, donc cela n'aidera pas avec la couverture, mais il peut être utilisé pour les builds automatisés.
Le test est une forme d'art. Je suis d'accord que la logique devrait être supprimée GUI autant que possible. Nous pouvons ensuite concentrer nos tests unitaires là-bas. Comme toute autre chose, les tests visent à réduire les risques. Vous n'avez pas toujours besoin de tout tester, mais beaucoup de fois la meilleure chose à faire est de briser les différents tests pour différentes régions.
L'autre question Est qu'est-ce que vous essayez vraiment de tester à la couche D'interface utilisateur. Le test de L'interface utilisateur est le test le plus coûteux car il prend généralement plus de temps à créer, à maintenir et c'est le plus fragile. Si vous testez la logique pour savoir que les coordonnées sont correctes avant d'essayer de tracer la ligne, que testez-vous spécifiquement? Si vous souhaitez tester un graphique avec une ligne rouge est tracée. Pouvez-vous lui donner un ensemble de coordonnées prédéterminées et tester si certains pixels sont rouges ou non rouges? Comme suggéré ci-dessus les comparaisons bitmap fonctionnent, Selenium mais mon objectif principal serait de ne pas trop tester l'interface graphique mais plutôt de tester la logique qui aidera à créer l'interface utilisateur, puis de se concentrer sur quelle partie de l'interface utilisateur se casse ou est suspecte et concentre une poignée de tests là-bas.
Vous pouvez utiliser JFCUnit pour tester votre interface graphique, mais les graphiques peuvent être plus difficile. J'ai à quelques reprises pris des instantanés de mon interface graphique et l'ai automatiquement comparé à une version précédente. Bien que cela ne fournisse pas de test réel, il vous avertit si une génération automatique ne produit pas la sortie attendue.
Ce que je comprends de votre question Est que vous cherchez un moyen automatisé de tester votre comportement GUI en détail, l'exemple que vous donnez est de tester si une courbe est réellement dessinée correctement.
Les frameworks de tests unitaires fournissent un moyen de faire des tests automatisés, mais je pense que le genre de tests que vous voulez faire sont des tests d'intégration compliqués qui vérifient le comportement correct d'une multitude de classes, parmi lesquelles les classes de votre GUI toolkit / bibliothèque, que vous ne devriez pas vouloir test.
Vos options dépendent beaucoup des plates-formes/boîtes à outils/frameworks que vous utilisez: par exemple, une application utilisant Qt comme framework GUI peut utiliser Squish pour automatiser ses tests. Vous vérifiez les résultats de vos tests une fois, et les tests exécutés automatiquement par la suite comparent les résultats aux résultats vérifiés.
D'après ce que je sais, c'est assez compliqué, et dépend vraiment de la langue - de nombreuses langues ont leur propre façon de tester L'interface graphique, mais si vous avez vraiment besoin de tester l'interface graphique (par opposition à l'interaction modèle/interface graphique), vous devez souvent simuler un utilisateur réel en cliquant sur les boutons. Par exemple, le framework SWT utilisé dans Eclipse fournit SWTBot, JFCUnit a déjà été mentionné, Mozilla a sa propre façon de simuler cela dans XUL (et d'après ce que j'ai lu sur leurs blogs, ces tests semblent être assez fragiles).
Parfois, vous devez prendre une capture d'écran et tester le rendu parfait pour les pixels (je crois que Mozilla le fait pour vérifier les pages correctement rendues)-cela nécessite une configuration plus longue, mais peut - être ce dont vous avez besoin pour les graphiques. De cette façon, lorsque vous mettez à jour votre code et qu'un test se casse, vous devez vérifier manuellement l'image si l'échec était réel, ou vous avez amélioré le code de rendu du graphique pour générer des graphiques plus jolis et besoin de mettre à jour le capture.
Si vous utilisez Swing, FEST-Swing est utile pour piloter votre interface graphique et tester les assertions. Il est assez simple de tester des choses comme "si je clique sur le bouton A, la boîte de dialogue B doit être affichée" ou "si je sélectionne l'option 2 dans la liste déroulante, toutes les cases à cocher doivent être désélectionnées" .
Le scénario graphique que vous mentionnez n'est pas si facile à tester. Il est assez facile d'obtenir une couverture de code pour les composants de L'interface graphique simplement en les créant et en les affichant (et peut-être les conduire avec FEST). Cependant, faire des assertions significatives est la partie difficile (et la couverture du code sans assertions significatives est un exercice d'auto-tromperie). Comment testez-vous que le graphique n'a pas été dessiné à l'envers, ou trop petit?
Je pense que vous devez juste accepter que certains aspects des interfaces graphiques ne peuvent pas être testés efficacement par des tests unitaires automatisés et que vous devrez les tester d'autres façons.