測(cè)試框架 Mocha 實(shí)例教程

原文鏈接:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

作者: 阮一峰
日期: 2015年12月 3日

Mocha(發(fā)音"摩卡")誕生于2011年,是現(xiàn)在最流行的JavaScript測(cè)試框架之一,在瀏覽器和Node環(huán)境都可以使用惑折。
所謂"測(cè)試框架",就是運(yùn)行測(cè)試的工具畔柔。通過(guò)它,可以為JavaScript應(yīng)用添加測(cè)試,從而保證代碼的質(zhì)量。
本文全面介紹如何使用Mocha
捞奕,讓你輕松上手。如果你以前對(duì)測(cè)試一無(wú)所知拄轻,本文也可以當(dāng)作JavaScript單元測(cè)試入門颅围。值得說(shuō)明的是,除了Mocha以外恨搓,類似的測(cè)試框架還有Jasmine
院促、Karma
Tape
等斧抱,也很值得學(xué)習(xí)常拓。


一、安裝
我為本文寫(xiě)了一個(gè)示例庫(kù)Mocha-demos
辉浦,請(qǐng)先安裝這個(gè)庫(kù)弄抬。
$ git clone https://github.com/ruanyf/mocha-demos.git

如果你的電腦沒(méi)裝Git,可以直接下載zip壓縮包宪郊,進(jìn)行解壓掂恕。
然后,進(jìn)入mocha-demos目錄弛槐,安裝依賴(你的電腦必須有Node)懊亡。
$ cd mocha-demos$ npm install

上面代碼會(huì)在目錄內(nèi)部安裝Mocha,為了操作的方便乎串,請(qǐng)?jiān)谌姝h(huán)境也安裝一下Mocha斋配。
$ npm install --global mocha

二、測(cè)試腳本的寫(xiě)法
Mocha的作用是運(yùn)行測(cè)試腳本,首先必須學(xué)會(huì)寫(xiě)測(cè)試腳本艰争。所謂"測(cè)試腳本"坏瞄,就是用來(lái)測(cè)試源碼的腳本。
下面是一個(gè)加法模塊add.js
的代碼甩卓。
// add.jsfunction add(x, y) { return x + y;}module.exports = add;

要測(cè)試這個(gè)加法模塊是否正確鸠匀,就要寫(xiě)測(cè)試腳本。通常逾柿,測(cè)試腳本與所要測(cè)試的源碼腳本同名缀棍,但是后綴名為.test.js(表示測(cè)試)或者.spec.js(表示規(guī)格)。比如机错,add.js
的測(cè)試腳本名字就是add.test.js爬范。
// add.test.jsvar 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ù)。
三茴扁、斷言庫(kù)的用法
上面的測(cè)試腳本里面铃岔,有一句斷言。
expect(add(1, 1)).to.be.equal(2);

所謂"斷言"峭火,就是判斷源碼的實(shí)際執(zhí)行結(jié)果與預(yù)期結(jié)果是否一致毁习,如果不一致就拋出一個(gè)錯(cuò)誤。上面這句斷言的意思是卖丸,調(diào)用add(1, 1)
纺且,結(jié)果應(yīng)該等于2。
所有的測(cè)試用例(it塊)都應(yīng)該含有一句或多句的斷言稍浆。它是編寫(xiě)測(cè)試用例的關(guān)鍵载碌。斷言功能由斷言庫(kù)來(lái)實(shí)現(xiàn)猜嘱,Mocha本身不帶斷言庫(kù),所以必須先引入斷言庫(kù)嫁艇。
var expect = require('chai').expect;

斷言庫(kù)有很多種朗伶,Mocha并不限制使用哪一種。上面代碼引入的斷言庫(kù)是chai
步咪,并且指定使用它的expect斷言風(fēng)格论皆。
expect斷言的優(yōu)點(diǎn)是很接近自然語(yǔ)言,下面是一些例子猾漫。
// 相等或不相等expect(4 + 5).to.be.equal(9);expect(4 + 5).to.be.not.equal(10);expect(foo).to.be.deep.equal({ bar: 'baz' });// 布爾值為trueexpect('everthing').to.be.ok;expect(false).to.not.be.ok;// typeofexpect('test').to.be.a('string');expect({ foo: 'bar' }).to.be.an('object');expect(foo).to.be.an.instanceof(Foo);// includeexpect([1,2,3]).to.include(2);expect('foobar').to.contain('foo');expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');// emptyexpect([]).to.be.empty;expect('').to.be.empty;expect({}).to.be.empty;// matchexpect('foobar').to.match(/^foo/);

