Jack 同學(xué)的作業(yè):
TDD (Test-Driven Development,測(cè)試驅(qū)動(dòng)開發(fā))
為什么用TDD?
1减宣、想的更多(我們?cè)陂_發(fā)過程中往往會(huì)考慮的不是很周全,看著是完成了功能玩荠,實(shí)際上卻有小的bug存在)
2漆腌、便于溝通(開發(fā)人員間贼邓,更多的是通過代碼來交流溝通的。測(cè)試用例比開發(fā)代碼更能明確的指出闷尿,系統(tǒng)要做什么)
3塑径、優(yōu)化設(shè)計(jì)(我們?cè)陂_發(fā)中應(yīng)當(dāng)遵循盡量簡(jiǎn)單而且行之有效的方法,減少依賴填具,降低耦合)
4统舀、鼓勵(lì)重構(gòu)(傳統(tǒng)的重構(gòu),每次修改都需要小心翼翼劳景,生怕修改之后誉简,不符合原來的要求,但是一旦有了TDD盟广,就不用擔(dān)心了)
5闷串、減少失誤(增加新功能的時(shí)候,往往是一改一大片筋量。但是烹吵,如果加入TDD測(cè)試,這種大幅度修改會(huì)讓你很難寫好測(cè)試桨武,強(qiáng)迫我們?nèi)ソ档托薷姆壤甙危看我稽c(diǎn)一點(diǎn)的修改)
TDD目的:以測(cè)試推動(dòng)開發(fā)進(jìn)程。
測(cè)試框架:JEST
測(cè)試工具庫:Enzyme
相比于mocha+chai
優(yōu)點(diǎn):
1玻募、集成覆蓋率檢查,減少額外的庫
2一姿、jest是fb的親兒子七咧,有著強(qiáng)力的官方支持。
缺點(diǎn):
1叮叹、感覺上比抹茶慢
相關(guān)依賴:
npm install --save-dev jest
npm install --save-dev babel-jest
npm install enzyme --save-dev
npm i --save-dev react-addons-test-utils
jest的配置艾栋。可以再package.json中增加:
"jest”:
{
"collectCoverageFrom”:
["**/*.{js,jsx}”,
"!**/coverage/**”,
"!**/dist/**”,
"!**/store.js”,
"!**/provider.jsx”,
"!**/index.js”,
"!**/webpack.config.js”],
"coverageThreshold”:
{"global”:
{
"branches":95,
"functions":95,
"lines":95,
"statements”:95
}
}
}
collectCoverageFrom :忽略的文件
coverageThreshold:文件覆蓋率
原則:
1蛉顽、UI測(cè)試的是dom是否生成
2蝗砾、action測(cè)功能性
3、reducer測(cè)試值是否正確
../src/views/Demo
import React from ’react’
export default class Demo extends React.Component{
constructor(){
super()
this.handleClick=this.handleClick.bind(this)
}
handleClick(){
console.log(123456)
}
render(){
return(
<div>
<header>
<h1>demo</h1>
<a onClick={this.handleClick}>123</a>
</header>
</div>
)}
}
Demo.propTypes={
onClick:React.PropTypes.func.isRequired
}
../test/Demo.test.js
import React from ‘react’
import {shallow} from ‘enzyme’
importDemo
from '../../src/views/Demo’
const props={onClick:jest.fn()}
describe(‘demo component',()=>{
it('should render dom',()=>{
const wrapper = shallow (<Demo{...props}/>) //加載Demo為Dom
expect(wrapper.find('a').text()).toContain(‘123’);//內(nèi)容包含123的dom
expect(wrapper
.props.children[0].props.children).to.equal(‘demo’);//內(nèi)容等于demo
})
})
packjson中的依賴關(guān)系:
"devDependencies": {
"babel-core": "^6.23.1",
"babel-jest": "^19.0.0",
"babel-loader": "^6.3.2",
"babel-plugin-transform-runtime": "^6.5.2",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.23.0",
"babel-preset-stage-0": "^6.22.0",
"babel-runtime": "^6.5.0",
"classnames": "^2.2.3",
"css-loader": "^0.26.2",
"enzyme": "^2.7.1",
"file-loader": "^0.10.1",
"html-webpack-plugin": "^2.28.0",
"jest": "^19.0.2",
"lodash": "^4.17.4",
"react-addons-test-utils": "^15.4.2",
"style-loader": "^0.13.2",
"url-loader": "^0.5.8",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.4.1"
},
"jest": {
"collectCoverageFrom" : [
"**/*.{js}",
"!**/coverage/**",
"!**/dist/**",
"!**/store.js",
"!**/provider.jsx",
"!**/index.js",
"!**/webpack.config.js"
],
"coverageThreshold": {
"global": {
"branches": 95,
"functions": 95,
"lines": 95,
"statements": 95
}
}
}
測(cè)試demo的git地址:https://github.com/xuxtc/react-redux-demo.git
Rex - JiangKaiPing 同學(xué)
什么是TDD携冤?
TDD是測(cè)試驅(qū)動(dòng)開發(fā)(Test-Driven Development)的英文簡(jiǎn)稱悼粮,是敏捷開發(fā)中的一項(xiàng)核心實(shí)踐和技術(shù),也是一種設(shè)計(jì)方法論曾棕。TDD的原理是在開發(fā)功能代碼之前扣猫,先編寫單元測(cè)試用例代碼,測(cè)試代碼確定需要編寫什么產(chǎn)品代碼翘地。
TDD自動(dòng)化測(cè)試工具
1申尤、 React Native
2癌幕、 Mocha+chai
3、 Jest+Enzyme
主要調(diào)研(Jest+Enzyme)(以下來之百度):
1昧穿、和React師出同門勺远,F(xiàn)B官方支持
2、已經(jīng)集成了測(cè)試覆蓋率檢查时鸵、mock等功能胶逢,不需要安裝額外的庫
3、文檔完備寥枝,官方提供了和babel宪塔、webpack集成情況下以及異步調(diào)用的測(cè)試解決方案
4、官方提供snapshot testing解決方案
上述3個(gè)工具差別
1囊拜、 React Native偏原生JS代碼
2某筐、 Mocha+chai效率快
3、 Jest比Mocha慢一點(diǎn)但師出同門都來自Facebook
Jest的簡(jiǎn)單安裝
1冠跷、安裝Jest
npm install --save-dev jest
2南誊、如果測(cè)試項(xiàng)目中使用babel
npm install --save-dev babel-jest
3、安裝Enzyme
npm install enzyme --save-dev
4蜜托、如果使用react13以上的版本
npm i --save-dev react-addons-test-utils
5抄囚、如果需要忽略一些配置比如store.js和用于合并reducers的index.js在package.json中添加
"jest": {
"collectCoverageFrom" : [
"**/*.{js,jsx}",
"!**/coverage/**",
"!**/dist/**",
"!**/store.js",
"!**/provider.jsx",
"!**/index.js",
"!**/webpack.config.js"
]
}
6、給單元測(cè)試覆蓋率定個(gè)目標(biāo)橄务,達(dá)到目標(biāo)才通過
"jest": {
"collectCoverageFrom" : [
"**/*.{js,jsx}",
"!**/coverage/**",
"!**/store.js",
"!**/provider.jsx",
"!**/index.js",
"!**/webpack.config.js"
],
"coverageThreshold": {
"global": {
"branches": 95,
"functions": 95,
"lines": 95,
"statements": 95
}
}
}
7幔托、添加測(cè)試命令
"scripts": {
"test": "jest"
}
8、這樣就可以通過npm test來測(cè)試代碼蜂挪,但是目前只測(cè)試Holle world 通過重挑,測(cè)試工程問題還有BUG待解決
David - LiQunBin 同學(xué)的作業(yè):
調(diào)研TDD前端測(cè)試驅(qū)動(dòng)的相關(guān)信息
一.與傳統(tǒng)開發(fā)的區(qū)別
正常的開發(fā)流程:先開發(fā)界面或類,然后在進(jìn)行編碼測(cè)試
即:項(xiàng)目代碼開發(fā) -> 編寫測(cè)試用例 –> 運(yùn)行測(cè)試用例 -> 修復(fù)代碼BUG
而TDD:首先是進(jìn)行測(cè)試用例的編寫棠涮,然后再進(jìn)行類或者用戶界面的開發(fā)谬哀。
即:編寫測(cè)試用例 -> 運(yùn)行測(cè)試用例 –> 編寫項(xiàng)目代碼 -> 運(yùn)行測(cè)試用例 -> 重構(gòu)代碼
二.原理
測(cè)試驅(qū)動(dòng)開發(fā)的基本思想就是在開發(fā)功能代碼之前,先編寫測(cè)試代碼严肪。也就是說在明確要開發(fā)某個(gè)功能后史煎,首先思考如何對(duì)這個(gè)功能進(jìn)行測(cè)試,并完成測(cè)試代碼的編寫驳糯,然后編寫相關(guān)的代碼滿足這些測(cè)試用例篇梭。然后循環(huán)進(jìn)行添加其他功能,直到完全部功能的開發(fā)酝枢。
三.特征
1.與其他代碼相隔離:?jiǎn)卧獪y(cè)試只測(cè)試一件事很洋,否則應(yīng)該懷疑是否是測(cè)試內(nèi)容有誤
2. 與其他開發(fā)人員隔離:保證最小化的變量影響單元測(cè)試,也就是控制變量法隧枫。逐漸形成了模擬框架以及依賴注入框架等輔助工具喉磁。
3.有針對(duì)性:要做有意義的測(cè)試谓苟,保證完成那些功能或方法。
4.可重復(fù):?jiǎn)卧獪y(cè)試的最大優(yōu)勢(shì)就是可重復(fù)协怒,這也是持續(xù)集成的意義所在涝焙。
5.可預(yù)測(cè):?jiǎn)卧獪y(cè)試保證的是---確定的輸入得到肯定的輸出。
四.測(cè)試方式
1.單元測(cè)試:針對(duì)一個(gè)基礎(chǔ)類進(jìn)行輸入/輸出測(cè)試
主要是工具:NUnit孕暇、MSTest
2.框架測(cè)試:測(cè)試一個(gè)方法而不對(duì)其他發(fā)展產(chǎn)生影響或者被影響
主要工具:Rhino Mock仑撞、Type Mock、Moq
五.過程
制定TODO列表—>快速完成測(cè)試用例編寫—>測(cè)試代碼編譯不通過—>編寫對(duì)應(yīng)功能代碼—>測(cè)試通過—>重構(gòu)—>循環(huán)開發(fā)
然后說了這么多妖滔,我并不知道要怎么做這個(gè)隧哮。
理解:就是將主要功能用簡(jiǎn)單的demo先做出效果,從而預(yù)測(cè)項(xiàng)目效果
Blue - ZhongXiuJuan 同學(xué)的作業(yè):
一座舍、什么是TDD沮翔?
1、TDD的全稱是Test Driver Development曲秉,測(cè)試驅(qū)動(dòng)開發(fā)采蚀。
2、它是開發(fā)中的一項(xiàng)核心實(shí)踐和技術(shù)承二,也是一種設(shè)計(jì)方法論榆鼠。
3、它的基本思路:通過測(cè)試來推動(dòng)整個(gè)開發(fā)的進(jìn)行亥鸠,但測(cè)試驅(qū)動(dòng)開發(fā)并不只是單純的測(cè)試工作妆够,而是把需求分析,設(shè)計(jì)负蚊,質(zhì)量控制量化的過程神妹。
4、測(cè)試驅(qū)動(dòng)開發(fā)是一種開發(fā)方法盖桥,是開發(fā)人員參與的活動(dòng)灾螃。
二题翻、TDD原則揩徊?
1、獨(dú)立測(cè)試:不同代碼的測(cè)試應(yīng)該相互獨(dú)立嵌赠。類塑荒、函數(shù)、用例等都獨(dú)立測(cè)試姜挺。
2齿税、測(cè)試列表:任何階段想添加功能時(shí),應(yīng)把相關(guān)功能點(diǎn)加到測(cè)試列表中炊豪,然后才能繼續(xù)手頭工作凌箕,避免疏漏拧篮。
3、測(cè)試驅(qū)動(dòng):要實(shí)現(xiàn)某個(gè)功能牵舱,要編寫某個(gè)類或某個(gè)函數(shù)串绩,應(yīng)首先編寫測(cè)試代碼,明確這個(gè)類芜壁、這個(gè)函數(shù)如何使用礁凡,如何測(cè)試,然后在對(duì)其進(jìn)行設(shè)計(jì)慧妄、編碼顷牌。
4、可測(cè)試性:產(chǎn)品代碼設(shè)計(jì)塞淹、開發(fā)時(shí)的應(yīng)盡可能提高可測(cè)試性窟蓝。
5、及時(shí)重構(gòu):對(duì)結(jié)構(gòu)不合理窖铡,重復(fù)等“味道”不好的代碼疗锐,在測(cè)試通過后,應(yīng)及時(shí)進(jìn)行重構(gòu)费彼。
三滑臊、流程?
測(cè)試驅(qū)動(dòng)開發(fā)的基本過程如下:
① 快速新增一個(gè)測(cè)試
② 運(yùn)行所有的測(cè)試(有時(shí)候只需要運(yùn)行一個(gè)或一部分)箍铲,發(fā)現(xiàn)新增的測(cè)試不能通過
③ 做一些小小的改動(dòng)雇卷,盡快地讓測(cè)試程序可運(yùn)行,為此可以在程序中使用一些不合情理 的方法
④ 運(yùn)行所有的測(cè)試颠猴,并且全部通過
⑤ 重構(gòu)代碼关划,以消除重復(fù)設(shè)計(jì),優(yōu)化設(shè)計(jì)結(jié)構(gòu)
四翘瓮、優(yōu)缺點(diǎn)贮折?
優(yōu)點(diǎn):
1、 首先站在客戶方代碼的立場(chǎng)资盅,可以獲得更好的api调榄。
2、在寫代碼之前先寫測(cè)試用例呵扛,可以對(duì)我們編寫代碼提供指導(dǎo)性的參考每庆,防止我們漏掉一些功能。
3今穿、在更改代碼后測(cè)試用例不能通過時(shí)缤灵,我們可以馬上鎖定問題位置,縮短排查bug時(shí)間。
4、可以改善軟件質(zhì)量腮出,支持重構(gòu)帖鸦。
5、用TDD測(cè)試覆蓋率高胚嘲,軟件做集成測(cè)試的時(shí)候一般問題會(huì)比較少富蓄。
缺點(diǎn):
1、它需要我們有設(shè)計(jì)完備的測(cè)試用例的能力,否則你將會(huì)吃了虧編寫了一大堆測(cè) 試用例慢逾,卻沒測(cè)到點(diǎn)子上立倍。
2、增加代碼量侣滩,測(cè)試代碼是系統(tǒng)代碼的兩倍或更多口注。
3、可能不適合時(shí)間很緊的軟件開發(fā)君珠,更適合于產(chǎn)品和平臺(tái)的開發(fā)寝志。
問題:
1、初步了解了TDD策添,知道是什么材部,有什么作用,但是我們什么時(shí)候會(huì)用到這個(gè)唯竹,或者要用的時(shí)候需要安裝哪些軟件乐导?具體怎么操作還是不懂。
JiaWei 同學(xué)的作業(yè):
What浸颓?
TDD(測(cè)試驅(qū)動(dòng)開發(fā)):簡(jiǎn)而言之就是在編寫任何功能代碼之前物臂,先寫它的測(cè)試代碼。
步驟:
根據(jù)需要編寫一個(gè)測(cè)試用例产上,代碼盡可能的簡(jiǎn)單棵磷;
運(yùn)行它應(yīng)該會(huì)有失敗這個(gè)機(jī)制;
編寫功能代碼晋涣,讓寫的測(cè)試用例通過仪媒;
完善該階段(單元)的測(cè)試用例;
根據(jù)功能的增加谢鹊,編寫更多的測(cè)試用例算吩;
修改功能代碼使新增的測(cè)試用例和原來的都通過;
重構(gòu)撇贺,包括功能代碼和測(cè)試用例赌莺;
單元測(cè)試的目的顯而易見冰抢,用來確定是否適合使用松嘶,每個(gè)單元測(cè)試就是一段用于測(cè)試一個(gè)模塊或接口是否能達(dá)到預(yù)期結(jié)果的代碼,開發(fā)人員需要使用代碼來定義一個(gè)可用的衡量標(biāo)準(zhǔn)挎扰,并且可以快速檢驗(yàn)翠订。
Why巢音?
用TDD的方法可以使代碼干凈(代碼重構(gòu)的結(jié)果),測(cè)試覆蓋率高(先寫測(cè)試的結(jié)果)尽超,軟件做集成測(cè)試的時(shí)候一般問題會(huì)比較少官撼。而且你敢改人家的代碼,看到有fail的test case 證明你有改錯(cuò)人家的東西似谁,看到所有的test case都過了的話傲绣,你也很有信心說,我沒有改錯(cuò)巩踏,或程序不會(huì)因?yàn)槲业母膭?dòng)而掛掉秃诵。
每次都是很小的方面出發(fā),從一個(gè)小問題開始解決塞琼,知道解決一個(gè)大問題菠净。俗話說:步子邁大了容易扯蛋,步子邁大了就想得多彪杉,不可預(yù)知的就多毅往,容易忽視很多小問題。
它可以逼著你提高你的編程習(xí)慣派近、往更好的方面去編寫代碼蛇捌,逼著你使用面向?qū)ο蠡狙埃岣咦约捍a的變成技能。
How?
1. 舉1個(gè)栗子:我需要隨機(jī)生成四位不重復(fù)的隨機(jī)數(shù)
首先我們分析一下我需要的東西:
它是數(shù)字褥赊;
它是四位的;
它是隨機(jī)出現(xiàn)的救湖,每次點(diǎn)擊生成的都是不同的涎拉;
它的每一位都是不同的;
所以:我們?cè)倬帉憸y(cè)試代碼的時(shí)候碟嘴,就要get到以上所有的點(diǎn)溪食。首先,我們可以判斷生成數(shù)的類型娜扇,其次我們可以遍歷每一位并且判斷每一位的數(shù)字有沒有重復(fù)的(也可以使用正則)错沃,最后我們可以生成多條,遍歷判斷是否多條數(shù)據(jù)中是否有兩個(gè)數(shù)據(jù)相等雀瓢。如果有一條通不過枢析,那么可以報(bào)fail,都通過可以直接success刃麸。
2. 舉2個(gè)栗子:一個(gè)除法函數(shù)來做例子
Paste_Image.png
顯然醒叁,將會(huì)提示pass通過。但是問題來了,這個(gè)測(cè)試的用例太單一和普通了把沼,如果使用0做除數(shù)呢啊易?或者在實(shí)際使用時(shí),產(chǎn)品需要一個(gè)0來代替這樣一個(gè)不符合數(shù)學(xué)概念的結(jié)果去適應(yīng)必須為數(shù)字類型的某種計(jì)算饮睬,于是division出現(xiàn)了一個(gè)bug租谈。
還有,如果用’alert’來做輸出捆愁,你四不四傻割去?一個(gè)測(cè)試用例還好,如果是一個(gè)項(xiàng)目的呢昼丑?你就不怕你的瀏覽器奔潰劫拗?
所以,代碼第二彈來了:
Paste_Image.png
現(xiàn)在可以使用matcher方法添加許多測(cè)試用例矾克,并且還能為該用例命名页慷,在頁面中直接顯示每個(gè)用例是否通過。這樣一個(gè)基本的單元測(cè)試就完成了胁附,當(dāng)然它的覆蓋率還遠(yuǎn)遠(yuǎn)不夠酒繁,這里僅作為一個(gè)例子。
使用方式:
Paste_Image.png
別人我都不會(huì)告訴的話:既然編寫了測(cè)試代碼控妻,你還在傻傻的點(diǎn)擊按鈕來操作嗎州袒?那么你四不四傻的N次方?請(qǐng)使用:document.getElementById('button_id').click();讓按鈕自己來調(diào)用弓候。
工欲善其事必先利其器(內(nèi)容來源于百度)
原文網(wǎng)址:https://segmentfault.com/a/1190000000317146
JavaScript測(cè)試框架:
Jasmine
Qunit
Sinon
Mocha
前端測(cè)試工具:
1. Client/Server測(cè)試
i. JSTD(JavaScript Test Driver)
ii. Karma
iii. TestSearm
iv. Buster
基于網(wǎng)頁測(cè)試:
Selenium
React
請(qǐng)參考網(wǎng)址:http://www.reibang.com/p/6c74c96148c9
PS:
對(duì)于“他弟弟”我的內(nèi)心還是拒絕的郎哭。是,每個(gè)人都追求能開發(fā)出高質(zhì)量的代碼菇存,更少的Bug夸研、更容易維護(hù)不僅讓人心情愉悅,也讓我們有更多時(shí)間去學(xué)習(xí)和生活依鸥。(少加一些班亥至,有時(shí)間交女朋友)。雖然TDD可以幫我們做到這一些贱迟。但是你從代碼上節(jié)省出來的時(shí)間姐扮,全用到TDD上去了,具體的數(shù)據(jù)我不知道衣吠,但是身邊那么多搞開發(fā)的有多少用到了TDD茶敏?有多少堅(jiān)持在用TDD?搞開發(fā)缚俏,準(zhǔn)備一輩子搞開發(fā)嗎惊搏?而且弄TDD你在開發(fā)之前就已經(jīng)想到你的代碼該怎么寫了贮乳,怎么寫TDD了,又有多少人能達(dá)到胀屿?我想說現(xiàn)在用TDD的可能就是為了一個(gè)逼格吧。我不反對(duì)學(xué)習(xí)新技術(shù)包雀,用DIV+CSS+JS可以開發(fā)前端宿崭,用React+Redux+JS也可以開發(fā)前端。說句很俗的話:你新學(xué)一項(xiàng)技能才写,下一份工作面試的時(shí)候可能會(huì)多一份機(jī)會(huì)葡兑,但是放眼網(wǎng)去中國招前端的有哪一家公司說需要TDD的呢?是在BTA里面嗎赞草?說白了讹堤,我進(jìn)不了BTA,別說什么我沒有志氣什么什么的話厨疙,我覺得我是認(rèn)清了事實(shí)洲守。前端三大技能HTML+CSS+JS這三項(xiàng)吃透了嘛?不可能吃透的沾凄,金字塔尖的面積很小梗醇,擠不上去的。中間的還有那么多人撒蟀,你擠得過嗎叙谨?所以對(duì)于他,我還是拒絕的保屯,雖然我還沒有開始實(shí)施這個(gè)東西手负,但是我覺得比較困難,要想到很多姑尺,要將整個(gè)項(xiàng)目全部了解竟终,了然于胸。然后花時(shí)間去寫測(cè)試切蟋,然后去調(diào)試衡楞,再修改,然后再調(diào)試修改敦姻,最好還要重構(gòu)瘾境。看著都頭大镰惦。
一家之言迷守,不知所云。權(quán)當(dāng)瞎BB旺入。23333333...
XuYang 同學(xué)的作業(yè)
TDD
1兑凿、 定義:TDD – 測(cè)試驅(qū)動(dòng)開發(fā)凯力,是敏捷開發(fā)的一項(xiàng)核心實(shí)踐和技術(shù)。也是一種設(shè)計(jì)方法論礼华。設(shè)計(jì)思路是通過測(cè)試來推動(dòng)整個(gè)開發(fā)的進(jìn)行咐鹤。首先編寫單元測(cè)試用例代碼來確定需求,去掉不確定的需求圣絮。
2祈惶、 優(yōu)點(diǎn):節(jié)省開發(fā)的時(shí)間,明確需求扮匠。保證代碼的健壯性捧请。
3、 缺點(diǎn):代碼量大棒搜。前期準(zhǔn)備過多疹蛉。需求開發(fā)要求比較高。
4力麸、 結(jié)論:TDD思想是從項(xiàng)目開始之初就進(jìn)行可款,不太適用目前的項(xiàng)目。
單元測(cè)試
1克蚂、 單元測(cè)試:是指對(duì)軟件中的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證
2筑舅、 優(yōu)點(diǎn):保證代碼質(zhì)量。規(guī)模小陨舱,易于隔離定位錯(cuò)誤翠拣。降低測(cè)試成本。
3游盲、 缺點(diǎn):增加學(xué)習(xí)成本误墓,增加代碼工作量。
4益缎、 必要性:
a) 保證代碼正確性
b) 解釋性谜慌,對(duì)其他人員接受代碼閱讀api提供條件
c) 保證重構(gòu)
5、 結(jié)論:?jiǎn)卧獪y(cè)試是必要的莺奔。
前端單元測(cè)試:(資料摘自http://www.admin10000.com/document/6457.html)
1.為什么需要單元測(cè)試
? 正確性:測(cè)試可以驗(yàn)證代碼的正確性欣范,在上線前做到心里有底
? 自動(dòng)化:當(dāng)然手工也可以測(cè)試,通過console可以打印出內(nèi)部信息令哟,但是這是一次性的事情恼琼,下次測(cè)試還需要從頭來過,效率不能得到保證屏富。通過編寫測(cè)試用例晴竞,可以做到一次編寫,多次運(yùn)行
? 解釋性:測(cè)試用例用于測(cè)試接口狠半、模塊的重要性噩死,那么在測(cè)試用例中就會(huì)涉及如何使用這些API颤难。其他開發(fā)人員如果要使用這些API,那閱讀測(cè)試用例是一種很好地途徑已维,有時(shí)比文檔說明更清晰
? 驅(qū)動(dòng)開發(fā)行嗤,指導(dǎo)設(shè)計(jì):代碼被測(cè)試的前提是代碼本身的可測(cè)試性,那么要保證代碼的可測(cè)試性垛耳,就需要在開發(fā)中注意API的設(shè)計(jì)栅屏,TDD將測(cè)試前移就是起到這么一個(gè)作用
? 保證重構(gòu):互聯(lián)網(wǎng)行業(yè)產(chǎn)品迭代速度很快,迭代后必然存在代碼重構(gòu)的過程艾扮,那怎么才能保證重構(gòu)后代碼的質(zhì)量呢既琴?有測(cè)試用例做后盾占婉,就可以大膽的進(jìn)行重構(gòu)
2.前端相關(guān)的單元測(cè)試技術(shù)
2.1 測(cè)試框架
目前泡嘴,前端的測(cè)試框架很多,像QUnit逆济、jasmine酌予、mocha、jest奖慌、intern等框架抛虫,這些框架各有特點(diǎn),簡(jiǎn)單描述下简僧,感興趣的可以具體研究:
? Qunit: 該框架誕生之初是為了jquery的單元測(cè)試建椰,后來獨(dú)立出來不再依賴于jquery本身,但是其身上還是脫離不開jquery的影子
? jasmine: Behavior-Drive development(BDD)風(fēng)格的測(cè)試框架岛马,在業(yè)內(nèi)較為流行,功能很全面棉姐,自帶asssert、mock功能
? mocha: node社區(qū)大神tj的作品啦逆,可以在node和browser端使用伞矩,具有很強(qiáng)的靈活性,可以選擇自己喜歡的斷言庫夏志,選擇測(cè)試結(jié)果的report
? intern: 看官方介紹該測(cè)試框架功能極其全面乃坤,似乎囊括了業(yè)內(nèi)跟測(cè)試相關(guān)的所有功能
2.2 斷言庫
? chai:應(yīng)該是目前組流行的斷言庫了,支持TDD(assert)沟蔑、BDD(expect湿诊、should)兩個(gè)風(fēng)格的斷言庫
? var chai = require('chai');
?
? var assert = chai.assert; // typef assert === 'object'
chai.should(); // 對(duì)Obejct.prototype進(jìn)行拓展
? should.js: TJ的另外一個(gè)開源貢獻(xiàn)
? expect.js:BDD風(fēng)格的另外一個(gè)斷言庫,基于should.js,是mini版的BDD庫
? assert(node自帶核心模塊): 可以在node中使用的斷言模塊
2.3 mock庫
先來說說為什么需要mock吧:需要測(cè)試的單元依賴于外部的模塊瘦材,而這些依賴的模塊具有一些特點(diǎn)枫吧,例如不能控制、實(shí)現(xiàn)成本較高宇色、操作危險(xiǎn)等原因九杂,不能直接使用依賴的模塊颁湖,這樣情況下就需要對(duì)其進(jìn)行mock,也就是偽造依賴的模塊例隆。例如在使用XMLHttpRequest時(shí)甥捺,需要模擬http statusCode為404的情況,這種情況實(shí)際很難發(fā)生镀层,必然要通過mock來實(shí)現(xiàn)測(cè)試镰禾。
? sinon.js: 目前使用最多的mock庫,將其分為spies唱逢、stub吴侦、fake XMLHttpRequest、Fake server坞古、Fake time幾種备韧,根據(jù)不同的場(chǎng)景進(jìn)行選擇。
2.4 test runner
? karma: 設(shè)置測(cè)試需要的框架痪枫、環(huán)境织堂、源文件、測(cè)試文件等奶陈,配置完后易阳,就可以輕松地執(zhí)行測(cè)試。
3.單元測(cè)試技術(shù)的實(shí)現(xiàn)原理
1. 測(cè)試框架:判斷內(nèi)部是否存在異常吃粒,存在則console出對(duì)應(yīng)的text信息
2. 斷言庫:當(dāng)actual值與expect值不一樣時(shí)潦俺,就拋出異常,供外部測(cè)試框架檢測(cè)到徐勃,這就是為什么有些測(cè)試框架可以自由選擇斷言庫的原因事示,只要可以拋出異常,外部測(cè)試框架就可以工作疏旨。
3. mock函數(shù):創(chuàng)建一個(gè)新的函數(shù)很魂,用這個(gè)函數(shù)來取代原來的函數(shù),同時(shí)在這個(gè)新函數(shù)上添加一些額外的屬性檐涝,例如called遏匆、calledWithArguments等信息
如何寫單元測(cè)試用例
1原則
? 測(cè)試代碼時(shí),只考慮測(cè)試谁榜,不考慮內(nèi)部實(shí)現(xiàn)
? 數(shù)據(jù)盡量模擬現(xiàn)實(shí)幅聘,越靠近現(xiàn)實(shí)越好
? 充分考慮數(shù)據(jù)的邊界條件
? 對(duì)重點(diǎn)、復(fù)雜窃植、核心代碼帝蒿,重點(diǎn)測(cè)試
? 利用AOP(beforeEach、afterEach),減少測(cè)試代碼數(shù)量巷怜,避免無用功能
? 測(cè)試葛超、功能開發(fā)相結(jié)合暴氏,有利于設(shè)計(jì)和代碼重構(gòu)
2 TDD
一句話簡(jiǎn)單來說,就是先寫測(cè)試绣张,后寫功能實(shí)現(xiàn)答渔。TDD的目的是通過測(cè)試用例來指引實(shí)際的功能開發(fā),讓開發(fā)人員首先站在全局的視角來看待需求侥涵。具體定義可以查看維基;
就個(gè)人而言沼撕,TDD不是一個(gè)技術(shù),而是一種開發(fā)的指導(dǎo)思想芜飘。在目前互聯(lián)網(wǎng)的開發(fā)環(huán)境下务豺,業(yè)務(wù)開發(fā)很難做到TDD開發(fā),一是因?yàn)樾枰鄷r(shí)間編寫單元測(cè)試用例嗦明;二是要求非常了解業(yè)務(wù)需求笼沥;三是要求開 發(fā)人員有很強(qiáng)的代碼設(shè)計(jì)能力。但是當(dāng)我們寫組件招狸、工具方法敬拓、類庫的時(shí)候邻薯,TDD就可以得到很好地使用裙戏。
3 BDD
行為驅(qū)動(dòng)開發(fā)要求更多人員參與到軟件的開發(fā)中來,鼓勵(lì)開發(fā)者厕诡、QA累榜、相關(guān)業(yè)務(wù)人員相互協(xié)作。BDD是由商業(yè)價(jià)值來驅(qū)動(dòng)灵嫌,通過用戶接口(例如GUI)理解應(yīng)用程序壹罚。詳見維基.
React測(cè)試
1、測(cè)試工具庫
官方測(cè)試工具庫
第三方封裝的Enzyme
推薦使用第三方庫Enzyme寿羞。React測(cè)試必須使用官方的測(cè)試工具庫猖凛,但是它用起來不夠方便,所以有人做了封裝绪穆,推出了一些第三方庫辨泳,其中Airbnb公司的Enzyme最容易上手。
2玖院、Enzyme 用法
Enzyme 模擬了jQuery的API菠红,非常直觀,易于使用和學(xué)習(xí)难菌。它提供三種測(cè)試方法试溯。
? shallow
? render
? mount
摘自(http://www.ruanyifeng.com/blog/2016/02/react-testing-tutorial.html)
4.1 shallow
shallow方法就是官方的shallow rendering的封裝。
4.2 render
render方法將React組件渲染成靜態(tài)的HTML字符串郊酒,然后分析這段HTML代碼的結(jié)構(gòu)遇绞,返回一個(gè)對(duì)象键袱。它跟shallow方法非常像,主要的不同是采用了第三方HTML解析庫Cheerio摹闽,它返回的是一個(gè)Cheerio實(shí)例對(duì)象杠纵。
4.3 mount
mount方法用于將React組件加載為真實(shí)DOM節(jié)點(diǎn)。
4.4 API
下面是Enzyme的一部分API钩骇,你可以從中了解它的大概用法比藻。
? .get(index):返回指定位置的子組件的DOM節(jié)點(diǎn)
? .at(index):返回指定位置的子組件
? .first():返回第一個(gè)子組件
? .last():返回最后一個(gè)子組件
? .type():返回當(dāng)前組件的類型
? .text():返回當(dāng)前組件的文本內(nèi)容
? .html():返回當(dāng)前組件的HTML代碼形式
? .props():返回根組件的所有屬性
? .prop(key):返回根組件的指定屬性
? .state([key]):返回根組件的狀態(tài)
? .setState(nextState):設(shè)置根組件的狀態(tài)
? .setProps(nextProps):設(shè)置根組件的屬性
Demo
$ git clone https://github.com/ruanyf/react-testing-demo.git
$ cd react-testing-demo && npm install
$ npm start
框架測(cè)試:(摘自:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html)
推薦使用Mocha (摩卡)
示例
$ git clone https://github.com/ruanyf/mocha-demos.git
$ cd mocha-demos
$ npm install
$ npm install --global mocha
測(cè)試腳本的寫法
Mocha的作用是運(yùn)行測(cè)試腳本,首先必須學(xué)會(huì)寫測(cè)試腳本倘屹。所謂"測(cè)試腳本"银亲,就是用來測(cè)試源碼的腳本。
下面是一個(gè)加法模塊add.js的代碼纽匙。
// add.js
function add(x, y) {
return x + y;
}
module.exports = add;
要測(cè)試這個(gè)加法模塊是否正確务蝠,就要寫測(cè)試腳本。
通常烛缔,測(cè)試腳本與所要測(cè)試的源碼腳本同名馏段,但是后綴名為.test.js(表示測(cè)試)或者.spec.js(表示規(guī)格)。比如践瓷,add.js的測(cè)試腳本名字就是add.test.js院喜。
// add.test.js
var add = require('./add.js');
var expect = require('chai').expect;
describe('加法函數(shù)的測(cè)試', function() {
it('1 加 1 應(yīng)該等于 2', function() {
expect(add(1, 1)).to.be.equal(2);
});
});
上面這段代碼,就是測(cè)試腳本晕翠,它可以獨(dú)立執(zhí)行喷舀。測(cè)試腳本里面應(yīng)該包括一個(gè)或多個(gè)describe塊,每個(gè)describe塊應(yīng)該包括一個(gè)或多個(gè)it塊淋肾。
describe塊稱為"測(cè)試套件"(test suite)硫麻,表示一組相關(guān)的測(cè)試。它是一個(gè)函數(shù)樊卓,第一個(gè)參數(shù)是測(cè)試套件的名稱("加法函數(shù)的測(cè)試")拿愧,第二個(gè)參數(shù)是一個(gè)實(shí)際執(zhí)行的函數(shù)。
it塊稱為"測(cè)試用例"(test case)碌尔,表示一個(gè)單獨(dú)的測(cè)試浇辜,是測(cè)試的最小單位。它也是一個(gè)函數(shù)七扰,第一個(gè)參數(shù)是測(cè)試用例的名稱("1 加 1 應(yīng)該等于 2")奢赂,第二個(gè)參數(shù)是一個(gè)實(shí)際執(zhí)行的函數(shù)。
斷言庫的用法
上面的測(cè)試腳本里面颈走,有一句斷言膳灶。
通配符
命令行指定測(cè)試腳本時(shí),可以使用通配符,同時(shí)指定多個(gè)文件轧钓。
$ mocha spec/{my,awesome}.js
$ mocha test/unit/*.js
上面的第一行命令序厉,指定執(zhí)行spec目錄下面的my.js和awesome.js。第二行命令毕箍,指定執(zhí)行test/unit目錄下面的所有js文件弛房。
除了使用Shell通配符,還可以使用Node通配符而柑。
$ mocha 'test/**/*.@(js|jsx)'
上面代碼指定運(yùn)行test目錄下面任何子目錄中文捶、文件后綴名為js或jsx的測(cè)試腳本。注意媒咳,Node的通配符要放在單引號(hào)之中粹排,否則星號(hào)(*)會(huì)先被Shell解釋。
上面這行Node通配符涩澡,如果改用Shell通配符顽耳,要寫成下面這樣。
$ mocha test/{,**/}*.{js,jsx}
測(cè)試用例的鉤子
Mocha在describe塊之中妙同,提供測(cè)試用例的四個(gè)鉤子:before()射富、after()、beforeEach()和afterEach()粥帚。它們會(huì)在指定時(shí)間執(zhí)行胰耗。
YangGuang 同學(xué)的作業(yè):
今天主要調(diào)研的什么是TDD,TDD常用的框架以及相應(yīng)的特點(diǎn)茎辐。具體如下:
1.什么是TDD宪郊?
通過維基百科介紹掂恕,TDD即Test-Driven Development拖陆,測(cè)試驅(qū)動(dòng)開發(fā),是來源于敏捷開發(fā)的一個(gè)極限編程思想懊亡。大概來說依啰,就是開發(fā)之前,先寫測(cè)試用例(test case)店枣,然后再實(shí)現(xiàn)需要實(shí)現(xiàn)的方法或功能速警,然后跑測(cè)試用例,看是否通過鸯两。將來增加新功能的時(shí)候闷旧,也是遵循上述流程,如果所有的test case都通過钧唐,那么可以保證代碼質(zhì)量忙灼。
2.什么是BDD?
BDD是Behavior-Driven Development,行為驅(qū)動(dòng)開發(fā),相比TDD该园,BDD更關(guān)注通過測(cè)試酸舍,觀察到程序的行為是否正確,因此它的接口行為是使用describe里初。而與BDD相比啃勉,TDD更偏重與測(cè)試代碼的功能是否實(shí)現(xiàn)正確,它的接口是suite双妨。suite是一組測(cè)試用例的集合淮阐,可用于對(duì)測(cè)試用例進(jìn)行分類娇妓。suite里面可以嵌套suite花嘶,就像測(cè)一個(gè)功能的一組測(cè)試?yán)永锩嬖偌?xì)分測(cè)不同小功能的測(cè)試?yán)印?
3.好的單元測(cè)試應(yīng)該有哪些特點(diǎn)?
(1)簡(jiǎn)單易懂绰精,每次使用就知道是在做什么哑诊,能得到什么樣的測(cè)試結(jié)果群扶。
(2)高覆蓋率,重構(gòu)時(shí)更有信心镀裤。
(3)運(yùn)行速度快竞阐,不要有額外的工作,例如復(fù)雜的環(huán)境依賴暑劝。
4.對(duì)比兩種測(cè)試框架 JEST 與 Mocha骆莹。
JEST特點(diǎn):
(1)Facebook 官方支持
(2)自動(dòng)的讓測(cè)試并行運(yùn)行,提高在大項(xiàng)目下測(cè)試效率
(3)已集成了測(cè)試覆蓋率檢查担猛、mock幕垦、spy等功能,并不需要安裝額外的庫
(4)文檔完備傅联,官方提供了和babel先改、webpack集成情況下以及異步調(diào)用的測(cè)試解決方案
(5)官方提供snapshot testing解決方案
(6)相比于Mocha運(yùn)行速度稍慢
(7)附帶的JSDom可以讓代碼在瀏覽器里面編寫測(cè)試
Mocha:
(1)簡(jiǎn)單、易上手
(2)支持TDD蒸走、BDD等多種接口
(3)支持同步和異步的測(cè)試
(4)支持多種方式導(dǎo)出結(jié)果
(5)支持直接在瀏覽器上跑JavaScript代碼
Mocha + chai 配置測(cè)試用例步驟:
(1)在項(xiàng)目根目錄下運(yùn)行 npm init仇奶,此時(shí)會(huì)自動(dòng)生成package.json的配置文件,期間會(huì)需要輸入一些信息比驻,比如:
name: (項(xiàng)目根目錄) sunshine
version: (1.0.0)
description: Mocha test
entry point: (index.js)
test command: (mocha)
git repository:
keywords: mocha
author: Sunshine
沒有就回車帶過
(2)在項(xiàng)目中安裝mocha和chai该溯,執(zhí)行命令npm install - -save-dev mocha chai(前提是電腦里面必須有node), 然后會(huì)在根目錄下生成node_modules文件夾
(3)一般把我們所編寫的代碼放到src里面, 然后將測(cè)試代碼放置在test目錄下(兩個(gè)目錄都需要在根目錄下新建), 并按照命名規(guī)則來清晰地對(duì)應(yīng)測(cè)試代碼和所被測(cè)試代碼之間的關(guān)系,比如 src下的 add.js, test下的 add.test.js就存在對(duì)應(yīng)關(guān)系别惦。
(4)編寫add.js :
function add (a, b) { return (a+b);}
module.exports = add
編寫add.test.js
var add = require(“../src/add.js”);
var expect = require('chai').expect; 在第二步裝好
describe('加法函數(shù)的測(cè)試', function() {
it('1 + 2 must = 3', function() {
expect(add(1, 2)).to.be.equal(3);
});
});
此處describe是測(cè)試套件(test suite), it為單獨(dú)的測(cè)試狈茉,是測(cè)試的最小單位,稱為測(cè)試用例(test case)掸掸。
至此氯庆,初步的測(cè)試已經(jīng)搭建完成,運(yùn)行mocha即可得到測(cè)試結(jié)果,需要補(bǔ)充說明以下幾點(diǎn):
1.Mocha默認(rèn)運(yùn)行test子目錄里面的測(cè)試腳本点晴,所以一般把測(cè)試文件放在test文件夾下感凤,因此可以省略參數(shù)而使用mocha,但是默認(rèn)情況下僅僅執(zhí)行test子目錄下面的第一層測(cè)試用例粒督,不會(huì)執(zhí)行更下層的用例陪竿,除非增加- -recursive參數(shù)
2.如果需要執(zhí)行其他文件夾及其子目錄的測(cè)試,需要在test的mocha.opts里面增加這個(gè)文件夾的名字屠橄,不過這樣就不執(zhí)行test里面的測(cè)試腳本了族跛。
3.mocha.opts可以配置mocha的命令行參數(shù),比如- -reporter / - R 報(bào)告格式 - -growl / -G 輸出到桌面 - - watch / -w 監(jiān)視指定腳本锐墙,只要指定的腳本有變化礁哄,就會(huì)自動(dòng)執(zhí)行 - -bail / -b 只要有一個(gè)測(cè)試用例沒有通過,就停止執(zhí)行后面的測(cè)試用例 - - grep -g 用于搜索測(cè)試用例的名稱溪北,然后只執(zhí)行匹配的測(cè)試用例 - -invert / -i 參數(shù)表示只運(yùn)行不符合條件的測(cè)試腳本, 必須與- - grep 參數(shù)配合使用
4.ES 6測(cè)試桐绒,需要先安裝Babel,執(zhí)行命令npm install babel-core babel-preset-es2015 —save-dev之拨,然后在項(xiàng)目目錄下面新建 .babelrc配置文件茉继,并寫入{ “presets” :[“es2015”] }, 最后使用 - -compilers參數(shù)指定測(cè)試腳本的轉(zhuǎn)碼器,采用
../node_modules/mocha/bin/mocha --compilers js:babel-core/register
以上命令表明測(cè)試之前蚀乔,先用babel-core/register模塊烁竭。處理一下.js文件,如果全局安裝了吉挣,就可以使用全局的mocha派撕,此時(shí)可以得到測(cè)試結(jié)果。
5.異步測(cè)試
Mocha默認(rèn)每個(gè)測(cè)試用例最多執(zhí)行2000毫秒睬魂,如果到時(shí)沒有得到結(jié)果终吼,就報(bào)錯(cuò)。對(duì)于異步操作汉买,這個(gè)時(shí)間往往是不夠的衔峰,需要使用-t或- -timeout參數(shù)指定超時(shí)門檻,測(cè)試用例有一個(gè)done函數(shù)用于告訴Mocha測(cè)試結(jié)束了蛙粘,否則會(huì)一直等到超時(shí)報(bào)錯(cuò)。例如:mocha -t 10000 async.test.js
6.mocha內(nèi)置對(duì)Promise的支持威彰,允許直接返回Promise出牧,等到它的狀態(tài)改變,再執(zhí)行斷言歇盼,而不用顯式調(diào)用done
7.測(cè)試用例的鉤子
before() : 在本區(qū)塊的所有測(cè)試用例之前執(zhí)行
after() : 在本區(qū)塊的所有測(cè)試用例之后執(zhí)行
beforeEach() 在本區(qū)塊的每個(gè)測(cè)試用例之前執(zhí)行
afterEach() 在本區(qū)塊的每個(gè)測(cè)試用例之后執(zhí)行
8.測(cè)試用例的管理:
可以采用 only指定執(zhí)行某個(gè)測(cè)試用例舔痕,而不執(zhí)行其他,也可以用skip跳過某個(gè)測(cè)試用例的執(zhí)行
9.瀏覽器測(cè)試: 采用mocha init xxx文件夾就會(huì)在xxx文件下下面生成 index.html mocha.css mocha.js tests.js四個(gè)文件
新建一個(gè)源文件 add.js 只寫一個(gè)函數(shù) add 表示兩數(shù)相加,把這個(gè)源文件和斷言庫chai.js 加入到index.html伯复,然后在tests.js里面寫入測(cè)試腳本慨代,然后在瀏覽器里面打開index.html,就可以看到腳本運(yùn)行結(jié)果啸如。