TDD总结
TDD(测试驱动开发)是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。
TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程。
TDD的重要目的不仅仅是测试软件,测试工作保证代码质量仅仅是其中一部分,而且是在开发过程中帮助客户和程序员去除模棱两可的需求。TDD首先考虑使用需求(对象、功能、过程、接口等),主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证。
————摘自《百度百科》
刚刚接触TDD,感觉就是个坑啊,还没有掌握好之前学习的东西,又硬生生改变的思维去写测试,每一步都反复琢磨,才勉强写完一个测试。
现在测试工具有很多,我这里用的是Jasmine,Jasmine项目主页:https://github.com/pivotal/jasmine
Jasmine的基本的用法:
describe('pos', function () { }
describe表示一个测试组。接写来的测试都写在里面:it('should print correct text', function () {
spyOn(console, 'log'); printInventory(inputs); var currentDate = new Date(), year = dateDigitToString(currentDate.getFullYear()), month = dateDigitToString(currentDate.getMonth() + 1), date = dateDigitToString(currentDate.getDate()), hour = dateDigitToString(currentDate.getHours()), minute = dateDigitToString(currentDate.getMinutes()), second = dateDigitToString(currentDate.getSeconds()), formattedDateString = year + '年' + month + '月' + date + '日 ' + hour + ':' + minute + ':' + second; var expectText = '***<没钱赚商店>购物清单***\n' + '打印时间:' + formattedDateString + '\n' + '----------------------\n' + '名称:雪碧,数量:5瓶,单价:3.00(元),小计:12.00(元)\n' + '名称:荔枝,数量:2斤,单价:15.00(元),小计:30.00(元)\n' + '名称:方便面,数量:3袋,单价:4.50(元),小计:9.00(元)\n' + '----------------------\n' + '挥泪赠送商品:\n' + '名称:雪碧,数量:1瓶\n' + '名称:方便面,数量:1袋\n' + '----------------------\n' + '总计:51.00(元)\n' + '节省:7.50(元)\n' + '**********************'; expect(console.log).toHaveBeenCalledWith(expectText); });
其中:
it('should print correct text', function () { }
每一个这样的it语句块就是一个单元测试的内容,我们在‘ ’中写下这个单元的名称,一般是写我们想要得到的结果,然后再function里面得到我们想要的内容,在这里,我们用spyon模拟printInventory(inputs)中的console.log()函数,而
expect(console.log).toHaveBeenCalledWith(expectText);
就是将console.log输出的值与expectText匹配,如果匹配成功,测试才会通过,现在
printInventory(inputs);
还没有实现,所以肯定会报错的,新手可以在函数中写入:
var currentDate = new Date(), year = dateDigitToString(currentDate.getFullYear()), month = dateDigitToString(currentDate.getMonth() + 1), date = dateDigitToString(currentDate.getDate()), hour = dateDigitToString(currentDate.getHours()), minute = dateDigitToString(currentDate.getMinutes()), second = dateDigitToString(currentDate.getSeconds()), formattedDateString = year + '年' + month + '月' + date + '日 ' + hour + ':' + minute + ':' + second; var expectText = '***<没钱赚商店>购物清单***\n' + '打印时间:' + formattedDateString + '\n' + '----------------------\n' + '名称:雪碧,数量:5瓶,单价:3.00(元),小计:12.00(元)\n' + '名称:荔枝,数量:2斤,单价:15.00(元),小计:30.00(元)\n' + '名称:方便面,数量:3袋,单价:4.50(元),小计:9.00(元)\n' + '----------------------\n' + '挥泪赠送商品:\n' + '名称:雪碧,数量:1瓶\n' + '名称:方便面,数量:1袋\n' + '----------------------\n' + '总计:51.00(元)\n' + '节省:7.50(元)\n' + '**********************'; printInventory = function(inputs) { console.log('expectText'); };
以让测试成功通过,保证测试本身不是错的。
接下来我们可以删掉不必要的代码了,然后真正实现功能。
再多说一点关于测试的东西,前面说到describe表示一个测试组,在describe中可以写无数个it语句块用来测试每一个单元,如果有一个it语句块提示错误,那么就不是哪一个实现模块出错,有可能是实现代码整体就出错了,其他的it语句块碰巧通过了而已,所以当测试报错之后,首先看提示,如果expect的期望值和实际值匹配不一致,可以用倒推的思想,逐步检查到底哪一步出错了,如果是代码本身的问题,可能你就要重写代码了。这样的倒推效率也是比较低的,所以当我们写测试的时候,首先要根据功能确定好测试框架,保证整体的思维不是错的,测试可以小步小步的进行,保证每一个小的实现都有测试与之对应。这样,测试提示错误的时候,我们就很容易找到错误的源头。
上一篇: php实现可运算的验证码
下一篇: 土豆粉热量高吗,你爱吃吗