Les calculs dans mon code sont bien testés, mais comme il y a beaucoup de code d'interface graphique, la couverture globale de mon code est inférieure à celle que je souhaiterais. Existe-t-il des directives sur le code d'interface graphique des tests unitaires? Cela a-t-il même un sens?
Par exemple, mon application contient des graphiques. Je n'ai pas été capable de comprendre comment automatiser le test des graphiques. Il faut un regard humain, autant que je sache, pour vérifier si le graphique est correct.
(J'utilise Java Swing)
Des conceptions telles que 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 plusieurs expériences en essayant de sortir la logique de l'interface logique: parfois, cela fonctionnait très bien et d'autres fois, cela posait plus de problèmes que cela ne valait la peine. C'est un peu en dehors de mon domaine d'expertise cependant.
Bien entendu, la solution consiste à utiliser MVC et à déplacer autant de logique que possible hors de l'interface graphique.
Cela étant dit, un collègue de travail m'a dit il y a longtemps que, lorsque SGI portait OpenGL sur un nouveau matériel, il effectuait une série de tests unitaires pour dessiner un ensemble de primitives à l'écran, puis calculer une somme MD5 du tampon d'images. Cette valeur peut ensuite être comparée aux bonnes valeurs de hachage connues afin de déterminer rapidement si l'API est précise par pixel.
Vous pouvez essayer ISpec4J est une bibliothèque de tests fonctionnels et/ou unitaires Open Source pour Java ...
Vous pouvez essayer d'utiliser Cucumber et Swinger pour écrire des tests d'acceptation fonctionnels en anglais clair pour les applications Swing GUI. Swinger utilise la bibliothèque Jemmy de Netbeans sous le capot pour piloter l'application.
Le concombre vous permet d’écrire des tests comme celui-ci:
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 à ceci démo vidéo Swinger pour le voir en action.
Le test est une forme d'art. Je suis d'accord que la logique devrait être supprimée autant que possible GUI. Nous pouvons alors 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 souvent, la meilleure chose à faire est de diviser les différents tests dans différentes zones.
L'autre question est de savoir ce que vous essayez vraiment de tester au niveau de la couche d'interface utilisateur. Les tests d'interface utilisateur sont les tests les plus coûteux, car leur création, leur maintenance et leur durée sont généralement plus longues. Si vous testez la logique pour savoir si 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 dessiné. 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, mais je m'attache surtout à ne pas sur-tester l'interface graphique, mais plutôt à tester la logique permettant de créer l'interface utilisateur, puis de se concentrer sur la partie suspecte de l'interface utilisateur et sur la focalisation de quelques tests. Là.
Voici quelques astuces:
Essayez de supprimer le plus de code possible de l'interface graphique (avec le contrôleur et l'objet modèle) de cette manière, 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.
Il existe Selenium RC , qui automatise le test d’une interface utilisateur Web. Il va enregistrer des actions et les rejouer. Vous devrez tout de même parcourir les interactions avec votre interface utilisateur. Cela ne va donc pas aider à la couverture, mais il peut être utilisé pour des versions automatisées.
D'après ce que je comprends de votre question, vous recherchez un moyen automatisé de tester votre comportement d'interface graphique en détail. L'exemple que vous donnez vérifie si une courbe est dessinée correctement.
Les frameworks de tests unitaires offrent un moyen de faire des tests automatisés, mais je pense que les types de tests que vous souhaitez 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 boîte à outils/bibliothèque GUI. ne devrait pas vouloir tester.
Vos options dépendent beaucoup des plates-formes/outils/frameworks que vous utilisez: par exemple, une application utilisant Qt en tant que framework d'interface graphique peut utiliser Squish pour automatiser ses tests. Vous vérifiez les résultats de vos tests une fois, puis les tests exécutés automatiquement comparent les résultats aux résultats vérifiés.
Vous pouvez utiliser JFCUnit pour tester votre interface graphique, mais les graphiques peuvent être plus complexes. À plusieurs reprises, j'ai pris des clichés de mon interface graphique et l'ai automatiquement comparée à une version précédente. Bien que cela ne fournisse pas un test réel, il vous avertit si une génération automatique ne produit pas la sortie attendue.
Window Licker pour Swing & Ajax
Ce n'est pas à vous de tester la bibliothèque d'interface graphique. Ainsi, vous pouvez éviter la responsabilité de vérifier ce qui est réellement dessiné à l'écran et de vérifier les propriétés des widgets, en confiant à la bibliothèque qu'elles représentent exactement ce qui est dessiné.
Si vous utilisez Swing, FEST-Swing est utile pour piloter votre interface graphique et tester vos assertions. Cela rend 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 le menu déroulant, toutes les cases à cocher doivent être désélectionnées" .
Le scénario graphique que vous avez mentionné n’est pas facile à tester. Il est assez facile d'obtenir une couverture de code pour les composants d'interface graphique simplement en les créant et en les affichant (et éventuellement en les pilotant avec FEST). Cependant, faire des assertions significatives est la partie difficile (et la couverture de code sans assertions significatives est un exercice d'auto-illusion). Comment testez-vous que le graphique n'a pas été dessiné à l'envers ou trop petit?
Je pense que vous devez simplement accepter que certains aspects des interfaces utilisateur graphiques ne peuvent pas être testés efficacement par des tests unitaires automatisés et que vous devrez les tester autrement.
D'après ce que je sais, c'est assez compliqué et dépend vraiment de la langue - de nombreuses langues ont leur propre méthode de test de 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 sous XUL (et d'après ce que j'ai lu sur leurs blogs, ces tests semblent assez fragiles).
Vous devez parfois prendre une capture d'écran et tester le rendu au pixel près (je pense que Mozilla le fait pour vérifier si les pages sont correctement rendues). Cela nécessite une configuration plus longue, mais peut-être ce dont vous avez besoin pour les graphiques. Ainsi, lorsque vous mettez à jour votre code et qu'un test s'interrompt, vous devez vérifier manuellement l'image si l'échec est réel, ou vous avez amélioré le code de rendu des graphes pour générer des graphes plus jolis et nécessiter la mise à jour des captures d'écran.