Info
上周 meeting 上同事說他們現在在用 java 寫 function test,產生了很多冗余的代碼,整個項目也變得比較臃腫。現在迫切需要個簡單的模板項目能快速搭建function test。
後來我回去想了想,為什麼我們非得用 java 來做 function test 呢?
Node.js 應該是個不錯的選擇,並且對 json 有著天然的支持,於是回去在 github 上隨手一搜,還果真有相關的項目:testosterone,於是便有了這篇blog.
Server
要做demo,自然要有相應的server來支撐。
在這裡我們選用Express作為server。
首先我們建立一個server的文件夾,新建package.json。
復制代碼 代碼如下:
{
"name": "wine-cellar",
"description": "Wine Cellar Application",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "3.x"
}
}
接下來run command
復制代碼 代碼如下:
npm install
這樣express就裝上了。
我們實現幾個簡單的 get post 方法來做實驗
復制代碼 代碼如下:
var express = require('express')
, app = express();
app.use(express.bodyParser());
app.get('/hello', function(req, res) {
res.send("hello world");
});
app.get('/', function (req, res) {
setTimeout(function () {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();
}, 200);
});
app.get('/hi', function (req, res) {
if (req.param('hello') !== undefined) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello!');
} else {
res.writeHead(500, {'Content-Type': 'text/plain'});
res.end('use post instead');
}
});
app.post('/hi', function (req, res) {
setTimeout(function () {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(req.param('message') || 'message');
}, 100);
});
app.get('/user', function(req, res) {
res.send(
[
{name:'jack'},
{name:'tom'}
]
);
});
app.get('/user/:id', function(req, res) {
res.send({
id: 1,
name: "node js",
description: "I am node js"
});
});
app.post('/user/edit', function (req, res) {
setTimeout(function () {
res.send({
id:req.param('id'),
status:1
});
}, 100);
});
app.listen(3000);
console.log('Listening on port 3000...');
testosterone
server 架設完畢,自然要開始做測試了。
這個 project 的接口的命名都挺優雅,直接上代碼。
首先是測試基本的功能
復制代碼 代碼如下:
var testosterone = require('testosterone')({port: 3000})
, assert = testosterone.assert;
testosterone
.get('/hello',function(res){
assert.equal(res.statusCode, 200);
})
.get('/hi',function(res){
assert.equal(res.statusCode, 500);
})
.post('/hi', {data: {message: 'hola'}}, {
status: 200
,body: 'hola'
});
然後針對上面模擬的user的get post 做簡單的測試。
復制代碼 代碼如下:
var testosterone = require('testosterone')({port: 3000})
, assert = testosterone.assert;
testosterone
.get('/user', function (res) {
var expectRes = [
{name:'jack'},
{name:'tom'}
];
assert.equal(res.statusCode, 200);
assert.equal(JSON.stringify(JSON.parse(res.body)),JSON.stringify(expectRes));
})
.get('/user/1', function (res) {
var user = JSON.parse(res.body);
assert.equal(res.statusCode, 200);
assert.equal(user.name, "node js");
assert.equal(user.description,"I am node js");
})
接下來,如果你想要針對每個test case 用 give when then 來描述的話,可以這樣:
復制代碼 代碼如下:
var testosterone = require('testosterone')({port: 3000, title: 'test user api'})
, add = testosterone.add
, assert = testosterone.assert;
testosterone
.add(
'GIVEN a user id to /user/{id} \n' +
'WHEN it have response user \n' +
'THEN it should return user json',
function (cb) {
testosterone.get('/user/1', cb(function (res) {
var expectRes = {
id: 1,
name: "node js",
description: "I am node js"
};
assert.equal(res.statusCode, 200);
assert.equal(JSON.stringify(JSON.parse(res.body)), JSON.stringify(expectRes));
}));
})
.add(
'GIVEN a POST a user info to /user/edit \n' +
'WHEN find modify success \n' +
'THEN it should resturn status 1',
function (cb) {
testosterone.post('/user/edit', {data: {id: 1, name: "change name"}}, cb(function (res) {
var res = JSON.parse(res.body);
assert.equal(res.status, 1);
}));
}
)
.run(function () {
require('sys').print('done!');
});
Conclusion
通過以上的代碼,可以看出,同java 冗長的 http 頭設置等,testosterone確實簡單和優雅了不少。