DOM Prozessoren

Beim Erstellen eines Reports aus einem Protokoll, oder der Generierung von Package Dokumentation aus einer Testsuite, arbeitet QF-Test mit einem zweistufigen Prozess. Im ersten Schritt wird ein XML-Dokument erstellt, welches im zweiten Schritt zu einem HTML-Dokument weiterverarbeitet wird. Beide Transformationen werden mittels XSLT Stylesheets durchgeführt.

Hinweis Der Begriff DOM (für Document Object Model) findet auch bei XML-Dokumenten Anwendung, nicht nur bei HTML-Webseiten. Dieser Abschnitt befasst sich ausschließlich mit XML und XSLT und hat nichts mit dem DOM eines Web SUT zu tun.

Leider sind XSLT Stylesheets nicht sonderlich brauchbar, wenn es darum geht, reinen Text zu bearbeiten. Die 'Bemerkung' Felder in 'Testfallsatz', 'Testfall', 'Testschritt', 'Package' oder 'Prozedur' Knoten enthalten aber oft zusätzliche Informationen in einer internen Struktur, die von Anwender zu Anwender verschieden ist, je nachdem, welche Konventionen verwendet werden. So werden zum Beispiel häufig JavaDoc Tags verwendet, um die Parameter einer 'Prozedur' zu beschreiben. Nach der ersten Stufe der Transformation sieht zum Beispiel die 'Bemerkung' der 'Prozedur' qfs.swing.menu.select aus unserer Standardbibliothek wie folgt aus:

<comment>Select an item from a menu.
For example: for the File -> Open action, the QF-Test component ID
 "File" is the menu, and the QF-Test component ID "Open" is the item.

@param  client  The name of the SUT client.
@param  menu    The QF-Test ID of the menu.
@param  item    The QF-Test ID of menu item.</comment>
Beispiel 53.40:  Beispiel 'Bemerkung' nach der ersten Transformation

Es ist überaus schwierig, nur mittels XSLT die @param Tags auszuwerten. Hier kommen nun die DOM Prozessoren ist Spiel. Zwischen der ersten und zweiten Transformation führt QF-Test optional eine zusätzliche Transformation direkt auf dem DOM des XML-Dokuments aus. Bei dieser Transformation durchläuft QF-Test den gesamten DOM Baum und ruft für jedes Element die dafür registrierten DOM Prozessoren auf, die dadurch die Möglichkeit haben, das DOM zu verändern.

Hinweis Für JDK 1.4 ist das XML Document Object Model (DOM) Teil der Standard-API. Für ältere JDK-Versionen wird es vom XML-Parser xerces (aus dem Apache Projekt) bereitgestellt, der Teil von QF-Test ist. Die API-Spezifikation des DOM finden Sie unter anderem unter http://download.oracle.com/javase/1.5.0/docs/api/org/w3c/dom/package-summary.html.

Das DOMProcessor Interface

Das zu implementierende Interface ist de.qfs.apps.qftest.extensions.DOMProcessor. Es ist im Grunde trivial und besteht nur aus einer einzigen Methode:

 
 
Element process(Element node)
Verarbeitet einen Element Knoten.
Rückgabewert Ein Element oder null. Wird null zurückgegeben, werden die Kindknoten des Elements ganz normal verarbeitet, andernfalls werden die Kindknoten nicht weiter betrachtet. Wird ein anderes Element als das Original zurückgeliefert, wird das Original im DOM durch den Rückgabewert ersetzt.
 
 

In der process Methode kann der Prozessor tun und lassen, was er will, solange er sich dabei auf den Knoten und seine (direkten oder indirekten) Unterknoten beschränkt. Das Element kann durch Rückgabe eines anderen Elements komplett ersetzt werden.

Hinweis Um ein Element aus dem DOM zu löschen, muss der DOMProcessor für einen höher gelegenen Knoten, z.B. den Vaterknoten, registriert werden. Der aktuelle Knoten darf in der process Methode nicht aus dem DOM entfernt werden.

Mit QF-Test werden zwei Beispiel Implementationen von DOM Prozessoren ausgeliefert. Der ParagraphProcessor ist in Java geschrieben und wird zur Illustration im Verzeichnis misc zur Verfügung gestellt. Er wird intern verwendet, um 'Bemerkungen' an Leerzeilen in einzelne Absätze aufzubrechen.

Ebenfalls im misc Verzeichnis befindet sich der DocTagProcessor, der zur Transformation von JavaDoc Tags dient, wie sie im obigen Beispiel beschrieben wurden. Nach seinem Einsatz sähe dieses Beispiel wie folgt aus:

<comment>Select an item from a menu.
For example: for the File -> Open action, the QF-Test component ID
 "File" is the menu, and the QF-Test component ID "Open" is the item.</comment>
<param name="client">The name of the SUT client.</param>
<param name="menu">The QF-Test ID of the menu.</param>
<param name="item">The QF-Test ID of menu item.</param>
Beispiel 53.41:  Beispiel 'Bemerkung' nach Einsatz eines DOM Prozessors

Daraus kann im zweiten Schritt ohne großen Aufwand sinnvolles HTML generiert werden.

Die DOMProcessorRegistry

Damit ein DOM Prozessor zum Einsatz kommen kann, muss er zunächst für die entsprechenden Elemente registriert werden. Dies geschieht mit Hilfe der DOMProcessorRegistry.

Für jede Art von Transformation gibt es eine DOMProcessorRegistry Instanz, die durch einen Namen identifiziert wird. Für die Reportgenerierung lautet dieser "report", für die Testfall Dokumentation "testdoc" und für die Package Dokumentation "pkgdoc". Dazu kommt je eine Variante für die Generierung der Zusammenfassungen mit den Namen "report-summary", "testdoc-summary" und "pkgdoc-summary". Eine Instanz der Registry erhalten Sie mit Hilfe der Methode instance:

 
 
DOMProcessorRegistry instance(String identifier)
Liefert eine Registry Instanz .
Parameter
identifierDer Bezeichner der entsprechenden Transformation.
 
 

Bei den restlichen Methoden handelt es sich um den üblichen Satz von register/unregister Varianten:

 
 
void registerDOMProcessor(DOMProcessor processor)
Registriert einen generischen DOM Prozessor, der für alle Arten von von Elementen aufgerufen wird.
Parameter
processorDer zu registrierende Prozessor.
 
void registerDOMProcessor(String node, DOMProcessor processor)
Registriert einen DOM Prozessor für ein spezifisches Element.
Parameter
nameDer Name des Elements.
processorDer zu registrierende Prozessor.
 
void unregisterDOMProcessor(DOMProcessor processor)
Entfernt einen generischen DOM Prozessor, der für alle Arten von von Elementen aufgerufen wird.
Parameter
processorDer zu entfernende Prozessor.
 
void unregisterDOMProcessor(String node, DOMProcessor processor)
Entfernt einen DOM Prozessor für ein spezifisches Element.
Parameter
nameDer Name des Elements.
processorDer zu entfernende Prozessor.
 
void unregisterDOMProcessors()
Entfernt alle DOM Prozessoren.
 
 

Fehlerbehandlung

Exceptions, die in der process Methode geworfen werden, fängt QF-Test ab und meldet sie. Die Transformation wird in diesem Fall gestoppt.