github 检查代码质量_07. 改善 GitHub 项目代码质量:测试
改善 GitHub 项目代码质量:测试TDD虽然接触的TDD时间不算短,然而真正在实践TDD上的时候少之又少。除去怎么教人TDD,就是与人结对编程时的switch,或许是受限于当前的开发流程。偶然间在开发一个物联网相关的开源项目——Lan的时候,重拾了这个过程。不得不说提到的一点是,在我们的开发流程中测试是由相关功能开发人员写的,有时候测试是一种很具挑战性的工作。久而久之,为自己的开源项目写测试变
改善 GitHub 项目代码质量:测试
TDD
虽然接触的TDD时间不算短,然而真正在实践TDD上的时候少之又少。除去怎么教人TDD,就是与人结对编程时的switch,或许是受限于当前的开发流程。
偶然间在开发一个物联网相关的开源项目——Lan的时候,重拾了这个过程。不得不说提到的一点是,在我们的开发流程中测试是由相关功能开发人员写的,有时候测试是一种很具挑战性的工作。久而久之,为自己的开源项目写测试变成一种自然而然的事。有时没有测试,反而变得没有安全感。
一次测试驱动开发
之前正在重写一个物联网的服务端,主要便是结合CoAP、MQTT、HTTP等协议构成一个物联网的云服务。现在,主要的任务是集中于协议与授权。由于,不同协议间的授权是不一样的,最开始的时候我先写了一个http put授权的功能,而在起先的时候是如何测试的呢?
curl--user root:root-X PUT-d'{ "dream": 1 }'-H"Content-Type: application/json"http://localhost:8899/topics/test
我只要顺利在request中看有无req.headers.authorization,我便可以继续往下,接着给个判断。毕竟,我们对HTTP协议还是蛮清楚的。
if(!req.headers.authorization){
res.statusCode=401;
res.setHeader('WWW-Authenticate','Basic realm="Secure Area"');
returnres.end('Unauthorized');
}
可是除了HTTP协议,还有MQTT和CoAP。对于MQTT协议来说,那还算好,毕竟自带授权,如:
mosquitto_pub-u root-P root-h localhost-d-t lettuce-m"Hello, MQTT. This is my first message."
便可以让我们简单地完成这个功能,然而有的协议是没有这样的功能如CoAP协议中是用Option来进行授权的。现在的工具如libcoap只能有如下的简单功能
coap-client-m get coap://127.0.0.1:5683/topics/zero-T
于是,先写了个测试脚本来验证功能。
varcoap=require('coap');
varrequest=coap.request;
varreq=request({hostname:'localhost',port:5683,pathname:'',method:'POST'});
...
req.setHeader("Accept","application/json");
req.setOption('Block2',[newBuffer('phodal'),newBuffer('phodal')]);
...
req.end();
写完测试脚本后发现不对了,这个不应该是测试的代码吗? 于是将其放到了spec中,接着发现了上面的全部功能的实现过程为什么不用TDD实现呢?
说说TDD
测试驱动开发是一个很”古老”的程序开发方法,然而由于国内的开发流程的问题——即开发人员负责功能的测试,导致这么好的一项技术没有在国内推广。
测试驱动开发的主要过程是:
先写功能的测试
实现功能代码
提交代码(commit -> 保证功能正常)
重构功能代码
而对于这样的一个物联网项目来说,我已经有了几个有利的前提:
已经有了原型
框架设计
TDD思考
通常在我的理解下,TDD是可有可无的。既然我知道了我要实现的大部分功能,而且我也知道如何实现。与此同时,对Code Smell也保持着警惕、要保证功能被测试覆盖。那么,总的来说TDD带来的价值并不大。
然而,在当前这种情况下,我知道我想要的功能,但是我并不理解其深层次的功能。我需要花费大量的时候来理解,它为什么是这样的,需要先有一些脚本来知道它是怎么工作的。TDD变显得很有价值,换句话来说,在现有的情况下,TDD对于我们不了解的一些事情,可以驱动出更多的开发。毕竟在我们完成测试脚本之后,我们也会发现这些测试脚本成为了代码的一部分。
在这种理想的情况下,我们为什么不TDD呢?
功能测试
轻量级网站测试TWilltwill was initially designed for testing Web sites, although since then people have also figured out that it’s good for browsing unsuspecting Web sites.
之所以说轻量的原因是他是拿命令行测试的,还有DSL,还有Python。
除此之外,还可以拿它做压力测试,这种压力测试和一般的不一样。可以模拟整个过程,比如同时有多少人登陆你的网站。
不过,它有一个限制是没有JavaScript。
看了一下源码,大概原理就是用requests下载html,接着用lxml解析html,比较有意思的是内嵌了一个DSL。
这是一个Python的库。
pip install twill
Twill 登陆测试
1.启动我们的应用。
2.进入twill shell
twill-sh
-=Welcometo twill!=-
current page:*empty page*
3.打开网页
>>go http://127.0.0.1:5000/login
==>at http://127.0.0.1:5000/login
current page:http://127.0.0.1:5000/login
4.显示表单
>>showforms
Form#1
## ## __Name__________________ __Type___ __ID________ __Value__________________
1csrf_token hidden csrf_token1423387196##5005bdf3496e09b8e2fbf450 ...
2email email emailNone
3password password passwordNone
4login submit(None)登入
current page:http://127.0.0.1:5000/login
5.填充表单
formclear1
fv1email test@tes.com
fv1password test
6.修改action
formaction1http://127.0.0.1:5000/login
7.提交表单
>>submit
Note:submitisusingsubmit button:name="login",value="登入"
current page:http://127.0.0.1:5000/
发现重定向到首页了。
Twill 测试脚本
当然我们也可以用脚本直接来测试login.twill:
go http://127.0.0.1:5000/login
showforms
formclear1
fv1email test@tes.com
fv1password test
formaction1http://127.0.0.1:5000/login
submit
go http://127.0.0.1:5000/logout
运行
twill-sh login.twill
结果
>>EXECUTING FILE login.twill
AT LINE:login.twill:0
==>at http://127.0.0.1:5000/login
AT LINE:login.twill:2
Form#1
## ## __Name__________________ __Type___ __ID________ __Value__________________
1csrf_token hidden csrf_token1423387345##7a000b612fef39aceab5ca54 ...
2email email emailNone
3password password passwordNone
4login submit(None)登入
AT LINE:login.twill:3
AT LINE:login.twill:4
AT LINE:login.twill:5
AT LINE:login.twill:6
Settingactionforform(,)to('http://127.0.0.1:5000/login',)
AT LINE:login.twill:7
Note:submitisusingsubmit button:name="login",value="登入"
AT LINE:login.twill:9
==>at http://127.0.0.1:5000/login
--
1of1files SUCCEEDED.
一个成功的测试诞生了。
Fake Server
实践了一下怎么用sinon去fake server,还没用respondWith,于是写一下。
这里需要用到sinon框架来测试。
当我们fetch的时候,我们就可以返回我们想要fake的结果。
vardata={"id":1,"name":"Rice","type":"Good","price":12,"quantity":1,"description":"Made in China"};
beforeEach(function(){
this.server=sinon.fakeServer.create();
this.rices=newRices();
this.server.respondWith(
"GET",
"http://localhost:8080/all/rice",
[
200,
{"Content-Type":"application/json"},
JSON.stringify(data)
]
);
});
于是在 afterEach 的时候,我们需要恢复这个server。
afterEach(function(){
this.server.restore();
});
接着写一个jasmine测试来测试
describe("Collection Test",function(){
it("should get data from the url",function(){
this.rices.fetch();
this.server.respond();
varresult=JSON.parse(JSON.stringify(this.rices.models[0]));
expect(result["id"])
.toEqual(1);
expect(result["price"])
.toEqual(12);
expect(result)
.toEqual(data);
});
});
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)