In diesem Tutorial möchte ich beschreiben, wie man eine Webanwendung mit Apache Maven erstellen und Jasmine JavaScript Testfälle erstellt. Diese Testfälle werden in den Buildprozess integriert und können somit später über ein BuiltServer automatisch ausgeführt werden.
Maven installieren
Das Buildtool Apache Maven kann von der Seite https://maven.apache.org/ bezogen werden. Nach dem Herunterladen und entpacken sollte die Umgebungsvariable „PATH“ um den Pfad zum Maven Verzeichnis ergänzt werden.
WebProjekt mit Maven erstellen
Als Erstes wird ein WebProjekt erstellt (soweit nicht schon vorhanden).
Ich erstelle gerne meine Projekte mit Maven da mein bevorzugtes build tool Maven ist.
Als Erstes müssen, wir ein Verzeichnis erstellen in welches wir unser WebProjekt von Maven erstellen lassen wollen. Wenn dieses geschehen ist, kann im Verzeichnis auf der Konsole folgender Befehl eingegeben werden:
mvn archetype:generate -DgroupId=de.jasminetest -DartifactId=TestWebApp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
Es wird nun ein Projekt erstellt mit welchem wir später weiterarbeiten können.
C:\development\JasmineTestWebApp>mvn archetype:generate -DgroupId=de.jasminetest -DartifactId=TestWebApp -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-archetype-plugin:2.4:generate (default-cli) > generate-sources @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:2.4:generate (default-cli) < generate-sources @ standalone-pom <<< [INFO] [INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom --- [INFO] Generating project in Batch mode [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: basedir, Value: C:\development\JasmineTestWebApp [INFO] Parameter: package, Value: de.jasminetest [INFO] Parameter: groupId, Value: de.jasminetest [INFO] Parameter: artifactId, Value: TestWebApp [INFO] Parameter: packageName, Value: de.jasminetest [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: C:\development\JasmineTestWebApp\TestWebApp [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4.538 s [INFO] Finished at: 2015-11-02T13:10:16+01:00 [INFO] Final Memory: 13M/143M [INFO] ------------------------------------------------------------------------ C:\development\JasmineTestWebApp>
Dieses Projekt kann man sich in eine beliebige Entwicklungsumgebung importieren.
Erweitern der Verzeichnisstruktur
Es muss folgende Struktur ergänzt bzw. erstellt werden. Damit die Testfälle später angelegt und vom Testframework abgearbeitet werden können.
Jasmine mit Maven
Als Nächstes müssen, wird die benötigten Abhängigkeiten einstellen, dazu wird die Datei pom.xml geöffnet und folgender Code hinzugefügt.
<properties> <jasmine.version>2.0</jasmine.version> <js.source.dir>${basedir}/src/main/webapp/resources/js</js.source.dir> </properties> <build> <pluginManagement> <plugins> <plugin> <groupId>com.github.searls</groupId> <artifactId>jasmine-maven-plugin</artifactId> <version>${jasmine.version}</version> <executions> <execution> <goals> <goal>test</goal> </goals> </execution> </executions> <configuration> <!-- Quellcode Verzeichnis der JavaScript Dateien --> <jsSrcDir>src/main/resources/js</jsSrcDir> <!-- Quellcode Verzeichnis der Testfälle --> <jsTestSrcDir>${basedir}/src/test/webapp/js/specs</jsTestSrcDir> <preloadSources> <!-- Zusätzliche Bibliotheken welche für den Testfall benötigt werden, zbsp. jQuery --> <source>${js.source.dir}/jquery-1.11.3.min.js</source> </preloadSources> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>com.github.searls</groupId> <artifactId>jasmine-maven-plugin</artifactId> <version>${jasmine.version}</version> </plugin> </plugins> </build>
Einfacher Test
Als Erstes wollen wir einen ganz einfachen Test schreiben.
Gegeben ist folgende JavaScript Klasse:
SimpleObject.js
function SimpleObject(){ } SimpleObject.prototype.sayHello = function(name){ return "Hello "+name; }
Unser Testfall würde wiefolgt aussehen :
SimpleObjectTest.js
Zeile 4 : erstellen eines Objektes vom Typ SimpleObject
Zeile 5 : ausführen der Methode „sayHello“ mit dem Wert „Max“ für den Parameter „name“
Zeile 6 : prüfen des Ergebnisses
describe("Testcases for SimpleObject", function () { it("say Hell Test", function () { var simpleObject = new SimpleObject(); var result = simpleObject.sayHello("Max"); expect(result).toBe("Hello Max"); }); });
Es ist beim Erstellen der Prüfbedingung nicht wichtig, ob man das erwartete Ergebnis mit dem Ergebnis validiert oder umgekehrt.
describe("Testcases for SimpleObject", function () { it("say Hell Test Version 1", function () { var simpleObject = new SimpleObject(); var result = simpleObject.sayHello("Max"); expect(result).toBe("Hello Max"); }); it("say Hell Test Version 2", function () { var simpleObject = new SimpleObject(); var result = simpleObject.sayHello("Max"); expect("Hello Max").toBe(result); }); });
Beide Testfälle ergeben das gleiche Ergebnis.
Jedoch sollte man sich der Lesbarkeit halber auf eine Darstellung einigen.
Ausführen des Testfalls auf der Konsole
Diesen einfachen Testfall können wir nun auf der Konsole mit folgendem Befehl ausführen:
mvn test
Das Ergebnis dieses Befehls ist folgende Ausgabe
[INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building TestWebApp Maven Webapp 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ TestWebApp --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ TestWebApp --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ TestWebApp --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ TestWebApp --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ TestWebApp --- [INFO] [INFO] --- jasmine-maven-plugin:2.0:test (default) @ TestWebApp --- [INFO] jetty-8.1.14.v20131031 [INFO] Started SelectChannelConnector@0.0.0.0:50167 [INFO] Executing Jasmine Specs [INFO] Resolved artifact C:\****\.m2\repository\com\github\klieber\phantomjs\2.0.0\phantomjs-2.0.0-windows.zip from central (https://repo.maven.apache.org/maven2, d [INFO] Extracting C:\****\.m2\repository\com\github\klieber\phantomjs\2.0.0\phantomjs-2.0.0-windows.zip\phantomjs-2.0.0-windows\bin\phantomjs.exe to C:\development\ Nov 02, 2015 1:47:19 PM org.openqa.selenium.phantomjs.PhantomJSDriverService <init> INFORMATION: executable: C:\development\JasmineTestWebApp\TestWebApp\target\phantomjs\phantomjs-2.0.0-windows\bin\phantomjs.exe Nov 02, 2015 1:47:19 PM org.openqa.selenium.phantomjs.PhantomJSDriverService <init> INFORMATION: port: 5341 Nov 02, 2015 1:47:19 PM org.openqa.selenium.phantomjs.PhantomJSDriverService <init> INFORMATION: arguments: [--webdriver=5341, --webdriver-logfile=C:\development\JasmineTestWebApp\TestWebApp\phantomjsdriver.log] Nov 02, 2015 1:47:19 PM org.openqa.selenium.phantomjs.PhantomJSDriverService <init> INFORMATION: environment: {} [INFO - 2015-11-02T12:47:27.197Z] GhostDriver - Main - running on port 5341 [INFO - 2015-11-02T12:47:31.449Z] Session [e1c66520-815f-11e5-b3bb-836a2fac72ab] - page.settings - {"XSSAuditingEnabled":false,"javascriptCanCloseWindows":true,"javascriptCa Windows NT 6.1; WOW64) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.0.0 Safari/538.1","webSecurityEnabled":true} [INFO - 2015-11-02T12:47:31.449Z] Session [e1c66520-815f-11e5-b3bb-836a2fac72ab] - page.customHeaders: - {} [INFO - 2015-11-02T12:47:31.450Z] Session [e1c66520-815f-11e5-b3bb-836a2fac72ab] - Session.negotiatedCapabilities - {"browserName":"phantomjs","version":"2.0.0","driverName" erts":false,"databaseEnabled":false,"locationContextEnabled":false,"applicationCacheEnabled":false,"browserConnectionEnabled":false,"cssSelectorsEnabled":true,"webStorageEnab [INFO - 2015-11-02T12:47:31.450Z] SessionManagerReqHand - _postNewSessionCommand - New Session Created: e1c66520-815f-11e5-b3bb-836a2fac72ab [INFO - 2015-11-02T12:47:32.998Z] ShutdownReqHand - _handle - About to shutdown [INFO] ------------------------------------------------------- J A S M I N E S P E C S ------------------------------------------------------- [INFO] Testcases for SimpleObject say Hell Test Results: 1 specs, 0 failures, 0 pending [INFO] stopped o.e.j.s.h.ContextHandler{/webjars,file:/C:/development/JasmineTestWebApp/TestWebApp/} [INFO] stopped o.e.j.s.h.ContextHandler{/classpath,file:/C:/development/JasmineTestWebApp/TestWebApp/} [INFO] stopped o.e.j.s.h.ContextHandler{/,file:/C:/development/JasmineTestWebApp/TestWebApp/} [INFO] stopped o.e.j.s.h.ContextHandler{/spec,file:/C:/development/JasmineTestWebApp/TestWebApp/} [INFO] stopped o.e.j.s.h.ContextHandler{/src,file:/C:/development/JasmineTestWebApp/TestWebApp/} [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 49.279 s [INFO] Finished at: 2015-11-02T13:47:34+01:00 [INFO] Final Memory: 20M/176M [INFO] ------------------------------------------------------------------------ C:\development\JasmineTestWebApp\TestWebApp>
Am schluss ist eine Zusammenfassung zu sehen
- wieviele Testfälle ausgeführt
- wieviele fehlgeschlagen, und
- wieviele wartend / auskommentiert sind
Einen Testfall entfernen
Manchmal ist es vonnöten einen Testfall zu entfernen, dazu kann man diesen entweder komplett löschen (und später sich durch die History des Quellcodeverwaltungssystems wühlen) oder aber man kommentiert diesen mit einem vorangestellten „x“ aus. zbsp:
describe("Testcases for SimpleObject", function () { it("say Hell Test", function () { var simpleObject = new SimpleObject(); var result = simpleObject.sayHello("Max"); expect(result).toBe("Hello Max"); }); //Auskommentierter Testfall mit x xit("say Hell Test", function () { var simpleObject = new SimpleObject(); var result = simpleObject.sayHello("Max1"); expect(result).toBe("Hello Max"); }); //Auskommentierter Testfall mit x xdescribe("Subtestcases for SimpleObject", function () { it("say Hell Test", function () { var simpleObject = new SimpleObject(); var result = simpleObject.sayHello("Max1"); expect(result).toBe("Hello Max"); }); }); });
Wenn man nun mit dem Befehl „mvn jasmine:bdd“ den Server für Jasmine Testfälle startet, kann man mit der Adresse „http://localhost:8234“ sich das Ergebnis anzeigen lassen. Der Vorteil mit dem Server ist, wenn man etwas ändert und die Adresse neuläd (F5) werden die gesamten Testfälle erneut ausgeführt.
Jasmine Testfälle im Browser anzeigen
Um nicht immer den Maven Befehl auf der Konsole einzugeben, kann man auch den Server von Jasmine über die Konsole starten und kann so im Browser sich das Ergebnis grafisch aufbereitet ansehen.