Schreiben, Testen und Debuggen von Tasmanische Handelsgesellschaft
Während der Code in den gespeicherten Prozeduren der Datenbank, Klassenmethoden, Formularmethoden, Menüs und Programmen geschrieben wurde, wurde er getestet und debuggt.
Dieser Themenabschnitt behandelt das Schreiben und Testen der Anwendung Tastrade und das Debuggen. Dabei werden folgende Bereiche berücksichtigt.
- Formulare
- Berichte
- Menüs und Symbolleisten
- Fehlerbehandlung
- Testen und Debuggen
Dieser Themenabschnitt enthält auch eine Zusammenfassung der Abläufe, die auftreten, wenn das Hauptprogramm erstmalig ausgeführt wird. Das Ende des Themenabschnitts enthält zusätzliche Kommentare zum Code.
Formulare
Tastrade enthält Formularklassen (gespeichert in VCX-Dateien) und auf Formularklassen basierende Formulare (gespeichert in SCX-Dateien). Weitere Informationen zu Formularklassen finden Sie unter "Entwerfen und Erstellen der Klassen von Tasmanische Handelsgesellschaft". Folgende Liste enthält alle Formulare (SCX-Dateien) in Tasmanische Handelsgesellschaft [übergeordnete Klassen (ParentClass) sind in Klammern aufgeführt].
Formularname | Beschreibung |
---|---|
BehindSc [tsBaseForm] | Formular Hintergrund |
ViewCode [tsTextForm] | Zeigt den Code aus dem Formular Hintergrund an |
Category [tsMaintForm] | Wartungsformular für Category.dbf. |
ChngPswd [tsBaseForm] | Ermöglichen der Kennwortänderung durch den Benutzer. |
CustAdd [tsBaseForm] | Ermöglichen der Eingabe von Informationen zu einem neuen Kunden durch den Benutzer. |
Customer [tsMaintForm] | Wartungsformular für Customer.dbf. |
Employee [tsMaintForm] | Wartungsformular für Customer.dbf. |
GetInv [form] | Ermöglichen der Angabe eines Datumsbereichs im Bericht Orders durch den Benutzer. |
GetTitle [form] | Ermöglichen der Angabe von Filterkriterien für die Mitarbeiter, die im Bericht ListEmpl angezeigt werden sollen, durch den Benutzer. GetInv und GetTitle basieren auf der Visual FoxPro-Basisklasse form. Daher können sie in vom Projekt-Manager aus gestarteten Berichten ausgeführt werden, ohne dass dazu Bibliotheken geöffnet werden müssen. |
OrdEntry [OrderEntry] | Formular Auftragseingabe |
OrdHist [OrderEntry] | Formular Auftragsstatistik |
Product [tsMaintForm] | Wartungsformular für Products.dbf. |
Rebuild [tsBaseForm] | Ermöglichen der Neuindizierung und Überprüfung der Gültigkeit der Datenbank durch den administrativen Benutzer. |
Reports [tsBaseForm] | Ermöglichen der Angabe eines auszuführenden Berichts durch den Benutzer. |
Shipper [tsMaintForm] | Wartungsformular für Shipper.dbf. |
Supplier [tsMaintForm] | Wartungsformular für Supplier.dbf. |
Die meisten Formulare mit Steuerelementen, denen keine Daten zugeordnet sind (z. B. IntroForm und About), sind als Klassen in VCX-Dateien gespeichert und werden mit der CREATEOBJECT( )-Funktion erstellt. Manchmal wird ein datengebundenes Formular direkt als eine Klasse aufgerufen. Beispielsweise legt die Login-Klasse Eigenschaften zum Festlegen ihrer Steuerelemente offen. Die Standardwerte dieser Eigenschaften sind auf Tabellen und Felder von Tasmanische Handelsgesellschaft festgelegt. Die LoginPicture-Unterklasse wird direkt innerhalb der Anwendung verwendet. Es gibt keine SCX-Datei für diese Formulare.
Der Vorteil des direkten Ausführens von Formularklassen besteht darin, dass Sie das Formular erstellen und auf zwei unterschiedliche Arten anzeigen können:
- Form = CREATEOBJECT("IntroForm")
- Form.Show
Dadurch können Sie die Einstellungen für die Eigenschaften anpassen, nachdem Sie das Objekt erstellt haben, jedoch bevor es angezeigt wird.
Der Vorteil des Erstellens von Formularen im Formular-Designer besteht im Zugriff auf die Datenumgebung und die Eigenschaften, Ereignisse und Methoden, die dem Datenumgebungsobjekt zugeordnet sind. Außerdem ist es bequemer, Formulare auf diese Weise zu entwerfen und zu testen, da Sie sie direkt vom Formular-Designer oder vom Projekt-Manager aus ausführen können.
Die meisten datengebundenen Formulare innerhalb der Anwendung enthalten in ihren Datenumgebungen Tabellen. Wenn die Anwendung ein Formular enthalten würde, das Benutzern ermöglichen würde, mehrere Tabellen gleichzeitig zu aktualisieren, wäre zu diesem Zweck eine Sicht erstellt worden.
Berichte
Berichte können nach Abschluss der Datenbankentwicklung jederzeit entwickelt werden. Tasmanische Handelsgesellschaft ist keine berichtintensive Anwendung. Daher wurden die Berichte in einer relativ späten Phase der Datenbankentwicklung erstellt. Jeder Bericht enthält eine lokalen Sicht in seiner Datenumgebung. Zwei dieser Berichte ermöglichen es den Benutzern, Parameter für den Bericht anzugeben.
- Der Bericht Orders druckt Rechnungen für die angegebenen Zeiträume aus.
- Der Bericht ListEmpl ermöglicht den Benutzern, die Mitarbeiterliste anhand einer Tätigkeitsbeschreibung zu filtern.
Die Sichten in der Datenumgebungen dieser Berichte wurden so erstellt, dass Parameterübergaben erlaubt sind. Wenn die Datenumgebung eines Berichts eine Sicht öffnet, zeigt Visual FoxPro standardmäßig ein generisches Dialogfeld an, in dem Benutzer zur Angabe von Parametern aufgefordert werden. Um dieses Verhalten an die Anforderungen von Tasmanische Handelsgesellschaft anzupassen, wurden die AutoOpenTables-Eigenschaften der Datenumgebungen auf Falsch (.F.) festgelegt. Im Init-Ereignis der Datenumgebung werden benutzerdefinierte Formulare ausgeführt, in die die Parametervariablen eingetragen werden. Anschließend wird die OpenTables-Methode der Datenumgebung aufgerufen.
Als Quellen für die Berichte wurden Abfragen in Betracht gezogen. Sie wurden jedoch nicht verwendet, weil sie zusätzliche (QPR-) Dateien zum Speichern und für die spätere Rückverfolgung beanspruchen würden. Stattdessen wurden Sichten in die Datenbankdatei (DBC) aufgenommen, die auf komfortable Weise im Datenbank-Designer angezeigt und bearbeitet sowie direkt zur Datenbankumgebung hinzugefügt werden können. SQL-Anweisungen SELECT wurden jedoch je nach Bedarf verwendet, z. B. in der gespeicherten RemainingCredit-Prozedur.
Menüs und Symbolleisten
Das Hauptmenü der Anwendung ist in Main.mnx definiert. Die einzige Symbolleiste, die in der Anwendung verwendet wird, basiert auf der Klasse tsToolbar in Tsbase.vcx.
Der Abschlusscode des Menüs überprüft die Zugriffsberechtigungsstufe der Person, die sich bei der Anwendung angemeldet hat, und entfernt Menünamen und Leisten, zu denen die Person keinen Zugang erhalten soll. Der Code in der Prozedur, die im Menü Datei dem Befehl Zurück zu Visual FoxPro zugeordnet ist, ruft die Cleanup( )-Methode des Application-Objekts auf, die CLEAR EVENTS ausgibt und das Visual FoxPro-Menüsystem wiederherstellt.
Code, der dem Click-Ereignis von Schaltflächen auf Symbolleisten zugeordnet ist, ruft Methoden des aktiven Formulars auf, um Funktionen auszuführen. Auf diese Weise ist die einem Formular zugeordnete Funktionalität im Formular gekapselt.
Um die Menüs und Symbolleisten in der Anwendung zu koordinieren, ruft der in den Menüeinträgen enthaltene Code den Code des Click-Ereignisses der Befehlsschaltflächen auf den Symbolleisten auf. Ein Ausdruck in der Skip For-Klausel aktiviert oder deaktiviert die Menüeinträge je nach Zustand der entsprechenden Befehlsschaltfläche auf der Symbolleiste. Weitere Informationen darüber, wie Menüs und Schaltflächen koordiniert werden, finden Sie in der Hilfe unter "Koordinieren von Menüs und Symbolleisten".
Fehlerbehandlung
Ziel der Fehlerbehandlung war es, Fehler vorauszusehen und soweit möglich ihr Auftreten im Code zu verhindern. Beispielsweise wurde Code in Main.prg aufgenommen, der die relative Pfadeinstellung anpasst, wenn Main.prg (in …\Samples\Tastrade\Progs) anstelle von Tastrade.app ausgeführt wird. Bevor Methodencode Eigenschaften des Application-Objekts objektextern festlegt oder liest, wird zunächst überprüft, ob das Application-Objekt überhaupt vorhanden ist:
IF TYPE('oApp') == 'O'
* do some code
ENDIF
Wenn das Wählen einer Schaltfläche in einer bestimmten Situation einen Fehler verursachen würde, ist diese Schaltfläche deaktiviert.
Es können jedoch nicht alle Fehler im Code vorweggenommen werden. Wenn erforderlich, wird die Fehlerbehandlung durch den Code verwaltet, der dem Error-Ereignis eines Objekts zugeordnet ist.
Wenn ein Fehler im Methodencode auftritt, sucht Visual FoxPro nach Fehlerbehandlungscode, der dem Error-Ereignis des Objekts zugeordnet ist. Wenn auf der Objektebene kein Code für dieses Error-Ereignis geschrieben wurde, wird der Code für das Error-Ereignis ausgeführt, der von der übergeordneten Klasse oder einer in der Klassenhierarchie noch höher stehenden Klasse übernommen wird.
Wurde in der Klassenhierarchie ebenfalls kein Code für das Error-Ereignis erstellt, so sucht Visual FoxPro nach einer ON ERROR-Routine. Existiert keine ON ERROR-Routine, zeigt Visual FoxPro die Standardfehlermeldung an. Um die Standard-Visual FoxPro-Fehlermeldungen anzuzeigen, öffnen Sie Fehlermeldungen A-Z.
Tasmanische Handelsgesellschaft sucht nach drei Fehlertypen, die auf der Datenbankebene auftreten können: Feldregelverletzung, Primärschlüsselverletzung und Trigger-Fehlschlag. Da die BufferMode-Eigenschaft der Formulare in Tasmanische Handelsgesellschaft auf den Wert 2 - optimistisch eingestellt ist, können diese Fehler nur dann auftreten, wenn Benutzer zu einem anderen Datensatz wechseln (und dadurch die Übertragung des Puffers auslösen) oder Änderungen des aktuellen Datensatzes speichern. Diese beiden Aufgaben werden mit Hilfe von Methoden auf der Formularebene behandelt (Methoden, die vom Formular tsBase übernommen wurden). Daher sucht Visual FoxPro zunächst im Error-Ereignis des Formulars nach Fehlerbehandlungscode. Beispielsweise ist dem Error-Ereignis des Formulars Costumer der folgende Code zugeordnet:
DO CASE
CASE nError = 1884 && Primary key violated
THISFORM.pageframe1.page1.cntCustomerInfo.Error(nError, cMethod, nLine)
CASE nError = 1582 && Field rule violated
THISFORM.pageframe1.page1.cntCustomerInfo.Error(nError, cMethod, nLine)
OTHERWISE
tsMaintForm::Error(nError, cMethod, nLine)
ENDCASE
Wenn der Primärschlüssel oder eine Feldregel verletzt wurden, wird die Fehlerinformation an das entsprechende Steuerelement (in diesem Fall cntCustomerInfo) weitergeleitet, damit der Fehlercode dieses Steuerelements eine genauere Fehlermeldung liefern kann als die Standardfehlermeldung von Visual FoxPro. Weiterhin soll dieser Fehlercode frühere Werte auf angemessene Weise wiederherstellen und die Aktivitäten auf das entsprechende Steuerelement verlagern.
Wenn ein weiterer Fehler auftritt, übergibt das Formular Customer den Fehler an die übergeordnete Klasse, tsMaintForm, die Fehlerbehandlungscode von tsBaseForm erbt. Wenn der Fehler einen Trigger-Fehlschlag meldet, zeigt der Code, der dem Error-Ereignis des Formulars tsBaseForm zugeordnet ist, die entsprechende Fehlermeldung an, die in der aErrorMsg[ ]-Eigenschaft des Formulars Costumer gespeichert ist: "Insert-Trigger versagte", "Update-Trigger versagte" oder "Delete-Trigger versagte". (Eine speziell auf ein einzelnes Formulare zugeschnittene benutzerdefinierte Fehlermeldung kann durch Initialisierung des entsprechenden Elements des aErrorMsg[ ]-Arrays im Init-Ereigniscode dieses Formulars erstellt werden.) Alle anderen Fehler werden behandelt, indem den Benutzern die Optionen Abbrechen, Wiederholen oder Ignorieren zur Verfügung gestellt werden.
In Tasmanische Handelsgesellschaft gibt es in der RestoreWindowPos( )-Methode des Formulars tsBaseForm eine ON ERROR-Einstellung:
ON ERROR llError = .T.
Der Code, der die Fensterpositionen wiederherstellt, überprüft den Wert von llError. Wenn während des Lesens der in der INI-Datei gespeicherten Fensterpositionen ein Fehler auftritt, bestimmen die Top- und Left-Standardeigenschaften des Formulars die Position des Formulars.
Testen und Debuggen
Testen und Debuggen bilden integrale Bestandteile aller Implementierungsphasen des Entwicklungsprozesses. Jedes Mal, wenn Komponenten von Tasmanische Handelsgesellschaft funktionierten, wurden sie getestet. Sobald Fehler festgestellt wurden, wurden sie mit Hilfe der Visual FoxPro-Debuggingtools isoliert und beseitigt.
Eine auf Anwendungsebene in Tastrade.h definierte Konstante wurde bei der Entwicklung von Tasmanische Handelsgesellschaft zur Durchführung des Testens und Debuggens verwendet:
#DEFINE DEBUGMODE .T.
Alle Benutzer wurden durch bedingten Code automatisch als Anwendungsentwickler (Leverling) angemeldet, wenn der Wert für DEBUGMODE auf Wahr (.T.) festgelegt war; daher brauchten die Entwickelnden diesen Prozess nicht jedes Mal zu durchlaufen, um die Anwendung zu Testzwecken auszuführen.
Das Menü Dienstprogramme in der Hauptsymbolleiste von Tasmanische Handelsgesellschaft ist aktiv, wenn sich Benutzer oder Tester als Anwendungsentwickler anmelden. Dieses Menü ermöglicht den Zugang zu den Test- und Ansichtsfenstern und zu den Debuggern und ermöglicht es auch, Code abzubrechen, fortzusetzen oder zu unterbrechen.
Hauptprogramm
Der Code in Main.prg bildet das Hauptprogramm der Anwendung. Beim Ausführen der Anwendung wird zuerst der Code in Main.prg ausgeführt. Dieser Code:
Deklariert die API-Funktionen, die zum Lesen und Schreiben der INI-Datei der Anwendung verwendet werden.
Speichert einige Umgebungseinstellungen. Diese Umgebungseinstellungen (CURDIR( ), PATH und CLASSLIB) müssen festgelegt werden, bevor das Application-Objekt erstellt werden kann.
Passt den Pfad an, wenn Main.fxp anstelle von Tastrade.app ausgeführt wird.
Stellt die Klassenbibliotheken auf MAIN und TSGEN ein.
Erstellt ein auf Tastrade in Main.vcx basierendes Application-Objekt.
oApp = CREATEOBJECT('TasTrade')
Als Ergebnis dieser Objekterstellung ereignen sich folgende Vorgänge:
Das Init-Ereignis der übergeordneten Klasse (APPLICATION) wird aufgerufen. Code, der diesem Ereignis zugeordnet ist, erstellt ein Umgebungsobjekt und speichert andere Umgebungseinstellungen.
THIS.AddObject("oEnvironment", "Environment")
THIS.oEnvironment.Set( )
Der Abschnitt [Defaults] der Datei Tastrade.ini wird mit GetPrivString gelesen, um zu bestimmen, ob der Einführungsbildschirm angezeigt werden soll.
Falls in der INI-Datei angegeben, wird "IntroForm" (der Einführungsbildschirm) angezeigt.
Die Login( )-Methode der Klasse wird im Init-Ereignis von Tastrade aufgerufen.
Die Login( )-Methode ruft die DoFormRetVal( )-Methode der Klasse auf.
DoFormRetVal( ) übernimmt die Parameter von Login, erstellt eine Instanz der Klasse LogInPicture und zeigt diese an.
Wenn sich Benutzer anmelden, wird ihre Zugriffsberechtigungsstufe zurückgegeben und als Eigenschaft (cUserLevel) des Application-Objekts gespeichert.
Ruft die Do( )-Methode des Application-Objekts auf.
oApp.Do( )
Code in der Do( )-Methode führt die folgenden Aktionen durch:
Führt das Menüprogramm für die Anwendung aus.
THIS.DoMenu( )
Bestimmt, anfänglich basierend auf der Zugriffsberechtigungsstufe des Benutzers, die Komponente der Anwendung, die ausgeführt werden soll:
lcAction = THIS.GetStartupAction( ) * The GetStartupAction method returns * the value in the Action field of the User
Führt diese Komponente aus, z. B. Auftragseingabe:
IF !EMPTY(lcAction) &lcAction ENDIF
Legt den Ereigniswartestatus mit READ EVENTS fest.
Kommentare zum Code
Zu Lokalisierungszwecken müssen alle Zeichenfolgen, die in verschiedene Sprachen übersetzt werden sollen, mit der Präprozessoranweisung #DEFINE definiert werden. Die definierten Konstanten müssen auf _LOC enden, damit Lokalisierungstools sie zum Übersetzen ausfindig machen können. Diese sind in der Includedatei Strings.h definiert.
Der größte Teil des Codes innerhalb der Anwendung wurde mit Hilfe von Klassen- oder Formularmethoden geschrieben, so dass er mit den entsprechenden Objekten zusammengefasst werden kann. Gespeicherte Prozeduren ermöglichen es, speziell zur Datenverwaltung oder Datenprüfung verwendeten Code in der Datenbank zu speichern.
Utility.prg, die Prozedurbibliothek für die Anwendung, umfasst vier Funktionen:
- IsTag( ), um sicherzustellen, dass ein Indexname existiert, bevor ein Verweis dafür erstellt wird.
- NotYet( ) zur Verwendung während der Entwicklung, wenn Features hinzugefügt werden.
- FileSize( ), um die Größe einer Datei zurückzugeben, die als Parameter übergeben wurde.
- FormIsObject( ), die Wahr (.T.) zurückgibt, wenn das aktive Formularobjekt ein Objekt ist, das auf der Basisklasse Form basiert.
Es wäre möglich, eine Klasse zu erstellen, die diese Dienstprogramme enthält; ein Objekt, das nur dazu erstellt wird, um Zugriff auf diese Prozeduren zu ermöglichen, bringt jedoch einen unnötigen Grad an Abstraktion mit sich.
Siehe auch
Lösungsbeispiele | Beispiel Tasmanische Handelsgesellschaft | Erstellen der Spezifikation für Tasmanische Handelsgesellschaft | Entwerfen und Erstellen der Klassen der Beispielanwendung Tasmanische Handelsgesellschaft | Tasmanische Handelsgesellschaft - Klassenbibliotheken | Entwerfen der Datenbank "Tastrade"