c++ testautomatisierung - Testen von MFC UI-Anwendungen




tools vergleich (7)

Eigentlich haben wir Rational Team Test und dann Robot verwendet, aber in den letzten Diskussionen mit Rational haben wir festgestellt, dass sie keine nativen x64-Anwendungen mit stärkerem Fokus auf .NET unterstützen wollen. Daher haben wir beschlossen, die automatisierten QA-Tools zu wechseln. Das ist großartig, aber die Lizenzkosten erlauben es uns nicht, es für alle Entwickler zu aktivieren.

Alle unsere Anwendungen unterstützen eine COM-API für das Scripting, die wir über VB Regressionstest, aber dies testet die API nicht die Anwendung als solche.

Im Idealfall würde mich interessieren, wie Leute Cppunit und ähnliche Einheitentestrahmen in der Anwendung auf einer Entwicklerebene integrieren.

Wie testen Sie eine große MFC-Benutzeroberflächen-Anwendung?

Wir haben ein paar große MFC-Anwendungen, die seit vielen Jahren in Entwicklung sind. Wir verwenden einige standardisierte automatisierte QA-Tools, um grundlegende Skripte auszuführen, um Grundlagen zu prüfen, Dateien zu öffnen usw. Diese werden von der QA-Gruppe nach dem täglichen Build ausgeführt.

Wir möchten jedoch Verfahren einführen, mit denen einzelne Entwickler Tests gegen Dialoge, Menüs und andere visuelle Elemente der Anwendung erstellen und ausführen können, bevor Code an den täglichen Build übergeben wird.

Ich habe von Techniken wie versteckte Testknöpfe in Dialogen gehört, die nur in Debug-Builds erscheinen. Gibt es dafür Standard-Toolkits?

Die Umgebung ist C ++ / C / FORTRAN, MSVC 2005, Intel FORTRAN 9.1, Windows XP / Vista x86 & x64.


Da Sie MFC erwähnt haben, habe ich angenommen, dass Sie eine Anwendung haben, die unter einem automatisierten Testkabelbaum schwer zu finden wäre. Sie werden die besten Vorteile von Unit-Test-Frameworks beobachten, wenn Sie Tests erstellen, während Sie den Code schreiben. Aber versuchen, eine neue Funktion testweise zu einer Anwendung hinzuzufügen, die nicht testbar ist ... kann harte Arbeit sein. und frustrierend.

Nun, was ich vorschlagen werde, ist definitiv harte Arbeit ... aber mit etwas Disziplin und Ausdauer wirst du den Nutzen bald genug sehen.

  • Zunächst benötigen Sie einige Verwaltungsunterstützung für neue Fixes, um etwas länger zu verwenden. Stellen Sie sicher, dass jeder versteht warum.
  • Als nächstes kaufen Sie eine Kopie des WELC-Buches . Lesen Sie es, um zu bedecken, wenn Sie die Zeit haben ODER wenn Sie schwer gedrückt werden, scannen Sie den Index, um das Symptom zu finden, das Ihre App ausstellt. Dieses Buch enthält viele gute Ratschläge und ist genau das, was Sie brauchen, wenn Sie versuchen, vorhandenen Code testbar zu machen. Alttext http://ecx.images-amazon.com/images/I/51RCXGPXQ8L._SL160_AA115_.jpg
  • Dann sollten Sie für jeden neuen Fix / Änderung etwas Zeit investieren und den Bereich verstehen, an dem Sie arbeiten werden. Schreiben Sie einige Tests in eine xUnit-Variante Ihrer Wahl (frei verfügbar), um das aktuelle Verhalten auszuüben.
  • Stellen Sie sicher, dass alle Tests bestanden sind. Schreiben Sie einen neuen Test, der das benötigte Verhalten oder den Fehler ausführt.
  • Schreiben Sie Code, um diesen letzten Testdurchlauf durchzuführen.
  • Refaktor gnadenlos in dem zu testenden Bereich, um das Design zu verbessern.
  • Wiederholen Sie diesen Vorgang für jede neue Änderung, die Sie an diesem System vornehmen müssen. Keine Ausnahmen von dieser Regel.
  • Jetzt das gelobte Land : Bald werden immer mehr Inseln mit gut getestetem Code auftauchen. Immer mehr Code würde unter die automatisierte Testsuite fallen und Änderungen werden immer einfacher zu machen. Und das ist, weil langsam und sicher das zugrundeliegende Design prüfbarer wird.

