This project is part of the tutorial BDD with Angular and CucumberJs
BDD (Behavior Driven Developement) became more common these years specially with Scrum teams since it gives more agility between product owners (and functionnal people) and the develpers.
One of the best tool to achieve BDD is cucumber along with its syntax called gherkin it gives an easier way to accomplish BDD.
The gherkin syntax looks like this :
Scenario: Some determinable business situation
Given some precondition
And some other precondition
When some action by the actor
And some other action
And yet another action
Then some testable outcome is achieved
And something else we can check happens too
Since this example is focused on Angular a we will use CucumberJS along with Protractor and the framework protractor-cucumber-framework
We will start first by creating a simple Angular counter app.
We will do so just by changing the app component of the deault app generated with the angular cli via the command ng new angular-bdd
to the following:
<h3 id="counter">{{ counter }}</h3>
<button id="increment" (click)="increment()">INCREMENT</button>
<button id="decrement" (click)="decrement()">DECREMENT</button>
And
import { Component } from "@angular/core";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.sass"]
})
export class AppComponent {
counter = 0;
increment(): void {
this.counter++;
}
decrement(): void {
this.counter--
}
}
To install Protractor you can follow the official documentation found in : protractortest.org.
Running the following commands will do it :
npm install -g protractor
webdriver-manager update
ng e2e --port 4201
Angular should have created a test file called app.e2e-spec.ts with a test named should display welcome message. You can modify that test to the following to test if everything is working fine (We will keep the default configuration for Protractor provided by Angular CLI):
it('should have AngularBdd as a title', () => {
page.navigateTo();
expect(browser.getTitle()).toEqual('AngularBdd');
});
To use Cucumber with Protractor we are going to use this plugin : protractor-cucumber-framework. We can install it via the command :
npm install --save-dev cucumber
npm install --save-dev protractor-cucumber-framework
Now we can follow the official documentation of the protractor-cucumber-framework and configure our protractor.conf.js like the following :
exports.config = {
// set to "custom" instead of cucumber.
framework: 'custom',
// path relative to the current config file
frameworkPath: require.resolve('protractor-cucumber-framework'),
// require feature files
specs: [
'./src/specs/*.feature' // accepts a glob
],
cucumberOpts: {
// require step definitions
require: [
'./src/steps/*.steps.ts' // accepts a glob
]
}
};
You can see that in the specs section we are only targeting the .feature files. Those files are used by cucumber to describe the app's behavior, so let's go ahead and create a simple one (app.feature) :
Feature: Increment the counter
This feature lets a user increment the counter by clicking on the button.
Scenario: Basic increment scenario
Given I am on the home page
When I click on the increment button 5 times
Then The counter should show 5
Now let's run our ng e2e
command.
As you can notice you will get a bunch of undefined warnings from cucumber, this basically tells us that what Protractor can't translate what we just wronte in Gherkins, which is normal since in a scrum environment the product owners/functionnals are the ones who write this files in human language then comes the role of somone with some programming language to translate those. Let's do that.
Cucumber actually helps us by suggesting the methods that needs to be implemented in the output, all we have to do is create a new file under e2e/steps (let's call it app.steps.ts)
// Import the cucumber operators we need
import { Before, Given, Then, When } from 'cucumber';
import { AppPage } from 'e2e/src/app.po';