搞定用TypeScript寫Protractor測試,陸續參考一些範例,發現蠻多人偏好使用Chai程式庫。原本Protractor預設的寫法expect(foo).toEqual(5),改用Chai之後變成:

  • expect(foo).to.be.a('string');
  • expect(foo).to.equal('bar');
  • expect(foo).to.have.length(3);
  • expect(tea).to.have.property('flavors') .with.length(3);

寫程式像在講話,幾乎就等同BDD Feature裡Then的口語描述,我猜想這是Chai受歡迎的原因。例如以下的BDD Feature範例:

Scenario:Add two numbers
    Given I have entered 50 into the calculator
    Then I have entered 70 into the calculator
    When I press add
    Then the result should be 120 on the screen

言歸正傳,要在Protractor改用Chai語法,可在conf.js的onPrepare()用require動態載入chai及chai-as-promised模組,將global.expect換掉(細節可參考Paul Li的介紹):

exports.config = {
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['lab1.spec.js'],
    onPrepare: () => {
        var chai = require('chai');
        var chaiAsPromised = require('chai-as-promised');
        chai.use(chaiAsPromised);
        global["expect"] = chai.expect;
    }
};

回到TypeScript,要讓Visual Studio認得Chai的to.equal()這種語法,就必須載入cha.d.ts及cha-as-promised.d.ts兩個定義檔。老樣子,用Manage NuGet Packages或Package Manager Console安裝chai-as-promised.TypeScript.DefinitelyTyped,它會一併安裝chai.TypeScript.DefinitelyTyped,定義檔就備齊了。

由於chai及chai-as-promised為node.js的外部模組(External Module),應用時跟平常網站TypeScript使用<script src="…">載入的概念有點不同,想深入了解的同學可以參考TypeScript官方文件,這裡只會提到滿足測試撰寫的必要做法。

node.js透過require("…")方式動態載入元件,對應到TypeScript要寫成import chai=require("chai"),由於chai.d.ts只有定義檔不包含實作,故這個import指令目的在匯入chai.d.ts的型別宣告,作用類似宣告/// <reference path="…" />,不會產生實際的JavaScript指令(測試腳本實際上也不需要載入chai,真正的載入及設定動作是在conf.js onPrepare()完成)。

要使用import,專案的TypeScript編譯選項要做些調整,Module System需選擇CommonJS:

接著,我們要宣告declare var expect: Chai.ExpectStatic,將全域變數expect函式定義成Chai版的expect,以便使用Chai的is.equal()串接語法。跟import指令一樣,declare指令不產生JavaScript,只決定TypeScript撰寫階段的變數型別。

還有一個小問題,在Protractor裡,expect()應傳回Promise形式的Assert函式,故得寫成is.eventually.equal()。故一開始的import指令要改成import chaiAsPromised = require("chai-as-promise"),Visual Studio才認得expect().is.eventually.equal()。

完整測試程式碼如下:

import chaiAsPromised = require("chai-as-promised");
declare var expect: Chai.ExpectStatic;
 
describe('Protractor Demo App', function () {
 
    var firstNumber = element(by.model('first'));
    var secondNumber = element(by.model('second'));
    var goButton = element(by.id('gobutton'));
    var latestResult = element(by.binding('latest'));
 
    beforeEach(function () {
        browser.get('http://juliemr.github.io/protractor-demo/');
    });
 
    it('should have a title', function () {
        expect(browser.getTitle()).is.eventually.equal("Super Calculator");
    });
 
    it('should add one and two', function () {
        firstNumber.sendKeys("1");
        secondNumber.sendKeys("2");
        goButton.click();
 
        expect(latestResult.getText()).is.eventually.equal("3");
    });
 
});

總算Visual Studio也認得to.eventual.equal()的chai-as-promise語法,編譯成功,收工!


Comments

Be the first to post a comment

Post a comment