[angular2]用bdd的方式來寫e2e ui自動測試(cucumber.js+protractor)

用bdd的方式來寫e2e ui自動測試(cucumber.js+protractor)

前言

其實bdd真的是一種很好的測試模式,尤其是在ui測試上,更是適合用寫規格的方式來做自動測試,有些表單式複雜的互動,光是一個頁面測試案例可能有好幾十種,如果我們可以把這種邏輯互動,經由自動測試保護,就可以節省我們之後手動測試時間,不管是避免忘記測試案例,或者是交給別的member維護,或者是要重構程式碼,用bdd的方式都會非常有幫助,但是angular預設並不是使用cucumber,而是使用jasmine的方式,所以我們必須改一些cli的配置,來符合我們使用cucumber的需求。

導覽

  1. 安裝用到的package和修改cli的配置
  2. 新增e2e的feature並執行測試
  3. cucumber在vs code的extension
  4. 結論

 

安裝用到的package和修改cli的配置

首先就是從npm安裝一下相關需要用到的package了,請在cmd打上如下的指令,安裝必要的package

npm i @types/chai  @types/chai-as-promised chai chai-as-promised cucumber cucumber-tsflow protractor-cucumber-framework  --D

接著我們需要修改protractor.con.js的一些設定,把原本jasmine改成cucmber,示例如下

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts


exports.config = {
  allScriptsTimeout: 5000,
  specs: [
    './e2e/features/*.feature' //這邊對應了我們在e2e所有的feature檔
  ],
  capabilities: {
    'browserName': 'chrome'
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  framework: 'custom', // set to "custom" instead of cucumber.
  frameworkPath: require.resolve('protractor-cucumber-framework'), //這邊則是我們從npm下載的package
  cucumberOpts: {
    require: ['./e2e/features/*.ts'], //這邊則對應了我們寫的ts測試檔
    tags: [], // <string[]> (expression) only execute the features or scenarios with tags matching the expression
    strict: true, // <boolean> fail if there are any undefined or pending steps
    format: ["pretty"], // <string[]> (type[:path]) specify the output format, optionally supply PATH to redirect formatter output (repeatable)
    dryRun: false, // <boolean> invoke formatters without executing steps
    compiler: [] // <string[]> ("extension:module") require files with the given EXTENSION after requiring MODULE (repeatable)
  },
  beforeLaunch: function() {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
  },
  onPrepare() {
    browser.manage().window().maximize();
  }
};

 

新增e2e的feature並執行測試

接著在e2e的資料夾裡面,新增一個features的資料夾,然後我習慣性的是把要測試的feature和ts是放在同一層底下,比如我新增了test.feature和test.steps.ts,資料夾結構如下圖

其實cucumber.js的文法結構跟specflow都是一樣的,只是specflow是.net版的cucumber,那先看一下我要測試的案例

Feature: This is a demo feature
    Scenario Outline: The user go to the sport and seach some value to filter display rows
        Given I open the browser
        When I focus on txtSearch key the '<searchValue>'
        And  I click search button
        Then The rows is '<result>'


    Examples:
    | searchValue | result |
    | abc         | 0      |
    | Ba          | 4      |
    |             | 10     |

因為我們已經是寫ts,所以我們的寫法跟原本的js寫法就不太一樣了,但是跟c#的寫法還挺像的

import { before, after } from 'cucumber-tsflow/dist';
import { browser, by, element } from 'protractor/built';
import { binding, given, when, then } from 'cucumber-tsflow';
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
const expect = chai.use(chaiAsPromised).expect;

@binding()
class TestSteps {

  txtSearch = element(by.id('searchName'));
  searchButton = element(by.id('searchButton'));
  trSports = element.all(by.id('trSports'));


  @before()
  private beforeDo() {
    // test before do something
  }

  @after()
  private afterDo() {
    //test after do something
  }

  @given(/^I open the browser$/)
  private givenIOpenTheBrowser(callback) {
    browser.get('/');
    callback();
  };

  @when(/^I focus on txtSearch key the '(.*)'$/)
  private whenFocusOnTxtSearchKeyThen(text, callback) {
    this.txtSearch.sendKeys(text);
    callback();
  }

  @when(/^I click search button$/)
  private whenClickSearchButton(callback) {
    this.searchButton.click();
    callback();
  }

  @then(/^The rows is '(.+)'$/)
  private thenAssertTitle(text, callback) {
    expect(this.trSports.count()).to.eventually.equal(+text).and.notify(callback);
  }
}

export = TestSteps;

最後我們只要在command line執行ng e2e就會跑起我們所有的測試了,測試結果如下

 

cucumber在vs code的extension

因為feature檔預設是沒有辦法格式化的,所以只好用手動排版的方式,這讓我感到蠻苦惱的,後來讓我找到了兩個vs code的extension,可以幫助我們自動format feature檔,還有intellisense和highlight的功能,分別是Cucumber Full Language Support和Table Formatter

cucumber這個工具可以format我們的step的說明,而table format就是example下的表格部份,底下是示例

 

結論

用人話來描述ui的測試,確實是再適合不過了,也能很大幅度的提升我們開發的品質,希望對需要的人有幫助,有任何更好的想法,也可以再提供給筆者囉