Der einfache Ausweg war meine vorherige Antwort. Das ist der schwierige, aber richtige Ausweg.


Obwohl nicht perfekt, ist das Beste, was ich dafür gefunden habe, AutoIt http://www.autoitscript.com/autoit3

"AutoIt v3 ist eine Freeware-BASIC-ähnliche Skriptsprache zur Automatisierung der Windows-GUI und der allgemeinen Skripterstellung. Sie verwendet eine Kombination aus simulierten Tastenanschlägen, Mausbewegungen und Fenster- / Steuerungsmanipulationen, um Aufgaben auf andere Weise zu automatisieren. Sprachen (zB VBScript und SendKeys) AutoIt ist auch sehr klein, eigenständig und läuft auf allen Versionen von Windows out-of-the-box ohne lästige "Laufzeiten"! "

Dies funktioniert gut, wenn Sie Zugriff auf den Quellcode der Anwendung haben, die ausgeführt wird, da Sie die Ressourcen-ID-Nummer der Steuerelemente verwenden können, die Sie steuern möchten. Auf diese Weise müssen Sie sich keine Gedanken über simulierte Mausklicks auf bestimmte Pixel machen. Leider können Sie in einer Legacy-Anwendung feststellen, dass die Ressourcen-ID nicht eindeutig ist, was zu Problemen führen kann. Jedoch. Es ist sehr einfach, die IDs als eindeutig zu definieren und neu zu erstellen.

Das andere Problem ist, dass Sie auf Zeitprobleme stoßen werden. Ich habe keine bewährte Lösung für diese. Versuch und Irrtum ist, was ich verwendet habe, aber das ist eindeutig nicht skalierbar. Das Problem besteht darin, dass das AutoIT-Skript darauf warten muss, dass die Testanwendung auf einen Befehl reagiert, bevor das Skript den nächsten Befehl ausgibt oder nach der richtigen Antwort sucht. Manchmal ist es nicht einfach, ein passendes Ereignis zu finden, auf das man warten muss.

Mein Gefühl ist, dass ich bei der Entwicklung einer neuen Anwendung auf einem konsistenten Weg bestehen würde, "READY" zu signalisieren. Dies wäre sowohl für die menschlichen Benutzer als auch für Testskripte hilfreich! Dies kann eine Herausforderung für eine Legacy-Anwendung sein, aber vielleicht können Sie sie in problematischen Punkten einführen und langsam auf die gesamte Anwendung verteilen, während die Wartung fortgesetzt wird.


Das hängt davon ab, wie die App aufgebaut ist. Wenn Logik und GUI-Code getrennt sind (MVC), ist das Testen der Logik einfach. Werfen Sie einen Blick auf Michael Feathers "Humble Dialog Box" (PDF).

EDIT: Wenn du darüber nachdenkst: Du solltest sehr vorsichtig umgestalten, wenn die App nicht so aufgebaut ist. Es gibt keine andere Technik zum Testen der Logik. Skripte, die Klicks simulieren, kratzen nur an der Oberfläche.

Es ist eigentlich ziemlich einfach:

