Introduction to an Angular Scenario DSL for Remote Node Backend Configuration

This post was written by Andreas Marek (@andimarek) and Daniel Bechler (@SQiShER).

In this article we’d like to introduce you to a library called node-config-ngscenario-dsl, which is our solution for advanced E2E testing with AngularJS and Node. This article may be interesting for you, if you are looking for a way to configure your Node backend right from your E2E tests.

We are currently developing our first project with AngularJS. It’s a new module in a larger application and consists of an AngularJS frontend and a Java backend.

Our team of six developers is highly „test infected“, so having a good test coverage was extremely important to us. Since this was our first AngularJS app, we spent quite some time figuring out how to properly test certain aspects of our application. As a result, our test suite consists of many unit tests, some semi-integrated directive tests and just a few E2E tests.

For the E2E tests (and the sake of easier local development), we created a Node.js server to simulate the „real“ Java backend. This worked great for most of our test cases, but we soon discovered that we needed more flexibility in order to test the behaviour of our client application in error scenarios like connection timeouts, bad responses, etc. So we needed to find a way to control the behavior of the Node server right from our E2E tests.

Our solution consists of two parts: a DSL extension for Angular Scenario and a small Node module, which provides the server-side interface used by the DSL. The easiest way to get it up and running looks like this:

/*
* Setup your express app
*/
var express = require('express');  
var app = express();

// this line is important for proper JSON handling
app.use(express.bodyParser());

/*
* Register the node-config-scenario-dsl express handlers
*/
require('node-config-ngscenario-dsl').setup(app);

/*
* Expose the express app
*/
var http = require('http');  
var server = http.createServer(app);  
server.listen(2888);  

As you can see, this is just a simple express app. Our node module is registered with the server by using the setup method. This method simply registers some additional request handlers to allow our Angular Scenario DSL extension to configure the server remotely.

Executing the code will start a new web server with the required configuration interface. For simple use cases, that's probably all you need. In our case we went a step further and created some request handlers to make the server respond properly to incoming requests to all of our backend services. In other words, we configured our Node server to return valid data by default. This allows us to use the Node server as a stand-alone replacement for the "real" backend, making it very easy to do manual frontend testing without the need to modify and restart our Java backend.

As great as this server is for manual testing, its true power unfolds in the E2E tests. Our static request handlers already allowed us to automatically test how the app behaves when the server returns "good" responses. But what about the cases when those requests fail? How could we test that our UI displays an error dialog, when a request times out? How could we verify that log messages get sent to the backend, when JavaScript errors occur? After all, we want the server to behave nicely by default, but we also want to have the option to trigger "bad" behaviour.

That's where our Angular Scenario DSL comes into play. Let's say, we want to test that our app displays an error dialog if an HTTP request returns status code 500. With our library we can temporarily modify the server to do just that:

// set up a response handler
server().onRequest({ method: 'GET', url: "/dummyRequest" })  
        .respondWith(500, { data: "Some error });

// for simplicity let's just assume the request is performed 
// whenever the frontend gets loaded:
browser().reload();

// run the test
expect($(".error-dialog")).toBeVisible();

// restore the original state
server().clear();  

And that's all there is to it!

The DSL also offers ways to prevent request handlers from ever responding, verify how often certain requests were made and, of course, to override existing with custom request handlers. These options combined already allowed us to test pretty much everything we could think of. But we're sure we'll come up with some more, as our project grows. To learn more about the API, have a look at our API documentation.

node-config-ngscenario-dsl is licensed under the Apache License, Version 2.0 and can be found on Github. To see it in action, take a look at our example project.

We would appreciate your feedback!