摘要:的配置文件是為了解析那些需要測試的源文件相關(guān)的文件,然后再給的單元測試用例去識別。其作用是僅僅渲染至虛擬節(jié)點(diǎn),不會返回真實(shí)的節(jié)點(diǎn),能極大提高測試性能。
為解放勞動力,發(fā)展生產(chǎn)力
測試有了這般變化:
鼠標(biāo)點(diǎn)擊手動測試 -> 用腳本模擬,自動化測試
全局安裝:babel、mocha、karma
其他局部安裝的包在下面的【測試環(huán)境搭建】最下方配置文件中給出
測試環(huán)境搭建配置主要是兩個,一是 karma 的配置文件,另一個是 karma 需要的webpack 配置文件。
webpack 的配置文件是為了解析那些需要測試的源文件(vue 相關(guān)的文件),然后再給karma 的單元測試用例去識別。
webpack3 配置文件var path = require("path") var webpack = require("webpack") var ExtractTextPlugin = require("extract-text-webpack-plugin") function resolve(dir) { return path.join(__dirname, "..", dir) } var webpackConfig = { module: { rules: [ // babel-loader { test: /.js$/, use: "babel-loader", include: [resolve("src"), resolve("test")] }, // 為了統(tǒng)計代碼覆蓋率,對 js 文件加入 istanbul-instrumenter-loader { test: /.(js)$/, exclude: /node_modules/, include: /src|packages/, enforce: "post", use: [{ loader: "istanbul-instrumenter-loader", options: { esModules: true }, }] }, // vue loader { test: /.vue$/, use: [{ loader: "vue-loader", options: { // 為了統(tǒng)計代碼覆蓋率,對 vue 文件加入 istanbul-instrumenter-loader preLoaders: { js: "istanbul-instrumenter-loader?esModules=true" } } }] }, // css loader { test: /.css$/, use: ExtractTextPlugin.extract({ use: "css-loader", fallback: "vue-style-loader" }) }, // img loader { test: /.(png|gif|jpe?g)(?S*)?$/, use: [{loader: "url-loader"}] }, // font loader { test: /.(eot|woff|woff2|ttf|svg)(?S*)?$/, use: [{loader: "url-loader"}] }, ] }, resolve: { extensions: [".js", ".vue", ".json"], alias: { "vue$": "vue/dist/vue.esm.js", "@": resolve("src"), // 調(diào)用組件的時候方便點(diǎn) } }, plugins: [ new webpack.DefinePlugin({ "process.env": { NODE_ENV: ""production"" } }) ] } module.exports = webpackConfigkarma配置文件
有兩種方法:
cd進(jìn)入當(dāng)前項(xiàng)目,使用 karma init命令,然后一系列提示選擇...
不用 karma init命令,新建一個karma.conf.js文件,然后配置:
var webpackConfig = require("../../build/webpack.test.config"); module.exports = function (config) { config.set({ // to run in additional browsers: // 1. install corresponding karma launcher // http://karma-runner.github.io/0.13/config/browsers.html // 2. add it to the `browsers` array below. browsers: ["PhantomJS"], frameworks: ["mocha", "sinon-chai", "phantomjs-shim"], reporters: ["spec", "coverage"], files: ["index.js"], preprocessors: { "./index.js": ["webpack", "sourcemap"] }, webpackMiddleware: { noInfo: true }, // 不顯示 `webpack` 打包日志信息 webpackServer: { noInfo: true }, webpack: webpackConfig, coverageReporter: { dir: "./coverage", reporters: [ { type: "lcov", subdir: "." }, { type: "text-summary" } ] } }) }目錄結(jié)構(gòu)
├─build │ webpack.test.config.js │ ├─src │ ├─package.json │ └─test └─unit │ index.js │ karma.config.js │ ├─coverage │ └─specs *.spec.js
測試文件相關(guān)都放置在 test/unit 下,入口文件為 index.js,每個vue 組件對應(yīng)的測試用例名為組件名稱.spec.js,根據(jù) istanbul-instrumenter-loader 文檔的說明,測試總?cè)肟谖募?index.js 內(nèi)容如下:
import Vue from "vue" Vue.config.productionTip = false // 測試所有以 .spec.js 名稱結(jié)尾的文件 // require all test files (files that ends with .spec.js) const testsContext = require.context("./specs", true, /.spec$/) testsContext.keys().forEach(testsContext) // 要求除main.js之外的所有src文件進(jìn)行覆蓋 // require all src files except main.js for coverage. // you can also change this to match only the subset of files that // you want coverage for. const srcContext = require.context("../../src", true, /^./(?!main(.js)?$)/) srcContext.keys().forEach(srcContext)最后看下package.json的devDependencies
"devDependencies": { ... "babel-core": "^6.9.0", "babel-loader": "^7.1.1", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-plugin-transform-vue-jsx": "^3.3.0", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.0", "babel-preset-es2015": "^6.18.0", "babel-preset-stage-2": "^6.18.0", "babel-runtime": "^6.18.0", "chai": "^4.1.2", "chalk": "^2.0.1", "css-loader": "^0.28.4", "extract-text-webpack-plugin": "^2.1.2", "istanbul-instrumenter-loader": "^3.0.0", "karma": "^1.7.1", "karma-coverage": "^1.1.1", "karma-mocha": "^1.3.0", "karma-phantomjs-launcher": "^1.0.4", "karma-phantomjs-shim": "^1.4.0", "karma-sinon-chai": "^1.3.2", "karma-sourcemap-loader": "^0.3.7", "karma-spec-reporter": "0.0.31", "karma-webpack": "^2.0.4", "mocha": "^3.5.0", "phantomjs-prebuilt": "^2.1.15", "postcss-px2rem": "^0.3.0", "sinon": "^3.2.1", "sinon-chai": "^2.13.0", ... "style-loader": "^0.18.2", "url-loader": "^0.5.7", "vue-loader": "^13.0.4", "vue-router": "^2.7.0" },
執(zhí)行命令 sudo npm install 安裝所需要的包
注意:
當(dāng)流程走到下面這個步驟時,可能耗費(fèi)的時間比較長,千萬別ctrl + c中斷下載重新install,靜靜等待就好
開始測試
新建一個Hello.vue組件
msg
在test/unit/specs 目錄下創(chuàng)建一個 Hello.spec.js 文件,再寫個簡單的單元測試用例:
import Vue from "vue" import Hello from "@/components/Hello" describe("Hello.vue", () => { it("should render correct contents", () => { const Constructor = Vue.extend(Hello) const vm = new Constructor().$mount() expect(vm.$el.querySelector(".hello h1").textContent) .to.equal("Welcome to Your Vue.js App") }) })
在package.json文件配置:
// package.json "scripts": { "test": "karma start test/unit/karma.config.js --single-run" }
執(zhí)行npm run test輸出測試結(jié)果,同時在 test/unit/coverage 生成測試報告。
一些測試的Case網(wǎng)上的例子...
點(diǎn)我點(diǎn)我點(diǎn)我
再點(diǎn)我點(diǎn)我點(diǎn)我
React中的組件測試 Jest + EnzymeJest:JS單元測試工具,包含DOM API 支持、斷言庫、Mock 庫等,還包含了 Spapshot Testing、 Instant Feedback 等特性
Enzyme:通過 jQuery 風(fēng)格的方式進(jìn)行DOM 處理,開發(fā)體驗(yàn)十分友好
測試環(huán)境搭建 1. 安裝一些包npm install jest enzyme babel-jest --save-dev2. 在package.json中配置jest:
"jest": { "moduleFileExtensions": [ "js", "jsx" ], "moduleNameMapper": { ".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "3. 新增啟動測試的腳本:/__mocks__/fileMock.js", ".*.(css|less|scss)$": " /__mocks__/styleMock.js" }, "transform": { "^.+.js$": "babel-jest" } },
"scripts": { "test": "jest" }開始測試 1. 引入
import { shallow } from "enzyme"
Enzyme 提供了三種方法
shallow:淺渲染。其作用是僅僅渲染至虛擬節(jié)點(diǎn),不會返回真實(shí)的節(jié)點(diǎn),能極大提高測試性能。但是它不適合測試包含子組件、需要測試聲明周期的組件
mount:Full Rendering,非常適用于存在于 DOM API 存在交互組件,或者需要測試組件完整的生命周期
render:Static Rendering,用于 將 React 組件渲染成靜態(tài)的 HTML 并分析生成的 HTML 結(jié)構(gòu)
一般情況下,shallow 就已經(jīng)足夠用了,偶爾情況下會用到 mount。
2. 模擬const setup = () => { // 模擬 props const props = { // Jest 提供的mock 函數(shù) onAddClick: jest.fn() } // 通過 enzyme 提供的 shallow(淺渲染) 創(chuàng)建組件 const wrapper = shallow(3. 編寫Test Case) return { props, wrapper } }
Case1::測試組件是否正常渲染
describe("AddTodoView", () => { const { wrapper, props } = setup(); // case1 // 通過查找存在 Input,測試組件正常渲染 it("AddTodoView Component should be render", () => { //.find(selector) 是 Enzyme shallow Rendering 提供的語法, 用于查找節(jié)點(diǎn) // 詳細(xì)用法見 Enzyme 文檔 http://airbnb.io/enzyme/docs/api/shallow.html expect(wrapper.find("input").exists()); }) })
Case2:輸入內(nèi)容并敲下回車鍵,測試組件調(diào)用props的方法
it("When the Enter key was pressed, onAddClick() shoule be called", () => { // mock input 輸入和 Enter事件 const mockEvent = { keyCode: 13, // enter 事件 target: { value: "Test" } } // 通過 Enzyme 提供的 simulate api 模擬 DOM 事件 wrapper.find("input").simulate("keyup",mockEvent) // 判斷 props.onAddClick 是否被調(diào)用 expect(props.onAddClick).toBeCalled() })生成報告
Jest 還提供了生成測試覆蓋率報告的命令,只需要添加上 --coverage 這個參數(shù)既可生成
"scripts": { "coverage": "jest --colors --coverage" }寫在最后
難點(diǎn)是要考慮周全,測試用例覆蓋全面
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/93231.html
摘要:年終總結(jié)結(jié)果到這個時間才寫,其實(shí)也是無奈。這一年最重要的事情就是順利從一只學(xué)生狗轉(zhuǎn)職為一只社畜。四月份畢業(yè)之后以前端工程師的職位入職天貓,到現(xiàn)在也差不多工作一年了。 年終總結(jié)結(jié)果到這個時間才寫,其實(shí)也是無奈。本來計劃過年寫的,沒想到Steam竟然開了個農(nóng)歷春節(jié)特惠,然后就被各種游戲打了,辣雞平臺,斂我錢財,頹我精神,耗我青春,害我單身 以下全都是個人看法,如果有不認(rèn)同的地方,請大吼一聲...
摘要:年終總結(jié)結(jié)果到這個時間才寫,其實(shí)也是無奈。這一年最重要的事情就是順利從一只學(xué)生狗轉(zhuǎn)職為一只社畜。四月份畢業(yè)之后以前端工程師的職位入職天貓,到現(xiàn)在也差不多工作一年了。 年終總結(jié)結(jié)果到這個時間才寫,其實(shí)也是無奈。本來計劃過年寫的,沒想到Steam竟然開了個農(nóng)歷春節(jié)特惠,然后就被各種游戲打了,辣雞平臺,斂我錢財,頹我精神,耗我青春,害我單身 以下全都是個人看法,如果有不認(rèn)同的地方,請大吼一聲...
摘要:如何構(gòu)建大型的前端項(xiàng)目搭建好項(xiàng)目的腳手架一般新開發(fā)一個項(xiàng)目時,我們會首先搭建好一個腳手架,然后才會開始寫代碼。組件化一般分為項(xiàng)目內(nèi)的組件化和項(xiàng)目外的組件化。 如何構(gòu)建大型的前端項(xiàng)目 1. 搭建好項(xiàng)目的腳手架 一般新開發(fā)一個項(xiàng)目時,我們會首先搭建好一個腳手架,然后才會開始寫代碼。一般腳手架都應(yīng)當(dāng)有以下的幾個功能: 自動化構(gòu)建代碼,比如打包、壓縮、上傳等功能 本地開發(fā)與調(diào)試,并有熱替換與...
摘要:如何構(gòu)建大型的前端項(xiàng)目搭建好項(xiàng)目的腳手架一般新開發(fā)一個項(xiàng)目時,我們會首先搭建好一個腳手架,然后才會開始寫代碼。組件化一般分為項(xiàng)目內(nèi)的組件化和項(xiàng)目外的組件化。 如何構(gòu)建大型的前端項(xiàng)目 1. 搭建好項(xiàng)目的腳手架 一般新開發(fā)一個項(xiàng)目時,我們會首先搭建好一個腳手架,然后才會開始寫代碼。一般腳手架都應(yīng)當(dāng)有以下的幾個功能: 自動化構(gòu)建代碼,比如打包、壓縮、上傳等功能 本地開發(fā)與調(diào)試,并有熱替換與...
摘要:前后端都要關(guān)注注入攻擊跨站腳本攻擊跨站請求偽造開放重定向這些安全性問題。前端也需要構(gòu)建自動化測試,包括獨(dú)立單元測試和端到端測試自動化,當(dāng)然還有人工測試。 總體指導(dǎo)思想是前后端分離,后端同事提供線上API數(shù)據(jù)查詢接口或websocket接口,前端同事負(fù)責(zé)處理獲取到的數(shù)據(jù)、編寫展示的頁面、實(shí)現(xiàn)用戶交互;前后端都要考慮web開發(fā)的安全性問題,表單提交到數(shù)據(jù)庫前對用戶的輸入進(jìn)行轉(zhuǎn)義、登錄避免明...
閱讀 2216·2021-09-07 09:58
閱讀 3391·2019-08-30 14:07
閱讀 1305·2019-08-29 12:32
閱讀 667·2019-08-29 11:06
閱讀 3692·2019-08-26 18:18
閱讀 3731·2019-08-26 17:35
閱讀 1381·2019-08-26 11:35
閱讀 611·2019-08-26 11:35