基本上点晴,expect
斷言的寫(xiě)法都是一樣的。頭部是expect方法悯周,尾部是斷言方法粒督,比如equal、a
/an禽翼、ok屠橄、match等。兩者之間使用to或to.be連接捐康。
如果expect斷言不成立,就會(huì)拋出一個(gè)錯(cuò)誤庸蔼。事實(shí)上解总,只要不拋出錯(cuò)誤,測(cè)試用例就算通過(guò)姐仅。
it('1 加 1 應(yīng)該等于 2', function() {});

上面的這個(gè)測(cè)試用例花枫,內(nèi)部沒(méi)有任何代碼,由于沒(méi)有拋出了錯(cuò)誤掏膏,所以還是會(huì)通過(guò)劳翰。
四、Mocha的基本用法
有了測(cè)試腳本以后馒疹,就可以用Mocha運(yùn)行它佳簸。請(qǐng)進(jìn)入demo01
子目錄,執(zhí)行下面的命令颖变。
$ mocha add.test.js 加法函數(shù)的測(cè)試 ? 1 加 1 應(yīng)該等于 2 1 passing (8ms)

上面的運(yùn)行結(jié)果表示生均,測(cè)試腳本通過(guò)了測(cè)試,一共只有1個(gè)測(cè)試用例腥刹,耗時(shí)是8毫秒马胧。
mocha
命令后面緊跟測(cè)試腳本的路徑和文件名,可以指定多個(gè)測(cè)試腳本衔峰。
$ mocha file1 file2 file3

Mocha默認(rèn)運(yùn)行test
子目錄里面的測(cè)試腳本佩脊。所以蛙粘,一般都會(huì)把測(cè)試腳本放在test目錄里面,然后執(zhí)行mocha
就不需要參數(shù)了威彰。請(qǐng)進(jìn)入demo02子目錄出牧,運(yùn)行下面的命令。
$ mocha 加法函數(shù)的測(cè)試 ? 1 加 1 應(yīng)該等于 2 ? 任何數(shù)加0應(yīng)該等于自身 2 passing (9ms)

這時(shí)可以看到抱冷,test子目錄里面的測(cè)試腳本執(zhí)行了崔列。但是,你打開(kāi)test子目錄旺遮,會(huì)發(fā)現(xiàn)下面還有一個(gè)test/dir子目錄赵讯,里面還有一個(gè)測(cè)試腳本multiply.test.js,并沒(méi)有得到執(zhí)行耿眉。原來(lái)边翼,Mocha默認(rèn)只執(zhí)行test
子目錄下面第一層的測(cè)試用例,不會(huì)執(zhí)行更下層的用例鸣剪。為了改變這種行為组底,就必須加上--recursive
參數(shù),這時(shí)test子目錄下面所有的測(cè)試用例----不管在哪一層----都會(huì)執(zhí)行筐骇。
$ mocha --recursive 加法函數(shù)的測(cè)試 ? 1 加 1 應(yīng)該等于 2 ? 任何數(shù)加0應(yīng)該等于自身 乘法函數(shù)的測(cè)試 ? 1 乘 1 應(yīng)該等于 1 3 passing (9ms)

五债鸡、通配符
命令行指定測(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通配符,要寫(xiě)成下面這樣拼弃。
$ mocha test/{,
/}.{js,jsx}

六夏伊、命令行參數(shù)
除了前面介紹的--recursive,Mocha還可以加上其他命令行參數(shù)吻氧。請(qǐng)?jiān)?a target="_blank" rel="nofollow">demo02
子目錄里面溺忧,運(yùn)行下面的命令咏连,查看效果。
6.1 --help, -h
--help
或-h
參數(shù)鲁森,用來(lái)查看Mocha的所有命令行參數(shù)祟滴。
$ mocha --help

