In a previous blog post, I described how I took Emscripten-created JS and turned it into an UMD module. One of the reasons I did this was because I wanted more control over the generated JavaScript and for it to be usable in more contexts, such as with the RequireJS module loader.
As I am a responsible developer, I desired to create a number of automated unit tests to ensure that the client-visible API for my Emscripten module works as I intended. I began by searching for a browser automated test framework and settled upon Nightwatch.js. Now I just had to figure out how to get Nightwatch.js tests running in my existing, CMake-based build system. Here’s how I did it.
Configurig Nightwatch.JS
In order to use Nightwatch.JS, you must first configure it by creating a file called nightwatch.json. The first major decision you need to make is which WebDriver-implementing system you wish to use. Most users use Selenium, but you can also run an individual browser driver directly.
As I was not concerned with cross-browser compatibility – I assume that if the test works on one browser it will work on all major browsers – and I was looking for a system with a minimum number of build-time dependencies, I decided to use ChromeDriver automatically as my WebDriver implementation.
To make everything work, I did the following:
To automatically download chromedriver, add the following to CMakeLists.txt:
To configure Nightwatch.JS to use chromedriver, create a nightwatch.json which looks like this (the purpose of nightwatch-globals.js will become clear shortly):
CMake will run the unit tests from ${CMAKE_CURRENT_BINARY_DIR}, so we’ll need to copy the above config files to ${CMAKE_CURRENT_BINARY_DIR}. Here’s how to do that:
You may want to separate your tests into multiple JavaScript files and execute them independently. Here’s one way to do that from CMake:
1
2
3
4
5
6
7
8
9
10
file(GLOBTESTCASE_SRCtests/*.js)foreach (testPath${TESTCASE_SRC})get_filename_component(testName${testPath}NAME_WE)# Test all unit tests
add_test(
NAMEbrowser_${testName}COMMAND./node_modules/nightwatch/bin/nightwatch-t${testPath} )endforeach()
Using Local Web Server when Running Test Cases
In certain cases, your unit tests be able to refer to local file: URLs, but things tend to be a lot easier if your unit tests reference URLs from a local web server. It’s really easy to get one up and running:
Download Node’s http-server module by adding the following to your CMakeLists.txt
Once this is done, your tests can refer to http://localhost:8080.
Note that http-server reads files from the current working directory, and CMake runs unit tests from ${CMAKE_CURRENT_BINARY_DIR}, so you may need to copy your test HTML and JavaScript to ${CMAKE_CURRENT_BINARY_DIR}. Here’s some CMake code which you might find helpful:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Copy all .HTML files to binary directory
file(GLOBHTML_SRC*.html)foreach (htmlPath${HTML_SRC})get_filename_component(htmlFileName${htmlPath}NAME)# Copy HTML to binary folder so they can be referred to by the test
add_custom_command(
OUTPUT${CMAKE_CURRENT_BINARY_DIR}/${htmlFileName}COMMAND${CMAKE_COMMAND}-Ecopy${CMAKE_CURRENT_SOURCE_DIR}/${htmlFileName}${CMAKE_CURRENT_BINARY_DIR}/${htmlFileName}DEPENDS${CMAKE_CURRENT_SOURCE_DIR}/${htmlFileName} )add_custom_target(
browser_copy_${htmlFileName}ALLDEPENDS${CMAKE_CURRENT_BINARY_DIR}/${htmlFileName} )endforeach()