Tcao 2014-06-01
TDD是Test Driven Development的简称,意为测试驱动开发。测试驱动开发是一种软件的开发方法。它指在编写某个功能的代码之前先编写测试代码,然后编写能使测试通过的功能代码,逐个测试来实现软件的开发。测试驱动开发有助于提高代码质量和开发进度。
测试驱动开发一般步骤:
1.新增一个测试
2.运行所有测试,发现新增测试不能通过
3.做一些小改动,让程序可以运行
4.运行所有测试,并且全部通过
5.重构代码
我做的练习是一个测试一个四位随机数的例子(开发工具rubymine)
要求:产生一个四位数;每位必须是数字;第一个(或千位)数字不能是0;四位数的每位数字不能相同
首先根据要求写测试程序,下面是测试程序的基本模版:
describe("number", function () { beforeEach(function () { }); afterEach(function(){ }) it("should be four length ", function () { });
describe后面的number是对本页测试的一个总的描述。
beforeEach(function ( ) {})是对本页测试的一个初始化,只要加载过这个页面,他就会执行。
而afterEach(function (){ })是本页面的所有测试程序执行完后进行的操作,若涉及到相关的存储事件,一般添加 :
localStorage.clear();
意为清空本页涉及存储的所有数据,包括beforeEach(function ( ) {})执行过的初始化数据
上述测试程序我存储的文件名是number_spec.js。若要加载此页需要在SpecRunner.html中引入。下面是引入的格式:
<script type="text/javascript" src="spec/number_spec.js"></script>
根据我做的练习,下面是一部分例子:
it("should be four length ", function () { var number = creat_a_number().toString() expect(number.length).toEqual(4); });
这个是测试是关于所要求的数字是否是四位的。create_a_number( )是功能函数中的一个产生随机数的方法,在此处代表产生的随机数,而
create_a_number( ).toString()
将这个随机数转化为字符串形式,这样就可以根据字符串的长度来测试这个数是不是四位的。
expect(number.length).toEqual(4);
expect括号中的内容代表要测试的内容,toEqual括号中的内容表示要测试内容的结果,如果不一致则SpecRunner.html中就会报错
下面是判断生成的内容是否是数字:
it("should be a number", function () { var number = creat_a_number(); expect(isNaN(number) == 0).toEqual(true); });
这个测试用到了isNaN方法,用来判断是否全是数字,用的“==”,所以如果是数字则返回值是“true”
下面是判断这个随机数是否是随机产生的,其方法就是测试产生的随机数中的某个数的概率,设计离散数学相关思想。
it("should be randomly producing", function () { var numbers = []; for(var i = 0; i < 1000; i++){ var number = creat_a_number(); numbers.push(number); localStorage.numbers = JSON.stringify(numbers); } var same_number = _.filter(numbers,function(number){ return numbers[0] == number; }) var Probability = same_number.length/numbers.length; expect(Probability>=0.001 && Probability<0.005).toEqual(true); });
通过for循环产生一千个随机数,然后存储一下,此前我并没有存储,而是调用产生随机数的方法返回值,但那样容易导致电脑卡死,所以我就存储了一下,这样在 afterEach(function(){})就加上localStorage.clear(),结束本页测试后来清除这些数据。
var Probability = same_number.length/numbers.length;
先找到所产生的一千个随机数中的某一个,再找与这个随机数相等的存数在same_number数组中。通过上面两个数组的长度比来对比随机数的产生概率,下面的expect用到这个概率,给出这个概率的范围Probability>=0.001 && Probability<0.005(不要写成0.001<=Probability<0.005),只要这个概率在此范围就通过测试。概率范围自己设定。
此前我将产生一千个随机数及上面将数字转化为字符串和判断数字的方法均写到的功能函数中,这样就不符合测试驱动开发的思想了,也可以将这些方法写到一个专门的测试函数中
下面是有关随机数的功能方法内容,这是我写的一个产生所需要求的方法:
function creat_a_number(){ var one = Math.floor(Math.random()*9+1); var two = Math.floor(Math.random()*9+0); var three = Math.floor(Math.random()*9+0); var four = Math.floor(Math.random()*9+0); if(!(one!=two&&one!=three&&one!=four&&two!=three&&two!=four&&three!=four)){ return creat_a_number (); } var number = one*1000+two*100+three*10+four*1; localStorage.current_number = number; return number; }
Math.floor(Math.random()*9+1)是产生一个1到9的随机数的方法,若是产生0到9就是Math.floor(Math.random()*9+0)。
我后面要做的是猜数字,也就是猜这个随机数,而且若有几个位置相同且数字相同就返回几A,若位置不同但数字相同就返回几B,所以就需要对这个四位数进行拆分,取出每位的数字。这个用到parseInt方法,详细介绍见“http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp”;
function get_every_number(number){ var one = parseInt(number / 1000); var two = parseInt((number - one * 1000) / 100); var three = parseInt((number - one * 1000 - two * 100) / 10); var four = number % 10; var every_number = []; every_number.push(one,two,three,four) return every_number; }
前三个数字用的是减去上一位值,第四个数字要用减明显不太合适,它更适合用取余的方法。这样就可以将每位的数字取出与所猜测的数字逐位比较,返回相应的值。