Question

Comment testez-vous une grande application d'interface utilisateur MFC?

Nous avons quelques grandes applications MFC en développement depuis de nombreuses années. Nous utilisons des outils d’assurance qualité automatisés standard pour exécuter des scripts de base permettant de vérifier les principes fondamentaux, l’ouverture des fichiers, etc. Celles-ci sont exécutées par le groupe d’assurance qualité après la construction quotidienne.

Nous aimerions toutefois introduire des procédures permettant aux développeurs individuels de créer et d'exécuter des tests sur les boîtes de dialogue, les menus et autres éléments visuels de l'application avant de soumettre le code à la construction quotidienne.

J'ai entendu parler de techniques telles que les boutons de test masqués sur les boîtes de dialogue n'apparaissant que dans les versions de débogage. Existe-t-il des kits d'outils standard pour cela.

L’environnement est C ++ / C / FORTRAN, MSVC 2005, Intel FORTRAN 9.1, Windows XP / Vista x86 & amp; x64.

Était-ce utile?

La solution

Cela dépend de la structure de l'application. Si la logique et le code d'interface graphique sont séparés (MVC), il est facile de tester la logique. Jetez un coup d'œil à Michael Feathers, & Humble Dialog Box " (PDF).

EDIT: Si vous y réfléchissez: vous devriez très soigneusement refactoriser si l’application n’est pas structurée de cette façon. Il n'y a pas d'autre technique pour tester la logique. Les scripts qui simulent des clics ne font qu'effleurer la surface.

C'est en fait assez facile:

Supposons que votre contrôle / fenêtre / quoi que ce soit change le contenu d'une zone de liste lorsque l'utilisateur clique sur un bouton et que vous voulez vous assurer que la zone de liste contient les éléments appropriés après le clic.

  1. Refactor afin qu'il y ait une liste séparée avec les éléments de la liste à afficher. Les éléments sont stockés dans la liste et ne sont pas extraits de l’origine de vos données. Le code qui fait que la liste de liste ne contient que des informations sur la nouvelle liste.
  2. Vous créez ensuite un nouvel objet contrôleur qui contiendra le code logique. La méthode qui gère le clic sur le bouton appelle uniquement mycontroller- > ButtonWasClicked (). Il ne sait pas à propos de la liste ou quoi que ce soit d'autre.
  3. MyController :: ButtonWasClicked () effectue ce qui doit être fait pour la logique souhaitée, prépare la liste des éléments et demande au contrôle de se mettre à jour. Pour que cela fonctionne, vous devez découpler le contrôleur et le contrôle en créant une interface (classe virtuelle pure) pour le contrôle. Le contrôleur ne connaît qu'un objet de ce type, pas le contrôle.

C'est tout. Le contrôleur contient le code logique et ne connaît le contrôle que via l'interface. Maintenant, vous pouvez écrire des tests unitaires réguliers pour MyController :: ButtonWasClicked () en vous moquant du contrôle. Si vous ne savez pas de quoi je parle, lisez l'article de Michaels. Deux fois. Et encore après.
(Note à moi-même: il faut apprendre à ne pas trop bavarder)

Autres conseils

Depuis que vous avez mentionné MFC, j'ai supposé que vous aviez une application difficile à utiliser avec un faisceau de test automatisé. Vous constaterez les meilleurs avantages des frameworks de tests unitaires lorsque vous construisez des tests lors de l'écriture du code. Mais essayer d'ajouter une nouvelle fonctionnalité de manière pilotée par les tests à une application qui n'est pas conçue pour être testable est une tâche ardue. et bien frustrant.

Maintenant, ce que je vais proposer, c’est un travail dur . Mais avec un peu de discipline et de persévérance, vous en verrez les bénéfices assez rapidement.

  • Tout d'abord, vous aurez besoin d'un certain soutien de gestion pour que les nouveaux correctifs prennent un peu plus longtemps. Assurez-vous que tout le monde comprend pourquoi.
  • Procurez-vous ensuite une copie du livre WELC . Lisez-le de bout en bout si vous avez le temps OU si vous êtes pressé, parcourez l'index pour trouver le symptôme que présente votre application. Ce livre contient beaucoup de bons conseils et constitue exactement ce dont vous avez besoin lorsque vous essayez de tester le code existant. alt text
  • Ensuite, pour chaque nouveau correctif / changement, prenez le temps de comprendre le domaine sur lequel vous allez travailler. Ecrivez des tests dans une variante xUnit de votre choix (disponible gratuitement) pour exercer le comportement actuel.
  • Assurez-vous que tous les tests sont réussis. Ecrivez un nouveau test dont les exercices nécessitent le comportement ou le bogue.
  • Écrivez le code pour réussir ce dernier test.
  • Refactorisez sans pitié dans la zone testée pour améliorer la conception.
  • Répétez cette opération pour chaque nouvelle modification à apporter au système à partir de maintenant. Aucune exception à cette règle.
  • Maintenant, la terre promise : des îlots de code bien testé et en pleine croissance commenceront à faire surface. De plus en plus de code tomberait dans la suite de tests automatisés et les modifications deviendraient progressivement plus faciles à effectuer. Et c’est parce que lentement et sûrement la conception sous-jacente devient plus testable.

La solution de facilité était ma réponse précédente. C’est la solution difficile mais la bonne solution.

Je réalise que la question est périmée, mais pour ceux d'entre nous qui travaillent toujours avec MFC, le framework de test d'unité Microsoft C ++ de VS2012 fonctionne bien.