6.2 --reporter, -R
--reporter
參數(shù)用來(lái)指定測(cè)試報(bào)告的格式,默認(rèn)是spec
格式歌溉。
$ mocha# 等同于$ mocha --reporter spec

除了spec
格式垄懂,官方網(wǎng)站還提供了其他許多報(bào)告格式
$ mocha --reporter tap1..2ok 1 加法函數(shù)的測(cè)試 1 加 1 應(yīng)該等于 2ok 2 加法函數(shù)的測(cè)試 任何數(shù)加0應(yīng)該等于自身# tests 2# pass 2# fail 0

上面是tap
格式報(bào)告的顯示結(jié)果痛垛。
--reporters
參數(shù)可以顯示所有內(nèi)置的報(bào)告格式草慧。
$ mocha --reporters

使用mochawesome
模塊,可以生成漂亮的HTML格式的報(bào)告匙头。


$ npm install --save-dev mochawesome$ ../node_modules/.bin/mocha --reporter mochawesome

上面代碼中漫谷,mocha
命令使用了項(xiàng)目?jī)?nèi)安裝的版本,而不是全局安裝的版本蹂析,因?yàn)閙ochawesome
模塊是安裝在項(xiàng)目?jī)?nèi)的舔示。
然后,測(cè)試結(jié)果報(bào)告就在mochaawesome-reports
子目錄生成电抚。
6.3 --growl, -G
打開(kāi)--growl
參數(shù)惕稻,就會(huì)將測(cè)試結(jié)果在桌面顯示。
$ mocha --growl


6.4 --watch蝙叛,-w
--watch
參數(shù)用來(lái)監(jiān)視指定的測(cè)試腳本俺祠。只要測(cè)試腳本有變化,就會(huì)自動(dòng)運(yùn)行Mocha甥温。
$ mocha --watch

上面命令執(zhí)行以后锻煌,并不會(huì)退出妓布。你可以另外打開(kāi)一個(gè)終端窗口姻蚓,修改test
目錄下面的測(cè)試腳本add.test.js
,比如刪除一個(gè)測(cè)試用例匣沼,一旦保存狰挡,Mocha就會(huì)再次自動(dòng)運(yùn)行。
6.5 --bail, -b
--bail
參數(shù)指定只要有一個(gè)測(cè)試用例沒(méi)有通過(guò)释涛,就停止執(zhí)行后面的測(cè)試用例加叁。這對(duì)持續(xù)集成很有用。
$ mocha --bail

6.6 --grep, -g
--grep
參數(shù)用于搜索測(cè)試用例的名稱(即it
塊的第一個(gè)參數(shù))唇撬,然后只執(zhí)行匹配的測(cè)試用例它匕。
$ mocha --grep "1 加 1"

上面代碼只測(cè)試名稱中包含"1 加 1"的測(cè)試用例。
6.7 --invert, -i
--invert
參數(shù)表示只運(yùn)行不符合條件的測(cè)試腳本窖认,必須與--grep
參數(shù)配合使用豫柬。
$ mocha --grep "1 加 1" --invert

七告希,配置文件mocha.opts
Mocha允許在test
目錄下面,放置配置文件mocha.opts
烧给,把命令行參數(shù)寫(xiě)在里面燕偶。請(qǐng)先進(jìn)入demo03
目錄,運(yùn)行下面的命令础嫡。
$ mocha --recursive --reporter tap --growl

上面這個(gè)命令有三個(gè)參數(shù)--recursive指么、--reporter tap、--growl榴鼎。
然后伯诬,把這三個(gè)參數(shù)寫(xiě)入test目錄下的mocha.opts
文件。
--reporter tap--recursive--growl

然后檬贰,執(zhí)行mocha就能取得與第一行命令一樣的效果姑廉。
$ mocha

如果測(cè)試用例不是存放在test子目錄,可以在mocha.opts寫(xiě)入以下內(nèi)容翁涤。
server-tests--recursive

