WoJ
  • Blog
  • About Jim

A place to obtain the wisdom of Jim.

How NOT to Set Up CucumberJS with Your AngularJS Project

7/2/2016

Comments

 
Cucumber is a fantastic tool for writing automated BDD tests in the Gherkin language. Similar to unit testing and e2e testing, Cucumber builds on them to give you another level of testing- this one much easier for other team members to read and understand. I began this blog post soon after venturing off to implement cucumber.js into my project. Let's just say I didn't go down the absolute best path (hehe), and so this guide is really not the recommended way to use cucumber.js in an AngularJS application. If you're interested in doing it right, check out Setting Up Protractor to Run The Cucumber.js Testing Framework. If you are just curious what's so bad about this way and why it's "wrong" then keep reading! :)

Step 0. Create an AngularJs Project!

Cucumber is just a testing library that you bring into an existing project. If you have an Angular 1.X application that you want to start testing with CucumberJS, you can just use that (although you might one do try it on a practice project first). If you don't have a project or just want to create a new one just for this, I recommend using a yeoman generator to scaffold out a boilerplate project. My favorite generator is Gulp-Angular on 1.5, but this should in theory work for any angular project. 
yo gulp-angular DESIRED_MODULE_NAME
You could also add the --skip-install flag if you want to, but then you have to run npm install and bower install​ after it finishes. 

Step 1. Install Cucumber Via NPM

Cucumber is a library for BDD testing many different languages: Java, .Net, ruby, JavaScript, and the list continues. Npm is a package manager for JavaScript stuff so when we say "npm cucumber" we know that this is the CucumberJS project. We'll add the --save-dev flag here since cucumber is just a development dependency and isn't needed for our final code that get's pushed to production.
npm install cucumber --save-dev

Step 2. Create a "Features" Folder

You can run the cucumber.js file to execute your .feature files from inside the node_modules/cucumber folder that was just downloaded. You can run cucumber like this:
./node_modules/cucumber/bin/cucumber.js 
If you do this immediately after installing it then you should see error telling you that you're missing a 'features' directory:
Picture
We can fix this by just making a folder called features. From the command line you can do it like this:
mkdir features
And then your directory structure should look something like this:
Picture

Step 3. Get a Clean Run With No Scenarios

Now that you have the features folder in place if you run the cucumber command then you should get an output with no erros that just says you have no scenarios:
Picture
Nice! Ok, it's nothing to write home about just yet, but it's progress! Let's add a feature and scenario now.

Step 4. Add a Feature File

The next step is to make your first .feature file. These can be anywhere in the features folder, even in subdirectories. This is the Gherkin syntax that is so key to behavior-driven development. WebStorm will recognize Gherkin and the .feature suffix, giving you nice syntax highlighting right out of the box. In this file you will normally have a single Feature with many Scenarios to describe it. Here's an example that you can just copy into your feature file if you wanted to:
  Feature: The Phrase "Hello World" shows up on the page when site first loads.
    In order to fulfill my desire to see the "Hello World" message
    As a user of the app
    I want to see the "Hello World" message when the app loads.
    

    Scenario: "Hello World" is displayed.
      Given the user is not currently at the site
      When the user lands on the site
      Then it should display the message "Hello World"

Step 5. Create a "World"

This is slightly confusing at first, but in cucumber.js there is a concept of a "World" that basically just ties everything together and allows you to run some initially code before any of the tests run if you choose to do so. It's customary to put the file defining the world in a folder called "support"
Picture
function World() {
  console.log('world running.');
}

module.exports = function() {
  this.World = World;
};

Step 6. Create a Step Definition File

Next, we create a step definition file. This is the bread a butter of cucumber.js since it's what allows your feature files to have real meaning and actually be executing against the application code. You don't have to suffix them with ".step.js", but I think it's a good practice to do so even if it's only to quickly understand the purpose of the file when scanning through your project explorer. 
Picture
We can then fill in the steps. We simple export a function that references "this", our world from before, Then we can add the Given, When, Then methods.
module.exports = function () {

  this.Given(/^the user is not currently at the site$/, function (callback) {

      callback.pending();

  });

  this.When(/^the user lands on the site$/, function (callback) {


    callback.pending();
  });

  this.Then(/^it should display the message "Hello World"$/, function (callback) {

    callback.pending()

  });

};

The Trouble With This Method

Ok, here's where things get a little hairy. So, in our example we're at the point basically where we want to start implementing these step definition methods. Inside the given we'd probably do some set up code, get references to our variables. Then in the when we can do something to change our system, to do the actual thing whose effects we want to test. Then in the then we can do some assertions. So, it's not too difficult to bring in chai / mocha to o sort of unit test-style testing. However, imo this "low level acceptance testing" is better done with protractor or some selenium-based testing framework. This is because when you write the feature files you are talking in terms of high-level things you can do in the app. The Gherkin is very much like stories from a user's perspective, and protractor testing is very similar to automating using the app from a user's perspective, while unit testing is more concerned with testing individual methods that looking the project as a whole, interactive application. I wasn't able to figure out how to add in protractor into this setup. Luckily however, instead of adding in protractor to our cucumber.js setup we can add in cucumber.js to our protractor setup. This involves changing the protractor.conf. If you're interested in doing this right, check out my other blog post! :)   
Comments
comments powered by Disqus

    ​Author

    Picture
    The posts on this site are written and maintained by Jim Lynch. About Jim...

    Categories

    All
    Actionscript 3
    Angular
    AngularJS
    Automated Testing
    AWS Lambda
    Behavior Driven Development
    Blogging
    Business Building
    C#
    C / C++
    ClojureScript / Clojure
    Coding
    Community Service
    CS Philosophy
    Css / Scss
    Dev Ops
    Firebase
    Fitness
    Flash
    Front End
    Functional Programming
    Git
    Go Lang
    Illustrations
    Java
    Javascript
    Lean
    Life
    Node.js
    Planning
    Productivity
    Professionalism
    Python
    React
    Redux / Ngrx
    Refactoring
    Reusable Components
    Shell Scripting
    Swift
    Test Driven Development
    TypeScript
    Useful Sites
    Useful Tools
    Video
    Website Development
    WebStorm
    Writing

    Archives

    April 2018
    March 2018
    February 2018
    January 2018
    December 2017
    November 2017
    October 2017
    September 2017
    August 2017
    July 2017
    May 2017
    April 2017
    March 2017
    February 2017
    January 2017
    December 2016
    November 2016
    October 2016
    September 2016
    August 2016
    July 2016
    June 2016
    May 2016
    April 2016
    March 2016
    February 2016
    January 2016
    December 2015
    November 2015
    October 2015

    RSS Feed


WoJ © 2015 - 2016
  • Blog
  • About Jim
✕