As one might intuit, the jasmine-maven-plugin is a Maven plugin for the JavaScript testing framework, Jasmine.
If you're using Maven, you're probably writing Java (but, hey, you could be using it for any JVM-language). And if you're anything like me, you're here to figure out how to treat your client-side code with the same degree of professionalism that you already show server-side code. Maybe that means you want a painless way to test-drive your JavaScript. Maybe you're trying to figure out how to incorporate JavaScript tests on your continuous integration server without requiring any browser shenanigans.
the good newsFirst run this:
mvn archetype:generate -DarchetypeRepository=http://searls-maven-repository.googlecode.com/svn/trunk/snapshots -DarchetypeGroupId=com.github.searls -DarchetypeArtifactId=jasmine-archetype -DarchetypeVersion=1.1.0.1-SNAPSHOT -DgroupId=com.acme -DartifactId=my-jasmine-project -Dversion=0.0.1-SNAPSHOT
And then this:
cd my-jasmine-project && mvn jasmine:bdd
Then go here and you should see:
If you're already familiar with adding Maven plugins to POM files, then this should be a breeze. If it's new to you, then take a deep breath and contemplate adding this XML to your project's "pom.xml" file:
<build>
…
<plugins>
…
<plugin>
<groupId>com.github.searls</groupId>
<artifactId>jasmine-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- configuration properties will go here -->
</configuration>
</plugin>
…
</plugins>
…
</build>
Ready to try it out? Once you've added the plugin to your project, just run the following in a terminal:
mvn jasmine:bdd
You should see some output like this
[INFO]
Server started--it's time to spec some JavaScript! You can run your
specs as you develop by visiting this URL in a web browser:
http://localhost:8234
The server will monitor these two directories for scripts
that you add, remove, and change:
source directory: src/main/javascript
spec directory: src/test/javascript
Just leave this process running as you test-drive your code,
refreshing your browser window to re-run your specs.
You can kill the server with Ctrl-C when you're done.
Now visit http://localhost:8234 in your browser of choice and you should see a Jasmine spec runner with 0 specs, 0 failures. Sort of like this one:
And that's it! When you add source scripts to the source directory and spec scripts to the specs directory and refresh the page, your specs will be executed.
Running the jasmine:bdd goal and refreshing an actual browser will always provide substantially faster feedback than the headless jasmine:test goal. As a result, I strongly recommend you use it to drive development of your JavaScript and only worry about running the headless execution when you would otherwise perform full Maven builds (like before you push your code or in CI).
If you've added the plugin as shown above (that is, with an execution of the test goal) to your POM, it's already set up execute your Jasmine specs every time your build goes through the test lifecycle phase!
So when you run this:
mvn clean test
A happy build might output:
[INFO] Executing Jasmine Specs
[INFO]
-------------------------------------------------------
J A S M I N E S P E C S
-------------------------------------------------------
[INFO]
the ElementMover object
instantiation
throws an exception if you forget "new"
moving around two divs
initially sees that div1 is above div2
moves div1 after div2
moves div2 before div1
adding a third div to the mix
moves div1 betwixt div2 & div3
moves div3 before div1
Results: 6 specs, 0 failures
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.607s
[INFO] Finished at: Mon Jul 04 15:01:58 EDT 2011
[INFO] Final Memory: 9M/81M
[INFO] ------------------------------------------------------------------------
And a failing build might output:
[INFO] Executing Jasmine Specs
[INFO]
-------------------------------------------------------
J A S M I N E S P E C S
-------------------------------------------------------
[INFO]
HelloWorld
should say hello
wins
wins
wins
loses <<< FAILURE!
* Expected 'sad' to be 'panda'.
1 failure:
1.) HelloWorld it loses <<< FAILURE!
* Expected 'sad' to be 'panda'.
Results: 5 specs, 1 failures
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.020s
[INFO] Finished at: Mon Jul 04 15:03:47 EDT 2011
[INFO] Final Memory: 8M/81M
[INFO] ------------------------------------------------------------------------
The plugin relies on HtmlUnit for headless (which is to say, GUI-less) execution. It's not a perfect emulation of a browser, but for moderately well-isolated unit testing (e.g. only pedestrian interactions with the DOM), it works really well.
The plugin makes numerous assumptions about how you've structured your project. To compensate for the fact that its defaults won't suit your project perfectly, it comes with a (confusingly vast) array of configuration properties. While you can find all of the properties in the project's source code, here are some of the popular ones.
(Also: for help seeing how these and other properties might be used, you can find a number of example projects in the project's github repo, which are used to support its Cucumber features.)
| name | purpose | default | notes |
|---|---|---|---|
| sourceIncludes | an ordered list of filters to match script source files | [**/*.js, **/*.coffee] | Often, you'll want to use sourceIncludes to control the ordering of your sources. If your external dependencies need to be loaded first, you might:
|
| specIncludes | an ordered list of filters to match script spec files | [**/*.js, **/*.coffee] | I often find myself needing control of the spec include order when I have some global spec helpers or spec-scoped dependencies, like:
|
| jsSrcDir | directory storing your JavaScript | src/main/javascript |
serving a Java webapp? You might set this to "${project.basedir}/src/main/webapp/js" |
| serverPort | the port that the jasmine:bdd goal binds to |
8234 | |
| skipTests | when true, specs won't be executed during the build | false | will most likely come in handy when set on the command line, like so: mvn package -DskipTests |
| format | the style with which the plugin outputs results during the build | documentation |
setting this to "progress" will print your specs in a much more succinct "....FF.." style |
| sourceExcludes | just like sourceIncludes, but will exclude anything matching the provided patterns | (none) | |
| specExcludes | just like specIncludes, but will exclude anything matching the provided patterns | (none) | |
| jsTestSrcDir | directory storying your Jasmine Specs | src/test/javascript |
|
| browserVersion | the type of browser HtmlUnit emulates when your specs run during the build | FIREFOX_3 |
valid values also include: FIREFOX_3_6, INTERNET_EXPLORER_6, INTERNET_EXPLORER_7, INTERNET_EXPLORER_8 |
| haltOnFailure | when true, failing specs break the build | true | you might want to set this to false temporarily when you have a known failing spec but you don't want to turn off spec execution altogether. |
| customRunnerTemplate | an HTML file that defines how the spec runner pages are rendered | for an example, consider starting from the plugin's default template. | |
| preloadSources | a list of relative-paths to scripts that need to be loaded before any others. | this property is only rarely neceesary. It might help in a situation where a spec file needs to be loaded above production sources, or when a remote dependency needs to be included (ex. <preloadSources><source>http://a.com/lib.js</source></preloadSources>) |
|
| timeout | when spec execution exceeds the timeout (in seconds), the build fails | 300 | if you have a lot of specs or if you're using Jasmine for integration testing, you may find that you need to increase this limit. |
| junitXmlReportFileName | the name of the generated JUnit XML report | TEST-jasmine.xml | the plugin generates XML of the same brand JUnit does; this is handy for when your CI server is capable of aggregating these XML files (like Jenkins freestyle projects) |