Lotus Notes / Domino Sonstiges > Java und .NET mit Notes/Domino

Mock-Framework für JUnit Tests

(1/7) > >>

flaite:
Hi,

ich arbeite an der entgültigen Strategie zum Junit-Testing von Notes-Agents.

Was ich will:
1. Notes soll für Junit Tests von Notes Agenten nicht gestartet werden.
2. Junit Tests sollen relativ einfach geschrieben werden können.

Denke nun, dass Stubbing und nicht die verschiedenen Mock-Frameworks (wie JMock1 ) einfacher und flexibler ist.
Was verstehe ich unter Stubs?
Einfach Klassen, die die Notes Interfaces implementieren. Schliesslich läuft der gesamte öffentliche Zugriff auf die Notes Api ja über Interfaces.
Stubs für Notes Java Klassen lassen sich mit Eclipse sehr einfach erstellen:
Beispiel: Klasse DocumentStub erzeugen, die einfach das Interface lotus.domino.Document implementiert. Für alle Methoden des Interfaces lotus.domino.Document werden von Eclipse schon Methodenrümpfe erstellt. Die kann ich dann möglichst wiederverwendbar erweitern.
Kann man z.B. für getItemValue, getItemValueString und getItemValueInteger so implementieren:

--- Code: ---
public Vector getItemValue(String name) throws NotesException {
Vector ret = new Vector();
Object val = itemValueMap.get(name);
if (val != null) {
ret.add(val);
}
return ret;


}

public int getItemValueInteger(String name) throws NotesException {
Vector vec = getItemValue(name);
if (vec.size() == 0) return 0;
Object firstEntry = vec.get(0);
if (firstEntry instanceof Number) {
if ((firstEntry instanceof Double)|| (firstEntry instanceof Float)) {
return ((int) Math.round(((Double)firstEntry).doubleValue()));
} else {
return (int) ((Long) firstEntry).intValue();
}
} else {
return 0;
}
}

public String getItemValueString(String name) throws NotesException {
Vector vec = getItemValue(name);
if (vec.size() == 0) return null;
Object firstEntry = vec.get(0);
if (firstEntry instanceof String) {
return (String) firstEntry;
} else {
return null;
}
}

--- Ende Code ---
Das liesse sich dann für alle Projekte  benutzen.
Die Stub Objekte besitzen eine private HashMap itemValueMap, in der die Feldwerte drinstehen:

--- Code: --- private Map itemValueMap = new HashMap();

public void addItemValue(String name, Object value) {
itemValueMap.put(name, value);
}

--- Ende Code ---
Diese itemValueMap kann über addItemValue von aussen gefüllt  werden.
Solche bei Bedarf immer mehr zu verfeinernden allgemein-verwendbare Notes Stub Objekte für Junit-Testing tu ich in ein eigenes Eclipse Projekte, dass ich dann problemlos in spezielle Projekte einbinden kann.

Oder ist das Quatsch? Ich halte die Idee zur Zeit für so großartig, dass ich mich wundere, warum kein anderer darauf gekommen ist.

Gruß Axel

MadMetzger:
Hm... Nach meinem Verständnis von Mocks und Stubs, könnte man deine Klasse auch als Mock, heißt übersetzt Attrappe, bezeichnen. Auf Basis der Übersetzung passt das, was du baust sehr gut dazu, so ich finde. Ein Stub (dt. Stummel) ist ja auch nicht viel anders, nur hätte ich gedacht, dass da zT konstante Werte zurückgegeben werden. An sich finde ich die Idee aber gut, vor allen Dingen kann man damit leichter Unit-Tests durchführen und teilweise auch testgetrieben entwickeln. Wenn ich diese Klasse sehe, fällt mir noch ein, dass man ja den Mock eigentlich auch noch testen muss, was du aber bestimmt auch tust.

Dabei kommt mir aber noch eine weitere Idee: Kann man das nicht auch für andere Notes-Objekte machen und das als "Test-Framework" zusammenstellen?

flaite:
Du hast Recht.
Ich benutze auf jeden Fall nicht Mock-Tools wie EasyMock und JMock1 (JMock2 ist nur für Java5). Das verleitete mich zu falschen Begriffen. Das ist mehr eine Art eigenes Notes-Mock-Objekte Package. 
Es ist ein bischen wie Spring-mock.jar (das dort für Integration-Testing verwendet wird).
http://static.springframework.org/spring/docs/1.2.x/reference/testing.html#integration-testing
Notes-Mock wäre mehr für Unit-Testing. Sobald eine einzelne Klasse Abhängigkeiten zu lotus.domino.* Klassen hat, benötigt man Mocks (oder Stubs), um das zu testen, ohne mit Notes selbst zu kommunizieren.
Notes mocken funktioniert ziemlich gut, weil die ganze apis aus Interfaces besteht.
Wobei ...Für bestimmte Notes-Methoden wirds vermutlich ziemlich schwierig dort geeignete Mock-Klassen selbst zu schreiben (z.B. RichText). Die Brot-und-Butter-Funktionalität (wichtigsten Funktionen von Database, View, DocumentCollection, Document, Item) lassen sich aber vermutlich mit vertretbaren Aufwand mocken.
Die Notes-Designer Funktionalität, java-Source Files über den Edit-Projekt Button direkt von dem entsprechenden Verzeichnis im Eclipse Projekt zu importieren funktioniert für Java-SkriptBibliotheken (nicht zu verwechseln mit JavaScript-ScriptBibliotheken) und Java-Agenten sehr gut.
Mit funktionierenden Notes-Mock-Packet lassen sich Notes-Agenten (und Notes Java-ScriptBibliotheken) sehr schnell testgetrieben oder/und unit-testgestützt entwickeln.
Ich könnte den Import von der Platte-wo-Eclipse-das-hinlegt in den Notes-Agenten oder die Notes Java-ScriptBibliothek noch per Ant-Script automatisieren. Oder Domiclipse verwenden, das aber nicht weiterentwickelt wird.
Ein falscher Weg ist imho, dass mehrere  Entwickler mit Domiclipse den GLEICHEN Notes-Java-Agenten oder NOTES-Java-Scriptbiothek entwickeln zu lassen. Dann eher schon erst testgestützt/testgetrieben entwickeln, den Code in einem Versionierungssystem halten und zu einem geeigneten Zeitpunkt dann die neuen Source Files dann auf den eigentlichen Testserver spielen. Die Prozesse könnte man natürlich noch mit sowas wie CruiseControl automatisieren.
Ich schau mal wie weit ich komme.
Einen Markt für Notes-Agenten gibts schon. Wenn z.B. Dateien als zips in eine Mail-In-DB kommen und dann weiterverarbeitet werden sollen, Zugriff über HTTP auf andere Server, aus einem gif Informationen herausholen, wie breit und hoch die ist, etc.

