On the road to Angular E2E testing — Protractor and Cucumber
I’m working on one project for a while and one day the client came with an idea: ‘Let’s implement E2E tests on frontend’. My first thoughts were: ‘Oh wait, E2E testing in JavaScript? Who does that?’. And after a few hours of researching, I realized there is a bunch of frameworks and libraries for Angular E2E testing and lot of people are using them.
One of the criteria was that these tests are understandable to everyone, from senior developers to managers without a technical background.
We agreed that Behavior Driven Development (BDD) approach is the best for our needs. Behavior Driven Development gives us an opportunity to create test scripts from both the developer’s and the customer’s perspective as well. So in the beginning, developers, project managers, QAs, user acceptance testers and the product owner (stockholder), all get together and brainstorm about which test scenarios should be passed in order to call this software/application successful. This way they come up with a set of test scenarios. All these test scripts are in simple English language, so it serves the purpose of documentation also.
BDD Example:
- the manages should be able to add a new user with all the fields filled
- the manager should not be able to add a new user with a missing email
How it works
First we need to describe the desired behavior in a feature file (to be introduced later), then we have to write step definitions (to be introduced later) and then the test fails (obviously). After some code refactoring, the test passes.
Technology Stack
In the next few lines, I’ll try to explain what we’ll use in a practical part of this post.
Fantastic Four:
- Protractor
- Selenium
- Cucumber
- Gherkin
Protractor is an end-to-end test framework for Angular and AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.
browser.get('https://angularjs.org');
element(by.model('todoList.todoText')).sendKeys('write first protractor test');element(by.css('[value="add"]')).click();
browse
and element
are globals created by Protractor, which are used for browser-level commands such as navigation or fetching and manipulating DOM elements.
Selenium is a browser automation framework. Selenium includes the Selenium Server, the WebDriver APIs, and the WebDriver browser drivers. What Selenium does is maybe the best described on their web page:
Selenium automates browsers. That’s it! What you do with that power is entirely up to you.
Protractor works in conjunction with Selenium to provide an automated test infrastructure that can simulate a user’s interaction with an Angular application running in a browser or mobile device.
Cucumber is a tool for running automated tests written in plain language (Gherkin syntax). Because they’re written in plain language, they can be read by anyone in team. When Cucumber executes a Gherkin step in a scenario, it will look for a matching step definition to execute.
Scenario Login to the app has three steps written in Gherkin syntax:
Scenario: Login to the app
When I go to login page
And I login as a student
Then I should be signed in as a student
Step definition of the step When I go to login page would be:
When('I go to login page', function () {
browser.get('https://mypage.com/login')
});
Expressions in step definition and in scenario step have to be the same, otherwise, we’ll get undefined.
How it works altogether?
When we run a test with Protractor, Cucumber will look for a matching step definition to execute it. The Selenium Server takes care of interpreting commands from the test and forwarding them to the browser. When the app is open, Browser Driver executes our commands and clicking through the app.
So let’s do it together
We’ll create a simple Angular app with a help of Angular CLI.
ng new e2e-test-app
And let’s install all the necessary npm packages.
npm install --save-dev webdriver-manager protractor cucumber protractor-cucumber-framework chai chai-as-promised
We need webdriver-manager to start Selenium server locally. protractor-cucumber-framework
is Cucumber framework plugin for Protractor. And Chai is assertion library which we need because we use custom Protractor framework.
So let’s start local Selenium server, but before starting Selenium server you will need to install the latest Java Development Kit.
webdriver-manager update && webdriver-manager start
We are going to add a new directory where we store all the test files. Under our main directory we have configuration file and two subdirectories — specs and steps. In specs directory we write scenarios and in steps directory we write step definitions.
Protractor configuration
In protractor.conf.js is our main configuration and here we define various things. This is some basic configuration. Here we defined our local selenium address, path to specs files, browser in which we want the tests to run, protractor framework, its path and of course path to step definitions.
Now, we can start writing tests.
First, we write our scenario which we want to test. For this purpose we are going to test angular.io web page. Like scenario says, we go to the angular.io page, click the “Get started” button, wait for page to load and check if page has changed.
And the last step is writing a step definitions for our simple scenario. We do it in the steps folder and do it like this. We have to require Given, When and Then from Cucumber and our assertion library Chai (you can use whatever you want).expect
is e.g. from Chai library.
And that’s it. Simple, right?
Now we are ready to start our test. We do it with protractor custom-e2e/protractor.conf.js
and hope we get all the green dots :)
Summary
This app is some basic example what we can do with Cucumber and Protractor. Of course there is more to do and if you want to know more check Protractor docs and WebDriverJs User Guide. Also, if you want to boost writing tests on a higher level use predefined steps and page objects. It will help you to write tests faster and organize them better.
I hope this article helped you to better understand E2E testing in Angular and that you will start or continue writing tests in your projects :)
Thank you for reading. Feel free to leave feedback and comments.