上面代碼指定運(yùn)行server-tests目錄及其子目錄之中的測(cè)試腳本桥言。
八、ES6測(cè)試
如果測(cè)試腳本是用ES6寫(xiě)的葵礼,那么運(yùn)行測(cè)試之前号阿,需要先用Babel轉(zhuǎn)碼。進(jìn)入demo04
目錄鸳粉,打開(kāi)test/add.test.js
文件扔涧,可以看到這個(gè)測(cè)試用例是用ES6寫(xiě)的。
import add from '../src/add.js';import chai from 'chai';let expect = chai.expect;describe('加法函數(shù)的測(cè)試', function() { it('1 加 1 應(yīng)該等于 2', function() { expect(add(1, 1)).to.be.equal(2); });});

ES6轉(zhuǎn)碼届谈,需要安裝Babel枯夜。
$ npm install babel-core babel-preset-es2015 --save-dev

然后,在項(xiàng)目目錄下面艰山,新建一個(gè).babelrc
配置文件湖雹。
{ "presets": [ "es2015" ]}

最后,使用--compilers參數(shù)指定測(cè)試腳本的轉(zhuǎn)碼器曙搬。
$ ../node_modules/mocha/bin/mocha --compilers js:babel-core/register

上面代碼中摔吏,--compilers
參數(shù)后面緊跟一個(gè)用冒號(hào)分隔的字符串,冒號(hào)左邊是文件的后綴名纵装,右邊是用來(lái)處理這一類文件的模塊名征讲。上面代碼表示,運(yùn)行測(cè)試之前橡娄,先用babel-core/register模塊诗箍,處理一下.js
文件。由于這里的轉(zhuǎn)碼器安裝在項(xiàng)目?jī)?nèi)挽唉,所以要使用項(xiàng)目?jī)?nèi)安裝的Mocha滤祖;如果轉(zhuǎn)碼器安裝在全局才避,就可以使用全局的Mocha。
下面是另外一個(gè)例子氨距,使用Mocha測(cè)試CoffeeScript腳本桑逝。測(cè)試之前,先將.coffee文件轉(zhuǎn)成.js文件俏让。
$ mocha --compilers coffee:coffee-script/register

注意楞遏,Babel默認(rèn)不會(huì)對(duì)Iterator、Generator首昔、Promise寡喝、Map、Set等全局對(duì)象勒奇,以及一些全局對(duì)象的方法(比如Object.assign)轉(zhuǎn)碼预鬓。如果你想要對(duì)這些對(duì)象轉(zhuǎn)碼,就要安裝babel-polyfill赊颠。
$ npm install babel-polyfill --save

然后格二,在你的腳本頭部加上一行。
import 'babel-polyfill'

九竣蹦、異步測(cè)試
Mocha默認(rèn)每個(gè)測(cè)試用例最多執(zhí)行2000毫秒顶猜,如果到時(shí)沒(méi)有得到結(jié)果,就報(bào)錯(cuò)痘括。對(duì)于涉及異步操作的測(cè)試用例长窄,這個(gè)時(shí)間往往是不夠的,需要用-t或--timeout參數(shù)指定超時(shí)門檻纲菌。
進(jìn)入demo05
子目錄挠日,打開(kāi)測(cè)試腳本timeout.test.js