Nehmen Sie an, dass Ihr Steuerelement / Fenster / was auch immer den Inhalt einer Listbox ändert, wenn der Benutzer auf eine Schaltfläche klickt und Sie sicherstellen möchten, dass die Listbox nach dem Klick die richtigen Elemente enthält.

  1. Refactor, so dass es eine separate Liste mit den Elementen für die Listbox gibt. Die Elemente werden in der Liste gespeichert und nicht von wo auch immer Ihre Daten stammen extrahiert. Der Code, der die Liste List Dinge macht, weiß nur über die neue Liste.
  2. Dann erstellen Sie ein neues Controller-Objekt, das den Logikcode enthält. Die Methode, mit der der Schaltflächenklick ausgeführt wird, ruft nur mycontroller-> ButtonWasClicked () auf. Es weiß nichts über die Listbox oder irgendetwas anderes.
  3. MyController :: ButtonWasClicked () führt aus, was für die beabsichtigte Logik getan werden muss, bereitet die Elementliste vor und teilt dem Steuerelement mit, dass es aktualisiert werden soll. Damit dies funktioniert, müssen Sie die Steuerung und die Steuerung entkoppeln, indem Sie eine Schnittstelle (reine virtuelle Klasse) für die Steuerung erstellen. Die Steuerung kennt nur ein Objekt dieser Art, nicht die Steuerung.

Das ist es. Die Steuerung enthält den Logikcode und kennt die Steuerung nur über die Schnittstelle. Jetzt können Sie einen regulären Komponententest für MyController :: ButtonWasClicked () schreiben, indem Sie das Steuerelement verspotten. Wenn Sie keine Ahnung haben, wovon ich spreche, lesen Sie Michaels Artikel. Zweimal. Und danach wieder.
(Hinweis an mich selbst: muss lernen, nicht so viel zu schimpfen)


Obwohl es die Benutzeroberfläche nicht verarbeiten kann, teste ich MFC-Code mit der Boost-Test-Bibliothek. Es gibt einen Code Project-Artikel zum Einstieg:

Entwerfen robuster Objekte mit Boost


Nun, wir haben eine dieser gigantischen MFC-Apps am Arbeitsplatz. Es ist ein riesiger Schmerz zu erhalten oder zu verlängern ... es ist ein riesiger Ball aus Schlamm jetzt aber es harket im Moolah.

  • Wir verwenden Rational Robot für Rauchprüfungen und dergleichen.
  • Ein anderer Ansatz, der einige Erfolge erzielt hat, besteht darin, eine kleine produktspezifische Sprache zu erstellen, und Skripttests , die VBScript und etwas Control verwenden, behandeln Spionagezauber. Verwandeln Sie allgemeine Aktionen in Befehle. Beispiel: OpenDatabase ist ein Befehl, der wiederum die erforderlichen Skriptblöcke einfügt, um auf Hauptmenü> Datei> "Öffnen ..." zu klicken. Sie erstellen dann Excel-Blätter, die eine Folge solcher Befehle sind. Diese Befehle können auch Parameter übernehmen. So etwas wie ein FIT-Test ... aber mehr Arbeit. Sobald Sie die meisten der gebräuchlichen Befehle gefunden haben und die Skripte bereit sind. Es werden Skripte ausgewählt und assembliert (gekennzeichnet durch CommandIDs), um neue Tests zu schreiben. Ein Test-Läufer analysiert diese Excel-Blätter, kombiniert alle kleinen Skript-Blöcke zu einem Test-Skript und führt es aus.

    1. OpenDatabase "C: \ Tests \ MyDB"
    2. OpenDialog "Modell hinzufügen"
    3. AddModel "M0001", "MyModel", 2.5, 100
    4. Drücke OK
    5. SpeichernDatenbank

HTH


Chutzpah - Ein JavaScript Test Runner

Ich habe ein Open-Source-Projekt mit dem Namen Chutzpah erstellt, das ein Test-Runner für JavaScript-Unit-Tests ist. Mit Chutzpah können Sie JavaScript-Komponententests über die Befehlszeile und innerhalb von Visual Studio ausführen. Es unterstützt auch das Ausführen im TeamCity Continuous Integration Server.





c++ unit-testing user-interface mfc tdd