本文介紹了 karma 的入門知識點。javascript
karma 是一個提高測試效率的工具,幫助開發者更好更快速地在多種環境下執行測試代碼,拿到測試結果。在運行的時候,它會自動啓動配置好的瀏覽器,同時也會啓動一個 node 服務器,而後在啓動好的瀏覽器中執行測試代碼,並將測試代碼執行結果傳回給 node 服務器,而後 node 服務器在打印出收到的執行結果。css
能夠經過 npm 安裝 karma :html
// 本地安裝 npm i karma --save-dev // 全局安裝 npm i karma -g
安裝完成以後,切換到目標項目根目錄,運行:java
karma init
這樣就會以嚮導的形式生成 karma 的配置文件 karma.conf.js
,文件內容大體爲:node
// Karma configuration // Generated on Wed Jun 29 2016 23:22:24 GMT+0800 (CST) module.exports = function(config) { config.set({ // 根路徑,後面配置的基本全部相對路徑都會根據這個路徑來構造。 basePath: '', // 使用到的框架 // 目前支持的框架: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine', 'requirejs'], // 將會在瀏覽器裏面執行的代碼 files: [ 'test/main.js', { pattern: 'src/**/*.js', // false 表示初始化的時候不會使用 script 標籤直接將相關 js 引入到瀏覽器,須要本身寫代碼加載 included: false }, { pattern: 'test/**/*Spec.js', included: false } ], // 須要從 files 中排除掉的文件 exclude: [], // 須要作預處理的文件,以及這些文件對應的預處理器。 // 此處就能夠將 coffee 、 ES6 等代碼轉換一下。 preprocessors: { 'src/**/*.js': ['babel', 'coverage'], 'test/**/!(main).js': ['babel', 'coverage'], 'node_modules/protectobject/src/**/*.js': ['babel'] }, // babel 預處理器的配置 babelPreprocessor: { options: { presets: ['es2015', 'stage-0'], plugins: ['transform-decorators-legacy', 'transform-es2015-modules-amd'] } }, // 覆蓋率報告器配置 coverageReporter: { type: 'html', dir: 'coverage' }, // 實際使用的報告期 // 可用的報告器: https://npmjs.org/browse/keyword/karma-reporter reporters: ['dots', 'coverage'], // 服務器端口號 port: 9876, // 在輸出內容(報告器和日誌)中啓用/禁用顏色 colors: true, // 日誌級別 // 取值: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // 啓用/禁用監視文件變化從新執行測試的功能 autoWatch: true, // 要測試的目標環境 browsers: ['Chrome', 'Firefox', 'Safari'], // 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 }); };
對於 Require.js ,還要注意配置一個入口文件,主要用於配置 Require.js 的模塊信息等。jquery
上述 karma 配置文件中的 test/main.js 即爲 Require.js 的入口文件,在該文件中的代碼通常來講應該是這樣的:es6
var TEST_REGEXP = /(spec|test)\.js$/i; var allTestFiles = []; // Get a list of all the test files to include Object.keys(window.__karma__.files).forEach(function(file) { if (TEST_REGEXP.test(file)) { // Normalize paths to RequireJS module names. // If you require sub-dependencies of test files to be loaded as-is (requiring file extension) // then do not normalize the paths var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, ''); allTestFiles.push(normalizedTestModule); } }); require.config({ // Karma serves files under /base, which is the basePath from your config file baseUrl: '/base/src', // example of using a couple of path translations (paths), to allow us to refer to different library dependencies, without using relative paths paths: { 'jquery': '../lib/jquery', 'underscore': '../lib/underscore', }, // example of using a shim, to load non AMD libraries (such as underscore) shim: { 'underscore': { exports: '_' } }, // dynamically load all test files deps: allTestFiles, // we have to kickoff jasmine, as it is asynchronous callback: window.__karma__.start });
運行以下命令,執行測試:npm
karma start
在執行測試的時候,點擊 debug
按鈕,進入 debug 頁面,而後打開瀏覽器開發者工具,能夠看到在 HTML 中有一段 js 代碼:瀏覽器
// Configure our Karma window.__karma__.config = {"args":[],"useIframe":true,"captureConsole":true,"clearContext":true}; // All served files with the latest timestamps window.__karma__.files = { '/base/node_modules/requirejs/require.js': '2c8b45573db27c131094a113e995236d20f043bb', '/base/node_modules/karma-requirejs/lib/adapter.js': '2621a4400d4a8a49588243fce2d8609ef950b46a', '/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js': '391e45351df9ee35392d2e5cb623221a969fc009', '/base/node_modules/karma-jasmine/lib/boot.js': '945a38bf4e45ad2770eb94868231905a04a0bd3e', '/base/node_modules/karma-jasmine/lib/adapter.js': '7975a273517f1eb29d7bd018790fd4c7b9a485d5', '/base/test/main.js': 'fc5206f4dff3b583db818cb10ed7c5cade572896', '/base/src/State.js': 'db89a58b4570983b8f8febfd4dedbc586c353670', '/base/test/StateSpec.js': 'faf31b373690a6d7a7035fdfdc9c85d906ace5c1' };
能夠看到 window.__karma__.files
中列出了全部的可能會在瀏覽器中執行的 js ,若是經過 Require.js 加載這裏沒有列舉出來的 js ,就會報錯。服務器
而後再看下面的一堆 script 標籤,大體是這樣的:
<script type="text/javascript" src="/base/node_modules/requirejs/require.js"></script> <script type="text/javascript" src="/base/node_modules/karma-requirejs/lib/adapter.js"></script> <script type="text/javascript" src="/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script> <script type="text/javascript" src="/base/node_modules/karma-jasmine/lib/boot.js"></script> <script type="text/javascript" src="/base/node_modules/karma-jasmine/lib/adapter.js"></script> <script type="text/javascript" src="/base/test/main.js"></script> <script type="text/javascript"> window.__karma__.loaded(); </script>
能夠看到,直接引入了 require.js 、 karma 相關的一堆 js 、jasmine 相關的 js ,還直接引入了剛纔配置的 test/main.js (Require.js 入口文件)。注意,此處並無直接引入 included: false
的 js 。
base
若是仔細看各類資源請求的 URL 地址,會發現除了 debug.js
和 context.js
以外,其它 js 文件都會以 /base
開頭,在配置 Require.js 的時候,務必注意這一點。
能夠引入 karma 的 coverage 插件來查看測試覆蓋率,該插件會在目標代碼中插入不少額外的代碼,用於判斷測試代碼執行流程有沒有走到這些地方。在 debug 的時候,最好關掉 coverage 功能,否則這些額外的代碼很是影響調試。
另外 karma-coverage-es6 聲稱支持 ES6 ,可是彷佛並不行?
默認狀況下,瀏覽器中 debug 頁面是不會輸出任何 jamine 測試結果的,能夠藉助 karma-jasmine-html-reporter
解決這個問題。
可是,karma-jasmine-html-reporter
有坑,在該插件的 index.js 中,有這樣一段代碼:
var createPattern = function(path) { return {pattern: path, included: true, served: true, watched: false}; }; var initReporter = function(files, baseReporterDecorator) { baseReporterDecorator(this); files.unshift(createPattern(__dirname + '/lib/adapter.js')); files.unshift(createPattern(__dirname + '/lib/html.jasmine.reporter.js')); files.unshift(createPattern(__dirname + '/css/jasmine.css')); }; initReporter.$inject = ['config.files', 'baseReporterDecorator']; module.exports = { 'reporter:kjhtml': ['type', initReporter] };
files
指的就是 karma.conf.js 中配置的 files ,此處使用 unshift
方法將這堆 js 、 css 放在了 files 最前面,這樣就會致使 html.jasmine.reporter.js
先於 jasmine.js
加載,從而報錯(html.jasmine.reporter.js
是要依賴 jasmine.js
的),因此這裏最好根據項目的實際狀況,合理調整一下順序。