it('測(cè)試應(yīng)該5000毫秒后結(jié)束', function(done) { var x = true; var f = function() { x = false; expect(x).to.be.not.ok; done(); // 通知Mocha測(cè)試結(jié)束 }; setTimeout(f, 4000);});

上面的測(cè)試用例翰舌,需要4000毫秒之后嚣潜,才有運(yùn)行結(jié)果。所以灶芝,需要用-t
或--timeout
參數(shù)郑原,改變默認(rèn)的超時(shí)設(shè)置唉韭。
$ mocha -t 5000 timeout.test.js

上面命令將測(cè)試的超時(shí)時(shí)限指定為5000毫秒夜涕。
另外,上面的測(cè)試用例里面属愤,有一個(gè)done
函數(shù)女器。it塊執(zhí)行的時(shí)候,傳入一個(gè)done
參數(shù)住诸,當(dāng)測(cè)試結(jié)束的時(shí)候驾胆,必須顯式調(diào)用這個(gè)函數(shù)涣澡,告訴Mocha測(cè)試結(jié)束了。否則丧诺,Mocha就無(wú)法知道入桂,測(cè)試是否結(jié)束,會(huì)一直等到超時(shí)報(bào)錯(cuò)驳阎。你可以把這行刪除試試看抗愁。
Mocha默認(rèn)會(huì)高亮顯示超過(guò)75毫秒的測(cè)試用例,可以用-s或--slow
調(diào)整這個(gè)參數(shù)呵晚。
$ mocha -t 5000 -s 1000 timeout.test.js

上面命令指定高亮顯示耗時(shí)超過(guò)1000毫秒的測(cè)試用例蜘腌。
下面是另外一個(gè)異步測(cè)試的例子async.test.js

it('異步請(qǐng)求應(yīng)該返回一個(gè)對(duì)象', function(done){ request .get('https://api.github.com') .end(function(err, res){ expect(res).to.be.an('object'); done(); });});

運(yùn)行下面命令饵隙,可以看到這個(gè)測(cè)試會(huì)通過(guò)撮珠。
$ mocha -t 10000 async.test.js

另外,Mocha內(nèi)置對(duì)Promise的支持金矛,允許直接返回Promise芯急,等到它的狀態(tài)改變,再執(zhí)行斷言驶俊,而不用顯式調(diào)用done方法志于。請(qǐng)看promise.test.js

it('異步請(qǐng)求應(yīng)該返回一個(gè)對(duì)象', function() { return fetch('https://api.github.com') .then(function(res) { return res.json(); }).then(function(json) { expect(json).to.be.an('object'); });});

十废睦、測(cè)試用例的鉤子
Mocha在describe
塊之中伺绽,提供測(cè)試用例的四個(gè)鉤子:before()、after()嗜湃、beforeEach()和afterEach()
奈应。它們會(huì)在指定時(shí)間執(zhí)行。
describe('hooks', function() { before(function() { // 在本區(qū)塊的所有測(cè)試用例之前執(zhí)行 }); after(function() { // 在本區(qū)塊的所有測(cè)試用例之后執(zhí)行 }); beforeEach(function() { // 在本區(qū)塊的每個(gè)測(cè)試用例之前執(zhí)行 }); afterEach(function() { // 在本區(qū)塊的每個(gè)測(cè)試用例之后執(zhí)行 }); // test cases});

進(jìn)入demo06
子目錄购披,可以看到下面兩個(gè)例子杖挣。首先是beforeEach
的例子beforeEach.test.js

// beforeEach.test.jsdescribe('beforeEach示例', function() { var foo = false; beforeEach(function() { foo = true; }); it('修改全局變量應(yīng)該成功', function() { expect(foo).to.be.equal(true); });});

上面代碼中刚陡,beforeEach
會(huì)在it之前執(zhí)行惩妇,所以會(huì)修改全局變量。
另一個(gè)例子beforeEach-async.test.js則是演示筐乳,如何在beforeEach之中使用異步操作歌殃。
// beforeEach-async.test.jsdescribe('異步 beforeEach 示例', function() { var foo = false; beforeEach(function(done) { setTimeout(function() { foo = true; done(); }, 50); }); it('全局變量異步修改應(yīng)該成功', function() { expect(foo).to.be.equal(true); });});

十一、測(cè)試用例管理
大型項(xiàng)目有很多測(cè)試用例蝙云。有時(shí)氓皱,我們希望只運(yùn)行其中的幾個(gè),這時(shí)可以用only
方法。describe塊和it塊都允許調(diào)用only方法波材,表示只運(yùn)行某個(gè)測(cè)試套件或測(cè)試用例股淡。
進(jìn)入demo07子目錄,測(cè)試腳本test/add.test.js就使用了only廷区。
it.only('1 加 1 應(yīng)該等于 2', function() { expect(add(1, 1)).to.be.equal(2);});it('任何數(shù)加0應(yīng)該等于自身', function() { expect(add(1, 0)).to.be.equal(1);});

上面代碼中唯灵,只有帶有only方法的測(cè)試用例會(huì)運(yùn)行。
$ mocha test/add.test.js 加法函數(shù)的測(cè)試 ? 1 加 1 應(yīng)該等于 2 1 passing (10ms)

此外隙轻,還有skip方法早敬,表示跳過(guò)指定的測(cè)試套件或測(cè)試用例。
it.skip('任何數(shù)加0應(yīng)該等于自身', function() { expect(add(1, 0)).to.be.equal(1);});

上面代碼的這個(gè)測(cè)試用例不會(huì)執(zhí)行大脉。
十二搞监、瀏覽器測(cè)試
除了在命令行運(yùn)行,Mocha還可以在瀏覽器運(yùn)行镰矿。



首先琐驴,使用mocha init
命令在指定目錄生成初始化文件。
$ mocha init demo08

運(yùn)行上面命令秤标,就會(huì)在demo08
目錄下生成index.html
文件绝淡,以及配套的腳本和樣式表。
<!DOCTYPE html><html> <body> <h1>Unit.js tests in the browser with Mocha</h1> <div id="mocha"></div> <script src="mocha.js"></script> <script> mocha.setup('bdd'); </script> <script src="tests.js"></script> <script> mocha.run(); </script> </body></html>

然后苍姜,新建一個(gè)源碼文件add.js
牢酵。
// add.jsfunction add(x, y) { return x + y;}

然后,把這個(gè)文件衙猪,以及斷言庫(kù)chai.js馍乙,加入index.html。
<script> mocha.setup('bdd');</script><script src="add.js"></script><script src="http://chaijs.com/chai.js"></script><script src="tests.js"></script><script> mocha.run();</script>

最后垫释,在tests.js里面寫(xiě)入測(cè)試腳本丝格。
var expect = chai.expect;describe('加法函數(shù)的測(cè)試', function() { it('1 加 1 應(yīng)該等于 2', function() { expect(add(1, 1)).to.be.equal(2); }); it('任何數(shù)加0等于自身', function() { expect(add(1, 0)).to.be.equal(1); expect(add(0, 0)).to.be.equal(0); });});

現(xiàn)在,在瀏覽器里面打開(kāi)index.html棵譬,就可以看到測(cè)試腳本的運(yùn)行結(jié)果显蝌。
十三、生成規(guī)格文件
Mocha支持從測(cè)試用例生成規(guī)格文件订咸。


進(jìn)入demo09
子目錄曼尊,運(yùn)行下面的命令。
$ mocha --recursive -R markdown > spec.md

上面命令根據(jù)test
目錄的所有測(cè)試腳本脏嚷,生成一個(gè)規(guī)格文件spec.md
骆撇。-R markdown
參數(shù)指定規(guī)格報(bào)告是markdown格式。
如果想生成HTML格式的報(bào)告spec.html
然眼,使用下面的命令艾船。
$ mocha --recursive -R doc > spec.html

(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末葵腹,一起剝皮案震驚了整個(gè)濱河市高每,隨后出現(xiàn)的幾起案子屿岂,更是在濱河造成了極大的恐慌,老刑警劉巖鲸匿,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蜘醋,警方通過(guò)查閱死者的電腦和手機(jī)蝴韭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)乔煞,“玉大人吁朦,你說(shuō)我怎么就攤上這事《杉郑” “怎么了逗宜?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)空骚。 經(jīng)常有香客問(wèn)我纺讲,道長(zhǎng),這世上最難降的妖魔是什么囤屹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任熬甚,我火速辦了婚禮,結(jié)果婚禮上肋坚,老公的妹妹穿的比我還像新娘乡括。我一直安慰自己,他們只是感情好智厌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布粟判。 她就那樣靜靜地躺著,像睡著了一般峦剔。 火紅的嫁衣襯著肌膚如雪档礁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天吝沫,我揣著相機(jī)與錄音呻澜,去河邊找鬼。 笑死惨险,一個(gè)胖子當(dāng)著我的面吹牛羹幸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辫愉,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼栅受,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起屏镊,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤依疼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后而芥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體律罢,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年棍丐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了误辑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歌逢,死狀恐怖巾钉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秘案,我是刑警寧澤睛琳,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站踏烙,受9級(jí)特大地震影響师骗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜讨惩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一辟癌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧荐捻,春花似錦黍少、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)魂角。三九已至,卻和暖如春野揪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斯稳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工海铆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挣惰,地道東北人殴边。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像珍语,于是被迫代替她去往敵國(guó)和親锤岸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容