Test Swing
Un article de ODcWiki.
| |
L'objectif de cet article est de recenser et de comparer les outils pour automatiser les tests d'interfaces utilisateur basées sur Swing.
Il existe deux grandes catégories d'outils:
- Ceux qui fonctionnent par codage
- Ils sont destinés aux développeurs et s'intègrent aux outils de tests unitaires habituels comme JUnit. Ils fonctionnent sur un mode "boîte blanche", car ils nécessitent de savoir comment sont conçus des écrans, tout du moins dans les grandes lignes. Il permettent de contrôler l'état des écrans et du reste de l'application (base de données). Les composants graphiques (champs texte, cases à cocher) doivent généralement être nommés (component.setName("..."))pour pouvoir y accéder plus facilement depuis les tests: Cette pratique peut paraître intrusive mais fait partie des bonnes habitudes à prendre pour rendre le code testable. Ils peuvent éventuellement servir à tester indépendamment du reste de l'application, un composant graphique personnalisé ou un écran donné.
- Ceux qui fonctionnent par enregistrement
- Ils sont davantage destinés à des analystes, des utilisateurs... même si des compétences en développement peuvent être utiles. Ils fonctionnent sur un mode "boîte noire": l'outil enregistre les événements (clics souris, saisies clavier...) puis un robot se charge de les rejouer à volonté. Comme ils n'ont pas connaissance du découpage sous jacent, ils ne contrôlent que l'état des écrans et servent uniquement à tester l'application dans sa globalité.
Sommaire |
Par codage
Bien que leurs API n'aient rien en commun, tous fonctionnent sensiblement sur le même principe:
- On recherche un composant donné: rechercher le champ texte nommé "utilisateur", rechercher le bouton "OK"
- Ce composant est enveloppé dans une classe qui permet de
- Déclencher des événements: saisir le texte "jdupont" dans le champ texte, cliquer sur le bouton "OK"
- Vérifier son contenu: quel texte est affiché dans le champ texte?
JFC Unit
http://jfcunit.sourceforge.net C'est historiquement la première bibliothèque Java pour tester des interfaces Swing, mais aujourd'hui elle semble quelque peu à l'abandon car la dernière version 2.08 date de 2004.
Son utilisation est décrite en détail dans l'article JFCUnit.
Abbot seul
L'API Java d'Abbot est relativement verbeuse comparée aux autres:
public class LoginDialogAbbotTest { private Hierarchy hierarchy; private ComponentFinder finder; private AWTFixtureHelper fixtureHelper; private LoginDialog loginDialog; @Before public void setUp() throws Exception { hierarchy = new TestHierarchy(); finder = new BasicFinder(hierarchy); fixtureHelper = new AWTFixtureHelper(hierarchy); loginDialog = new LoginDialog(); fixtureHelper.showWindow(loginDialog); } @Test public void testLoginOK() throws Exception { JTextComponentTester textComponentTester = new JTextComponentTester(); // User name text field JTextField userNameText = (JTextField) finder.find(loginDialog, new NameMatcher("userNameText")); textComponentTester.actionEnterText(userNameText, "admin"); // Pasword field JPasswordField loginText = (JPasswordField) finder.find(loginDialog, new NameMatcher("passwordText")); textComponentTester.actionEnterText(loginText, "admin"); // OK Button JButton okButton = (JButton) finder.find(loginDialog, new NameMatcher("okButton")); new JButtonTester().actionClick(okButton); // Dialog not visible assertFalse(loginDialog.isVisible()); } @After public void tearDown() throws Exception { fixtureHelper.dispose(); } }
Le ComponentFinder permet de recherche les composants graphiques à l'écran, les J*Tester permettent de déclencher des événements dessus.
Jemmy
http://jemmy.netbeans.org Développé par l'équipe NetBeans et utilisé pour tester l'IDE lui même, cet outil propose une très bonne couverture des possibilités offertes par Swing et s'intègre avec le Swing Application Framework. Il s'inscrit dans une boîte à outils pour tester les interfaces graphiques nommées Jelly Tools. Il propose son propre système de scénarios mais permet aussi l'utilisation de JUnit:
public class LoginDialogJemmyTest { @Before public void setUp() throws Exception { new ClassReference(LoginDialog.class.getName()).startApplication(); } @Test public void testLoginOK() { JDialogOperator loginDialogOp = new JDialogOperator("Login Dialog"); new JTextFieldOperator(loginDialogOp, new NameComponentChooser("userNameText")).enterText("admin"); new JPasswordFieldOperator(loginDialogOp, new NameComponentChooser("passwordText")).enterText("admin"); new JButtonOperator(loginDialogOp,"OK").clickMouse(); assertFalse(loginDialogOp.isVisible()); } }
Chaque composant graphique est enveloppé dans un J*Operator qui permet de le retrouver et d'interagir avec lui.
UISpec4J
UISpec4J est capable d'exécuter des tests d'interfaces Swing sans les afficher. C'est assez pratique sur les serveurs d'intégration continue qui n'ont pas d'affichage.
public class LoginDialogUISpec4JTest { static { UISpec4J.init(); } private org.uispec4j.Window loginDialogFix; @Before public void setUp() throws Exception { loginDialogWrap = new org.uispec4j.Window(new LoginDialog()); } @Test public void testLoginOK() throws Exception { loginDialogWrap.isVisible().check(); loginDialogWrap.getTextBox("userNameText").setText("admin"); loginDialogWrap.getPasswordField("passwordText").setPassword("admin"); assertFalse(loginDialogFix.isVisible().isTrue()); } }
La JDialog est enveloppée dans une classe Window qui permet de retrouver les composants qu'elle contient. Ceux-ci sont eux-mêmes enveloppés pour pouvoir simuler une interaction utilisateur.
FEST Swing
http://fest.easytesting.org/swing/ Cet bibliothèque s'inscrit dans le cadre du framework FEST (Fixtures for Easy Software Testing) dont l'objectif est de simplifier l'écriture de tests JUnit ou TestNG. Elle a commencé son existence comme une enveloppe d'Abbot jusqu'à que ses contributeurs lui donnent son indépendance. Alex Ruiz, le leader du projet, est d'ailleurs issu de la communauté Abbot.
La simplification de l'écriture des tests passe par l'utilisation des design patterns Fluent Interface et Method Chaining. On obtient ainsi du code concis et lisible.
public class LoginDialogFestTest { private DialogFixture loginDialogFix; @Before public void setUp() throws Exception { loginDialogFix=new DialogFixture(new LoginDialog()); loginDialogFix.show(); } @Test public void testLoginOK() { loginDialogFix.textBox("userNameText").enterText("admin"); loginDialogFix.textBox("passwordText").enterText("admin"); loginDialogFix.button("okButton").click(); loginDialogFix.requireNotVisible(); } @After public void tearDown() throws Exception { loginDialogFix.cleanUp(); } }
Le fonctionnement est le même que UISpec4J.
Par enregistrement
Abbot + Costello
Costello est un outil construit au dessus de Abbot. Il enregistre les scénarios au format XML. La détection des drag'n'drop est assez moyenne. L'outil est peu ergonomique mais fonctionnel.
Abbot et Costello est en fait un duo comique qui sévit dans les années 40.
Marathon
http://www.marathontesting.com/Marathon.html Marathon est un environnement intégré pour les tests d'interfaces. Il enregistre les scénarios dans le language Python (Jython pour être exact) ce qui permet aux scénarios de s'appeller les uns les autres, et de factoriser des portions communes. Le code généré a le mérite d'être clair, concis et retouchable à la main dans l'éditeur fourni. La documentation est claire mais sommaire (API Python non documentée). Ce n'est pas gênant car l'ergonomie est remarquable.
Jython est un interpréteur de langage Python écrit en Java, il est ainsi aisé d'attaquer les librairies Java en Python.
Liens
- L'article Recording vs Coding propose une comparaison (moyennement objective) des deux approches.
- L'article Testing GUI applications dresse une liste des outils disponibles pour tester les applications Swing ou SWT.

