TDD(测试驱动开发)代码优雅

从Unit Test到TDD再到BDD

2019-02-14  本文已影响174人  爱写作的harry

为什么要做单元测试(Unit Test)——What to Test

单元测试指的是对一个单元的代码进行测试,通常是一个函数,解决的是测试什么(What)的问题。当你的测试越来越多的时候,那测试可以发现的bug就会越多,软件的质量就会越高。

下面就是一个使用Jest和Chai的单元测试代码。

describe('Test Counter function', function() {
  test('Counter number should start from 0', function() {
    const counter = new Counter()
    expect(counter.number).to.be.equal(0)
  }
}

单元测试不一定非要使用测试框架来进行,我们完全可以自己写代码来测试,比如上面的测试代码我们可以用纯JavaScript来代替:

const counter = new Counter()
if (counter !== 0) throw new Error('Counter number should start from 0')

使用测试框架的好处是可以让我们写测试更方便,比如有测试结果报告,还有一些helper function来帮助我们更好的编写和组织测试代码,比如expect(counter.number).to.be.equal(0)就是测试框架提供的很容易理解的代码。

为什么要做TDD(Test Driven Development)——When to Test

TDD是一个流程,来自于Test First Development (TFD)和Refactoring(重构)的混合,TDD解决的是什么时候(When)测试的问题。很多单元测试只是用来验证function是否得到期望的输出,所以基本都是先完成所有的功能和function之后才去做测试,而TDD反其道而行之,先写测试,然后再实现功能,基本的过程是这样的:

  1. 功能定义好之后,先写单元测试,这时候所有的测试都会失败
  2. 编写功能,直到所有的测试都通过
  3. 持续重构代码,保证代码修改后,所有的测试都通过

这三个步骤是一个循环,每次开发新的功能都是重复这个循环。

为什么要做BDD(Behavior Driven Development)——How to Test

BDD要解决的是如何测试的问题,BDD是一种协作的方式,目的是让BD,产品和开发部门的人对于需求有充分一致的了解,防止因为理解的不一致导致的返工,让产品开发以大家期望的方式进行。

如何做呢,拿上面的例子来说,通常的测试是集中在代码的具体实现上:

describe('Test Counter function', function() {
  test('Counter number should start from 0', function() {
    const counter = new Counter()
    expect(counter.number).to.be.equal(0)
  }
}

而BDD是要求以行为为导向做测试,行为是指用户的行为,是从功能的角度来考虑的。这样来看的话,上面的例子本来是想测试每个新注册用户的积分数为0,这样使用BDD的方式来写这个测试的话,就会是这样:

describe('Test user related function', function() {
  test('New user score should start from 0', function() {
    const user = new User()
    expect(user.score).to.be.equal(0)
  }
}

这样是不是就非常通俗易懂了?通过这种思维方式的转变,不同部门的人都可以参与进来了,让对于功能的理解更加一致。另外,对于开发进度的跟踪也更加清晰,只需要看看还有多少失败的测试就大概知道了。

BDD需要与TDD和单元测试结合起来用,因为它们本身就是一脉相承的。

总结

通过对BDD,TDD和单元测试的介绍,我们了解了如何做,什么时候做和具体测什么的问题,从一个小的单元测试到BDD的流程化的思维,让我们看到了好的工具和好的流程的强大作用,它们让跨部门沟通更高效,让软件开发和维护更容易,最终让用户体验更加满意。

上一篇下一篇

猜你喜欢

热点阅读