使用Jest對原生TypeScript項目進行UI測試

前戲

最近寫了一個 wechat-colorpicker 小項目。 主要是爲了練習下TS。既然寫了一個小庫,我就想着順便學下如何寫測試吧,這是一件蠻有意思的事情。javascript

從選型到搭建環境,前先後後用了近2個小時。不得不說一個合格的前端必然是一個合格的配置工程師。再次列舉下,這個項目中所須要搭建配置的工具。css

  • webpack.config 自動編譯ts+css
  • tsconfig.config ts的配置文件
  • tslint.json tslint的配置文件
  • jest.config 配置jest
  • .babelrc jest解析js時還會須要用到的插件
  • circle.yml CircleCI 配置文件

若是你們有什麼不懂的,自行百度html

Jest + TS 入門

第一個問題,我項目都是TS寫的,天然會有 import 這樣的語法怎麼辦?

經過官網的Getting started 咱們能夠在最下方找到 ts-jest 不難理解,咱們須要配的其實就是jest加載到什麼樣類型的文件,使用什麼預處理來處理文件。前端

transform: {
    '.*\\.(ts)$': '<rootDir>/node_modules/ts-jest/preprocessor.js',
},
複製代碼

transform 就是專門用來匹配各類文件後綴,而後進行對應的預處理,你能夠理解爲webpack裏的loadervue

我在TS中引入了.css文件咋辦?同上

既然有transform,那咱們任何文件均可以經過transform進行預處理了。java

transform: {
    '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
    '.*\\.(ts)$': '<rootDir>/node_modules/ts-jest/preprocessor.js',
    '^.+\\.(css)$':"<rootDir>/node_modules/jest-css-modules"
},
複製代碼

若是是js文件我經過babel-jest處理,css則使用jest-css-modules。假如沒有這些配置,那import了你的庫,庫裏有引入了高特性的js文件,或者css文件就會編譯報錯。node

關於rootDir

在進行技術選型的過程當中,我看了最新版本的vue-cli裏推薦用哪些框架進行測試,一個是jest,還一個是krama+mocha。 我選擇了jest,jest自己是fb出的,對於react很是友好。自己也作了許多環境上的封裝切換jsdom環境或者node環境很是方便。我最後選擇了這個。react

剛剛開始看vue-cli裏的jest配置我是拒絕的,第一個最顯眼的關鍵字就是<rootDir>這種像XML得東西。可是你慢慢靜下心來去理解就很容易了,其實就是一個basePath的感受。咱們能夠看下文檔怎麼說 rootDirjquery

個人目錄以下webpack

--- __test__
    jest.config.js
--- dist
--- node_modules
--- src

複製代碼
//jest.config.js
module.exports = {
      rootDir: path.resolve(__dirname, '../'),
}
複製代碼

<rootDir>其實就表明根目錄了

setupFiles 選項

setupFiles是一個AOP的配置,我以爲這個很是好用!由於jest是經過jsdom是模擬了一個document的執行環境,那必然還有不少多是沒有的,好比localStorage,那咱們能夠經過該配置來設置咱們啓動前,須要加載什麼,好比vue-cli中就是設置了Vue.config.productionTip = false,而咱們可讓環境支持localStorage。

setupFiles: ["jest-localstorage-mock"]
複製代碼

不難發現,其實jest的生態仍是很豐富的,我本次遇到的問題谷歌幾個關鍵字很快都能解決

UI Test 該怎麼寫?

test應該是像純函數同樣保證輸入輸出都是同樣的,UI test一方面與Dom耦合,另外一方面又用戶交互耦合,那具體應該怎麼寫呢?

思路是:模擬用戶操做,再經過Dom進行判斷是否渲染正確。

好比這個實例化的測試,咱們能夠測試是否初始化是否正常,經過jquery來輔助判斷

// 實例化測試
import WeChatColorPicker from '../src';
import $ from 'jquery';

export function newInstance() {
  document.body.innerHTML = `<div id="container"></div>`;
  return new WeChatColorPicker(pickerOptions);
}

const baseColorArr = [ ... ];

test('test new instance', () => {
  const instance = newInstance();
  expect(instance.baseComponent.baseColorArr).toEqual(baseColorArr);
  expect($('.wechat-colorpicker')).not.toBeNull();
});

複製代碼

好比這個是點擊【基本色】【更多顏色】咱們會切換class,那就能夠像這樣

// tab class切換的交互測試
import $ from 'jquery';
import { newInstance } from './utils';

describe('change tab test', () => {
  newInstance();
  test('use base color', () => {
    $('.wechat-picker-box p i').eq(0).click();
    expect($('.wechat-colorpicker').hasClass('base-color')).toBe(true);
  });

  test('use picker', () => {
    $('.wechat-picker-box p i').eq(1).click();
    expect($('.wechat-colorpicker').hasClass('more-color')).toBe(true);
  });
});
複製代碼

是否是忽然就以爲很是簡單了?而且是惟一性的,測試用例可靠性也有保障。 以後咱們就只須要配合一個CI,每次提交前跑一邊咱們的測試代碼,全部用例測試成功便可pr,不然直接被拒絕。

寫完了測試,給咱們的jest.config 多加一行配置,來生成咱們的測試報告(Jest內置了istanbul)

module.exports = {
  // ...
  collectCoverage: true,
  // ...
}
複製代碼

接着執行下 npm t 查看測試結果以下

wechat-colorpicker-06

  • % Stmts 是語句覆蓋率(statement coverage):是否每一個語句都執行了?
  • % Branch 分支覆蓋率(branch coverage):是否每一個if代碼塊都執行了?
  • % Funcs 函數覆蓋率(function coverage):是否每一個函數都調用了?
  • % Lines 行覆蓋率(line coverage):是否每一行都執行了?

更多測試用例前往 >>> repo-wechat-colorpicker <<< 查看

CricleCI(番外篇)

咱們能夠經過CI的工具來完善咱們的wordflow,在這我選用了CricleCi。進入官網咱們直接github登入後,setup 咱們的項目。

wechat-colorpicker-02

而後根據它的推薦走,在咱們項目根目錄添加一個cricle.yml,複製黏貼它的推薦配置便可。

而後咱們push測試一下,在這裏我寫錯了個人文件路徑,因此構建報錯了。

wechat-colorpicker-03

從新修復了問題後,就能夠正常運行工做了。

wechat-colorpicker-04

因爲本文不是重點介紹CI,這裏就不過多展開了,有興趣的朋友能夠本身摸索下

後面真的沒有了

至此,你應該對前端UI測試應該大體有一個宏觀的瞭解。

本文沒有過多得介紹Jest的用法或者語法,但願能夠給不知道如何作測試的朋友們一點方向,本身去嘗試找到適合本身項目的纔是最好的。

剛剛開始可能很難,無從下手,成本很大。實際上作起來,其實都是慢慢的套路,寫熟練了後應該會上癮,畢竟最後跑完測試的那感受會讓你達到高潮。

相關文章
相關標籤/搜索