We’ve got a couple apps that use Cesium (one JS+Backbone, the other Java+GWT). Sadly, neither has any actual unit tests, although we’ve finally been working on some automated integration tests for the Backbone app. I’ve been prototyping a potential rewrite of the GWT app in modern JS (Webpack+ES6+React), and currently have a basic unit testing setup in place using Mocha (test runner), Chai (assertions), Enzyme (React component testing), and JSDOM (for actually “rendering” components under Node, without needing a browser). I’ve also got Webpack set up to load Cesium using a variation on the “pre-built” approach described at https://github.com/mmacaula/cesium-webpack (and I may try to document those changes when I have a chance).
At the moment, I’ve got the Mocha setup being done separately from all the Webpack stuff, so Mocha uses Babel to do the transpiling, but then ignores stuff Webpack would load like CSS and images. This worked fine, until I tried running my test setup and it pulled in my initial React component that requires Cesium. I see one error which I may or may not be able to work around, but this actually brings up some larger questions about how to approach testing things that depend on Cesium. I know I’ve also seen suggestions that offline tests with Mocha should be doing by just using Webpack to do an actual build with test-specific entry points and running Mocha against the bundled output, as that would centralize the load/alias/whatever logic. I may give that a shot soon, but trying to see how far I can get with this.
First, the actual error I see at the moment. Because Cesium embeds a copy of Knockout, and depends on Require to load it, Node wound up reporting “Error: Cesium missing ThirdParty/knockout-3.2.0”. I figure there’s probably some way to work around that using some hack-ish approach to modifying Node’s built-in “require” function, but haven’t gotten that far yet. (Any suggestions welcome.)
So the larger question is really this: what is an appropriate way to approach unit testing components that depend on Cesium? This would include, say, a top-level component that is responsible for actually initializing and rendering a Cesium.Viewer widget, or view classes which are responsible for creating and destroying Cesium primitives as part of their lifecycle (we have Backbone Views that render Cesium primitives in our first app, and I’m figuring I can do the same with React Components in the second app). How would I handle having Cesium as a dependency for a given component? Is there a good approach for mocking out Cesium? Can Cesium even do anything useful under Node, particularly with JSDOM or similar, or would I be restricted to purely testing/running code that uses it in an actual browser?
I guess my questions are being driven by a few intertwined thoughts. First is my lack of actual practical experience with writing unit tests, so I’m still mostly trying to figure out what sorts of behavior and tests to write in the first place. The second is trying to put together a specific build configuration using the tooling I’ve selected, particularly Webpack and Cesium. The third is wanting to be able to run tests offline under Node using Mocha, without having to use a real browser or even a headless browser like PhantomJS, for simplicity of dependencies and speed.
I would appreciate any thoughts, suggestions, or comments people have on these issues.