How to write ATDD tests with cucumber-js, protractor and typescript
ATDD (Acceptance Test Driven Development) has been around for a while now. I use it quite a lot on projects that I work on. It helps me and others translate requirements into automated tests with the minimum amount of ceremony. We can talk to users about what they want and write that down in a format that they understand and we can automate.
What is cucumber and why should I care?
For those that don't know cucumber or ATDD for that matter. Cucumber is framework that allows you to write feature files. A feature file looks like this:
The idea behind ATDD is that you define acceptance tests in a readable format and automate them using code so that you don't have to execute them manually everytime you want to validate the functionality of your application.
Using a readable format for your users helps you create a common understanding of what the application does for the user. Automating these specs into runnable tests closes the gap between the requirements and the tests. Often times people write specs and create a separate set of tests. The problem with this is that the tests tend to drift away from the original spec. This causes bugs that could easily be avoided if you make the specs the tests.
Setting up cucumber with protractor
In order to write acceptance tests for Angular 2 or AngularJS you need to use protractor. Protractor is a tool that links your tests to a webdriver which ultimately links your tests to a browser. This is useful since you can now navigate to a page in the application and communicate with the DOM. That way you can validate your app by querying if the right HTML elements were shown and much more.
To set protractor up you need to install the following NPM packages on your machine:
You can install these with the following command:
Make sure that you update the webdriver-manager after you installed it by running
This will download the proper webdriver files for you so you can start running tests against the various supported browsers such as IE, Chrome and FireFox.
Next create a new protractor configuration file in your angular project.
The file should point to the feature files in your project. I put those in the
folder, but you can place them somewhere else if you like. Next you need to set the framework
to custom and point protractor to the cucumber-js framework using the frameworkPath setting.
Make sure that you install the protractor-cucumber-framework as part of your project using the following command:
Check your configuration by executing
protractor protractor.conf.js. If you have
a feature file in your project you should see protractor spin up a browser and spit out
a bunch of text on the console about your feature file. This usually should involve
a couple of green and yellow lines of text. The green lines show steps in the feature
files that were executed. The yellow lines show steps that aren't implemented yet.
Automating feature files with typescript
You include them in the protractor config file by specifying a setting called
Typescript offers a much better way of defining step definitions for cucumber-js. But you have to do a little work for it to function properly.
First you need to install the
cucumber-js-tsflow packages in your project
using the following command:
Next you need to modify the protractor configuration so that it includes the following
This configures cucumber so that it looks for step definitions in the
folder and tries to load the typescript files directly from there. The problem is that it
can't load typescript files under normal circumstances. However, you can specify a custom compiler
for the cucumber framework. This is where
ts-node comes in. When you configure cucumber-js to use
the typescript interface from
ts-node it is capable of loading the step definitions.
Time to write some step definitions in typescript:
This looks way easier to read and I can assure you it's much more ergonomic to write. And luckely it is not much work to set up in the end.