Procédure générale:

  1. Compilez votre projet MFC en tant que bibliothèque statique
  2. Ajoutez un nouveau projet de test unitaire natif à votre solution.
  3. Dans le projet test, ajoutez votre projet MFC en tant que référence.
  4. Dans les propriétés de configuration du projet test, ajoutez les répertoires Include pour vos fichiers d'en-tête.
  5. Dans l'éditeur de liens, les options d'entrée ajoutent votre fichier MFC.lib; nafxcwd.lib; libcmtd.lib;
  6. Sous "Ignorer les bibliothèques spécifiques par défaut", ajoutez nafxcwd.lib; libcmtd.lib;
  7. Sous Général, ajoutez l'emplacement du fichier lib exporté au format MFC.

Le https: // stackoverflow. com / questions / 1146338 / error-lnk2005-new-and-delete-déjà-défini-dans-libcmtd-libnew-obj décrit bien pourquoi vous avez besoin des nafxcwd.lib et libcmtd.lib.

L'autre chose importante à vérifier dans les projets hérités. Dans Propriétés de configuration générale, assurez-vous que les deux projets utilisent le même «jeu de caractères». Si votre MFC utilise un jeu de caractères multi-octets, vous aurez également besoin du test MS.

Bien que cela ne soit pas parfait, le meilleur que j'ai trouvé pour cela est AutoIt http://www.autoitscript.com/ autoit3

"AutoIt v3 est un langage de script gratuit de type BASIC conçu pour automatiser l'interface utilisateur graphique Windows et les scripts généraux. Il utilise une combinaison de frappes de touche simulées, de mouvements de la souris et de manipulations de fenêtre / contrôle afin d'automatiser les tâches de manière impossible ou fiable avec d'autres langues (par exemple, VBScript et SendKeys). AutoIt est également très petit, autonome et s’exécutera sur toutes les versions de Windows prêtes à l’emploi, sans "runtimes" ennuyeux. obligatoire! "

Cela fonctionne bien lorsque vous avez accès au code source de l'application pilotée, car vous pouvez utiliser le numéro d'ID de ressource des contrôles que vous souhaitez piloter. De cette façon, vous n'avez pas à vous soucier des clics de souris simulés sur des pixels particuliers. Malheureusement, dans une application héritée, il est possible que l’ID de la ressource ne soit pas unique, ce qui peut poser problème. Toutefois. il est très simple de changer les identifiants pour qu'ils soient uniques et de les reconstruire.

L’autre problème est que vous rencontrerez des problèmes de synchronisation. Je n'ai pas de solution éprouvée pour ces problèmes. Essai et erreur est ce que j'ai utilisé, mais ce n'est clairement pas évolutif. Le problème est que le script AutoIT doit attendre que l'application de test réponde à une commande avant que le script n'émette la commande suivante ou vérifie si la réponse est correcte. Parfois, il n’est pas facile de trouver un événement commode à attendre.

Mon sentiment est que, lors du développement d'une nouvelle application, j'insisterais sur une manière cohérente de signaler "READY". Cela serait utile aux utilisateurs humains ainsi qu'aux scripts de test! Cela peut représenter un défi pour une application héritée, mais vous pouvez peut-être l’introduire sous forme de problèmes et l’étendre lentement à l’ensemble de l’application à mesure que la maintenance se poursuit.

Bien qu’elle ne puisse pas gérer l’interface utilisateur, je teste le code MFC à l’aide de la bibliothèque Boost Test. Il existe un article Code Project sur la prise en main:

Conception d'objets robustes avec boost

Nous avons l'une de ces énormes applications MFC sur le lieu de travail. C’est une douleur gigantesque de maintenir ou d’allonger… c’est une énorme boule de boue maintenant, mais elle traîne dans le moolah. De toute façon

  • Nous utilisons Rational Robot > pour faire des tests de fumée et autres.
  • Une autre approche qui a connu un certain succès consiste à créer un petit langage spécifique au produit et des tests de script utilisant VBScript et certains outils de contrôle de la magie de l'espionnage. Transformez les actions courantes en commandes. OpenDatabase serait une commande qui injecterait à son tour les blocs de script requis pour cliquer sur le menu principal > Fichier > "Ouvert ...". Vous créez ensuite des feuilles Excel qui sont une série de telles commandes. Ces commandes peuvent aussi prendre des paramètres. Quelque chose comme un test FIT .. mais plus de travail. Une fois que vous avez identifié la plupart des commandes courantes et préparé les scripts. C'est choisir et assembler des scripts (étiquetés par CommandIDs) pour écrire de nouveaux tests. Un testeur analyse ces feuilles Excel, combine tous les petits blocs de script dans un script de test et l'exécute.

    1. OpenDatabase "C: \ tests \ MyDB"
    2. OpenDialog "Ajouter un modèle"
    3. AddModel "M0001", "MyModel", 2,5, 100
    4. Appuyez sur OK
    5. SaveDatabase

HTH

En fait, nous utilisions Rational Team Test, puis Robot, mais lors de discussions récentes avec Rational, nous avons découvert qu’ils ne prévoyaient pas prendre en charge les applications natives x64 en mettant davantage l’accent sur .NET. Nous avons donc décidé de changer d’outil de contrôle qualité automatisé. C’est formidable, mais les coûts de licence ne nous permettent pas de l’activer pour tous les développeurs.

Toutes nos applications prennent en charge une API COM pour les scripts, que nous testons par régression via VB, mais cela teste l'API sans l'application en tant que telle.

Idéalement, je souhaiterais savoir comment les gens intègrent cppunit et des frameworks de tests unitaires similaires dans l'application au niveau des développeurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top