E2E Testing in Angular with CucumberJS

Devin Kelly-Collins

About me

  • Senior Engineer at Artisan Technology Group
  • Graduated from K-State
  • Experience with C#, Typescript, Ruby, Elm, Angular, Nest, Ionic, ASP.Net
  • Currently playing Monster Hunter World

What this talk will cover

  • E2E Testing
  • Cucumber
  • Testing tips

What this talk will not cover

  • Building your application to be testable
  • Protractor

End to End tests

  • Unit Tests
    • Tests a single piece of the application
  • Integration Tests
    • Tests two or more pieces of the application
  • End to End Tests
    • Tests the entire application will little or nothing mocked out.

Cucumber

  • Built for Behavior-Driven Development
  • Available for many languages
  • Can act as living documentation of application features.

Features

Scenario: easy maths
    Given a variable set to 1
    When I increment the variable by 1
    Then the variable should contain 2

Steps

Then(/^the response status is (.*)$/, function (status) {
  assert.equal(this.responseStatus, status)
});
Then(/^the error output contains the text snippets:$/, function(table) {
  const actualOutput = normalizeText(this.lastRun.errorOutput)
  table.rows().forEach(row => {
    const expectedOutput = normalizeText(row[0])
    expect(actualOutput).to.include(expectedOutput)
  })
})

Hooks

Before(function () {
  // This hook will be executed before all scenarios
});

Before({tags: "@foo"}, function () {
  // This hook will be executed before scenarios tagged with @foo
});

Before({tags: "@foo and @bar"}, function () {
  // This hook will be executed before scenarios tagged with @foo and @bar
});

Before({tags: "@foo or @bar"}, function () {
  // This hook will be executed before scenarios tagged with @foo or @bar
});

// You can use the following shorthand when only specifying tags
Before("@foo", function () {
  // This hook will be executed before scenarios tagged with @foo
});

World

function CustomWorld() {
  this.driver = new seleniumWebdriver.Builder()
    .forBrowser('firefox')
    .build();

  // Returns a promise that resolves to the element
  this.waitForElement = function(locator) {
    var condition = seleniumWebdriver.until.elementLocated(locator);
    return this.driver.wait(condition)
  }
}

setWorldConstructor(CustomWorld)

Demo

Testing tips

  • E2E tests should test the system in broad strokes.
  • Write tests that tell you something meaningful.
  • Listen to your tests. If a feature is hard to test, it is probably hard to use.
  • Tests are a part of your application, treat the test code the same as you would your application code.

Questions?

devin.kellycollins@artisantechgroup.com