單元測試(二)
上次談了用 chai
和 chai-spies
來進行單元測試,但是這種測試方法存在著一些不方便之處,每次改動程式碼之後都需要重新整理瀏覽器,開啟開發者工具,來檢視有沒有報錯。
那麼,有沒有一種方法,使這些流程自動化,自動將測試的結果輸出到某個可見的地方(例如:終端)?這次就來嘗試完成這個過程。
用到的工具
這次我們需要用到:
- Karma:卡瑪是一個測試執行器,它可以呼起瀏覽器,載入測試指令碼,然後執行測試用例。
- Mocha:摩卡是一個單元測試框架/庫,它可以用來寫測試用例。
- Sinon:西農是一個 spy / stub / mock 庫,用以輔助測試。
安裝
執行下面的命令安裝工具。別一個一個地看包名了,全都安裝就完事了。 npm i -D karma karma-chrome-launcher karma-mocha karma-sinon-chai mocha sinon sinon-chai karma-chai karma-chai-spies
配置 Karma
新建一個 karma.conf.js,並將下面的內容複製進去。
module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '', // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['mocha', 'sinon-chai'], client: { chai: { includeStack: true } }, // list of files / patterns to load in the browser files: ['dist/**/*.test.js', 'dist/**/*.test.css'], // list of files / patterns to exclude exclude: [], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: {}, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress'], // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes autoWatch: true, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['ChromeHeadless'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: false, // Concurrency level // how many browser should be started simultaneous concurrency: Infinity }); }; 複製程式碼
重寫測試用例
新建一個 test 資料夾,並在裡面建立一個 button.test.js
的檔案,接下來將在這個檔案裡面重寫測試用例。
const expect = chai.expect; import Vue from 'vue'; import Button from '../src/button'; Vue.config.productionTip = false; Vue.config.devtools = false; describe('Button', () => { it('存在.', () => { expect(Button).to.be.ok; }); it('可以接受 color 作為類名', () => { const div = document.createElement('div'); document.body.appendChild(div); const Constructor = Vue.extend(Button); const vm = new Constructor({ propsData: { color: 'red' } }).$mount(div); const element = vm.$el; //我斷言這個生成的 button 有一個類名叫 'red' 為真 expect(element.classList.contains('red')).to.eq(true); vm.$el.remove(); vm.$destroy(); }); it('點選 button 觸發 click 事件', () => { const Constructor = Vue.extend(Button); const vm = new Constructor({ propsData: { color: 'red' } }).$mount(); //間諜函式 const callback = sinon.fake(); vm.$on('click', callback); vm.$el.click(); expect(callback).to.have.been.called; }); }); 複製程式碼
和之前的測試用例類似,就稍微改變了結構。
建立測試指令碼
為了方便啟動,我們將啟動命令寫到 package.json
裡面。
"scripts": { "dev-test": "parcel watch test/* --no-cache & karma start", "test": "parcel build test/* --no-minify && karma start --single-run" } 複製程式碼
談談兩個命令中的兩個引數的意義。
parcel <slot></slot>
使用
執行一次檢視結果
如果只想看看測試用例的結果就執行下面的命令。 npm run test

從圖中的執行結果可以看出,在輸入這個命令之後,會進行元件打包、讀取測試用例檔案、開啟伺服器、啟動瀏覽器、執行測試用例等等一系列操作,最後將執行結果輸出。圖中顯示一共有3個測試,通過了3個,也就是測試用例全部通過。
監測測試結果
如果想隨時地監測測試用例檔案的執行結果就用這個命令。 npm run dec-test

它啟動之後,會先輸入當前測試用例的執行結果,然後進行監測,當測試用例檔案傳送變化時,它就會再一次的執行並輸入結果。
我們嘗試將測試顏色作為類名的測試改一下。
it('可以接受 color 作為類名', () => { const div = document.createElement('div'); document.body.appendChild(div); const Constructor = Vue.extend(Button); const vm = new Constructor({ propsData: { color: 'black' } }).$mount(div); const element = vm.$el; //我斷言這個生成的 button 有一個類名叫 'red' 為真 expect(element.classList.contains('red')).to.eq(true); vm.$el.remove(); vm.$destroy(); }); 複製程式碼
來看看終端有什麼變化。

這裡我們看到又運行了一次測試用例,顯示有一個測試失敗了,也就是我們剛剛改的那一個。
我們可以利用這個功能,來協助我們來寫測試用例。
如何更自動化?
雖然我們現在能夠在本地開啟監聽服務,隨時檢查測試用例的通過情況,但是還是要手動地開啟服務。
那麼,有沒有一種辦法,在雲端自動進行測試呢?下次來講講將程式碼上傳至 Github 後,利用雲服務自動測試程式碼,並將結果通知給我們。