Gruß Axel

MadMetzger:
Was die technische Umsetzung anbelangt in Bezug auf "Koppelung" von externen Java-IDEs wie Eclipse mit dem Designer habe ich mir noch nicht so wirklich Gedanken gemacht, da es bisher für mich nicht aktuell war. Wird es wohl die nächste Zeit auch nicht werden, da in meinem neuen Unternehmen überhaupt kein Notes eingesetzt wird.

Genau den Gedanken für die Basis-Funktionen hatte ich auch, eine View oder auch eine Collection ist wohl mit vertretbarem Aufwand zu simulieren in einigen Bereichen. Man sollte aber auch hier eben durch Tests versuchen sicherzustellen, dass die Attrappen auch tun, was sie sollen.

Ich denke mal, dass testgetriebene Entwicklung eine gute Sache ist, da man durch die Unit-Tests eine Menge Sicherheit in Bezug auf Änderungen bekommt, sofern die existierenden Testfälle gut sind.

flaite:
Übrigens benutzen auch unsere Sharepoint-Entwickler Unit-Testing.

--- Zitat von: MadMetzger am 17.10.07 - 07:49:43 ---Was die technische Umsetzung anbelangt in Bezug auf "Koppelung" von externen Java-IDEs wie Eclipse mit dem Designer habe ich mir noch nicht so wirklich Gedanken gemacht,

--- Ende Zitat ---
Wenn man den richtigen Prozess hat, kann man Notes Agenten vollständig in Eclipse entwickeln.
Völlig problemlos. Man braucht nicht mal Domiclipse. Alles andere sind Mythen. Hat mich selbst ein wenig überrascht.
Im Agenten Fenster im Designer kann man über Edit Process / Local File System / Base Directory auf src Ordner des Eclipse Projekts auf der Platte stellen und Import. Importiert neue, ersetzt bestehende. Und zwar alles unterhalb des src Ordners.
Man entwickelt den Agenten und die Java-ScriptBibliotheken in Eclipse (mit der Notes Java VM als eingetragene VM für das Projekt). Die dort erzeugten Java Klassen kann man problemlos vom Designer aus importieren. Das ist Deployment.
Vereinfacht gesprochen hat man für deployment-Prozesse immer ein Source-Repository auf der einen Seite und eine Zielplattform auf der anderen Seite. In ant-getriebenen Prozessen, pusht man den Inhalt des source-repository in die Zielplattform. In Notes pullt man aus der Zielplattform die Inhalte des source repository. Dieser Pull-Prozess ist nur ein wenig umständlicher. Ich könnte vermutlich eine funktionierende ant-Erweiterung schreiben, die pusht. Schliesslich besitzt Domiclipse den entsprechenden Code. So wichtig ist das aber gar nicht, da pull nur wenig zeitaufwendiger ist. 

Für jede Java-ScriptBibliothek hab ich ein eigenes Projekt in Eclipse. Jeder Agent auch. Die Abhängigkeiten zwischen Agenten - Java-Scriptbibliotheken und Java-ScriptBibliotheken lassen sich in Eclipse problemlos nachbilden (JavaBuild Path, Project - Tab). Das sind dann natürlich recht viele Projekte. Die organisiere ich aber unter einem Working-Set in Eclipse.
Ich bemühe mich um separation of concern (kommt man über testgestützte Entwicklung quasi von alleine drauf). D.h. Notes wird sowieso nur in sehr wenig Klassen angesprochen. Der Rest ist sowieso problemlos unit-testbar.
Java Agenten nimmt man für Spezialaufgaben, für die es in Notes allenfalls plattformabhängige Möglichkeiten mit C-Apis gibt. Z.B. entzippen von Bildern, ausmessen von height, width, grösse in Bytes der Bilder und importieren der Bilder in Notes RichText Objekte. Oder Kommunikation mit externen Webservices. In solchen Agenten ist der Anteil Klassen, die mit Notes kommunizieren, ohnehin relativ gering. Die Kern-Funktionalität ist von Notes unabhängig und somit Unit- und Integrations-testbar. Ein solches Notes-Mock Paket wäre quasi nur noch die letzte Meile, dass auch Methoden, die in Notes Agenten Notes-Klassen ansprechen, unit-testbar werden.



Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln