Written by Jason Strimpel, Staff Software Engineer, @WalmartLabs
I’m a developer for a branch of @WalmartLabs in Carlsbad, Calif. (San Diego area), and one of the pain points we share with the community is unit testing AMD code bases. That’s why our team developed grunt-castle, a unit-testing Grunt plugin for AMD client, server, and client-server code bases. The plugin eases the pain of unit testing AMD code bases by reducing specification boilerplate, auto-resolving of paths, and auto-wiring and configuring other open source libraries.
What it does
If you have unit tested an AMD code base before, you know first-hand the challenges it presents. For those who have not, I highly suggest reading Effective Unit Testing with AMD by Mike Pennisi.
In addition to solving the issues Mike outlines grunt-castle wires together several open source projects required for automating the testing of client-server AMD code bases. If you are starting from scratch figuring out how to put these pieces together, configure them, and wrap them up with a convenient API can be challenging. When we set out to write grunt-castle there were four main requirements that we used as guidelines. Remember it does the following for both environments!
- Mocking: Another major pain point we had was mocking dependencies. We wanted the ability to easily mock a dependency anywhere in the dependency tree by simply providing a module id. Grunt-castle does this via a lightweight wrapper that proxies to Squire.js. Additionally, we wanted to be able to mock global objects and have these global objects cleaned up between each test and specification to prevent problems with specifications corrupting global objects and breaking tests in subsequent specifications. Grunt-castle does this by automatically creating a fresh copy of global objects that have been mocked between tests.
- Path Resolution and Automation: Path issues can be quite challenging when it comes to unit testing AMD code. We wanted these issues automatically resolved, which is exactly what grunt-castle does. It uses the Grunt task configuration to resolve application and mock paths. It then uses these paths to configure RequireJS and load mocks, so that all you have to do is provide a module id. We also did not want to have load supporting libraries such as Chai or Sinon-Chai for each specification, so grunt-castle does this and makes them automatically available in specifications. We did not want to have to create HTML wrappers and worry about configuring paths correctly for the client either, so grunt-castle automatically generates HTML versions of all your specifications.
- Code Coverage: Our last requirement was generating code coverage reports. We needed the ability to easily instrument code and generate LCOV reports that could be consumed by an internal reporting tool. We also wanted to generate HTML coverage reports that we could view locally to find coverage gaps. Grunt-castle does this by using the Mocha json-cov reporter and converting the results to LCOV. For the local reports it uses the Mocha coverage reporting templates.
Getting started with grunt-castle is a breeze. If you are not familiar with Grunt then I advise reading the Getting Started guide first. For those of you who are familiar with Grunt already I created an example project that will have you unit testing AMD code with grunt-castle in three easy steps.
Things to Come
Grunt-castle was built to abstract and encapsulate processes that we found necessary for unit testing a client-server web framework. Because of this the plugin’s scope became too large. In the future we would like to limit the plugin’s scope to running unit test and generating output via Mocha reporters. For instance, the instrumentation of code should not be the responsibility of grunt-castle, so this will likely be removed.
This was the first Grunt plugin anyone of the team has authored and our previous experience with Grunt is limited, we’re always looking for open source contributors who are Grunt plugin experts from the community to help improve grunt-castle.