• TDD vs. BDD


    如果你一直在关注最新的软件开发,你一定听过测试驱动开发(Test-driven development TDD)和行为驱动开发(Behavior-driven development BDD)。这篇文章说明比较了这两种不同的开发模式,并提供了例子。

     

    Test Drive Development,测试驱动开发

    当我第一次听说TDD,就觉得它是一个很简单的概念,TDD是使用测试案例等来驱动你的软件开发。

     

    如果我们想要更深入点了解TDD,我们可以将它分成五个不同的阶段:

    1.首先,开发人员编写一些测试方法。

    2.其次,开发人员使用这些测试,但是很明显的,测试都没有通过,原因是还没有编写这些功能的代码来实际执行。

    3.接下来,开发人员实现测试中的代码。

    4.如果开发人员写代码很优秀,那么在下一阶段会看到他的测试通过。

    5.然后开发人员可以重构自己的代码,添加注释,使其变得整洁,开发人员知道,如果新添加的代码破坏了什么,那么测试会提醒他失败。

     

    这种周期不断的循环下去,只要开发者有更多的功能需要开发。流程图如下:

    Test-driven development flowchart

     

    例子:

    我们来看看一个开发人员是怎么来做着几个步骤的。这篇文章的完整的代码在:https://github.com/jdavis/tdd-vs-bdd,代码免费下载,你可以使用以下命令来运行:npm install && grunt

    比方说,开发人员希望写一个简单的函数来极端阶乘(这个例子很简单,但它会告诉我们TDDBDD之间的差异)。TDD的常规做法是使用这个方法(function),然后断言(assert)计算结果符合条件。

    在这个例子中,我们将使用Javascript的测试框架中的Mocha。测试应该和下面这个差不多:

    var assert = require('assert'),

        factorial = require('../index');

    suit('Test', function(){

        setup(function(){

            //Create any objects that we might need

        });

        suit('#factorial()', function(){

            test('equals 1 for sets of zero length', function(){

                assert.equal(1, factorial(0));

            });

            test('equals 1 for sets of lengrh one', function(){

                assert.equal(1, factorial(1));

            });

            test('equals 2 for sets of lengrh two', function(){

                assert.equal(2, factorial(2));

            });

            test('equals 6 for sets of length three', function(){

                assert.equal(6, factorial(3));

            });

        });

    });

    很明显,测试会失败,因为我们还没有写函数。然后让我们来写满足测试条件的函数。这些函数可能像下面这样:

    module.exports = function(n) {

        if(n<0) return NaN;

        if(n===0) return 1;

        return n*(factorial(n-1));

    }

    现在我们运行这个测试,就可以通过了。下面我们看看BDD是怎样工作的。

     

    Behavior-Driven Development ,行为驱动开发

    好啦,现在你可能要问什么是BDD呢?这个定义呢,就有一点模糊了。有些人会说,它和TDD很像;还有人会说,这就是有着更好的指导的TDD

    不管它实际的定义是什么,这没有那么重要。最主要的是你要知道BDD可以消除TDD可能存在的问题。

    TDD比起来,BDD是需要我们先写行为规范(功能明细),在进行软件开发。功能明细和测试看起来非常相似,但是功能明细更加含蓄一些。

    例子:

    让我们继续看一下上面那个例子用BDD如何实现:

    var assert=require('assert'),

        factorial = require('../index');

    describe('Test', function(){

        before(function(){

            //Stuff to do before the tests, like imports, what not

        });

        describe('#factorial()', function(){

            it('should return 1 when given 0', function(){

                factorial(0).should.equal(1);

            });

            it('should return 1 when given 1', function(){

                factorial(1).should.equal(1);

            });

            it('should return 2 when given 2', function(){

                factorial(2).should.equal(2);

            });

            it('should return 6 when given 3', funcrion(){

                factorial(3).should.equal(6);

            });

        });

        after(function(){

            //Anything after the tests have finished

        });

    });

    最主要的区别在于描述的不同。BDD采用了更详细的方式使得它看起来就像是一句话。

    这就是我所说的BDD可以解决一些TDD可能导致的问题。让你的测试看起来更像一个句子,是一种认知上的转变,你会更多的去考虑如何写你的测试。有一种说法是,如果你可以毫无障碍的阅读你的测试,你自然会写出更好的、更全面的测试。

    这个例子很简单,我们不需要对其做过多的说明。BDD测试应该注重功能而不是实际的结果。你常常会听说BDD是帮助设计软件,而不是像TDD那样的测试软件。

    TDD VS BDD

    TDDBDD之间做选择是比较复杂的事情。这取决于你使用的语言是否有一个合适的测试框架,你的同事们是否熟悉他等等因素。

    有些人认为BDD总比TDD要好。因为它能够消除TDD带来的问题。

    BDD的关键在于,他并不是总能够保证阻止问题的发生。就像那些糟糕的代码组织或者是糟糕的设计的问题依然存在。使用测试让你写糟糕代码的可能性降低,从而有更强大的功能。

    结论

    哪一种测试方案会更好,这完全取决于个人。一个知道如何写优秀的TDD测试的人可能和另一个写优秀的BDD测试的人所写出代码的bug一样少。如果你发现你自己使用TDD写了不完整的测试,并希望设计更好的软件,那么不妨使用下BDD。如果你是一个学习TDDBDD的新手,我建议你先学习TDD。这两种风格最重要的部分就是强制你写你代码的测试样例。如果你从不测试你的代码,你会需要他们的。

    我不是一个研究TDDBDD的专家。我只是知道他们之间的一点区别,并研究了以下。再次说明,文中的代码位于:https://github.com/jdavis/tdd-vs-bdd。

    如果您对这篇文章有建议或错误改正。或者只是提出你的不同意的观点,我很乐意听到这一切。请随时与我联系。感谢您的阅读!

     

    原文链接:

    https://joshldavis.com/2013/05/27/difference-between-tdd-and-bdd/

  • 相关阅读:
    Shell基础:什么是shell脚本、2种脚本解释器、#!约定解释器类型、运行shell脚本的2种方式、shell变量命令规范/赋值/如何使用/只读变量/删除变量/变量类型、shell字符串及其常用方法、shell数组及其常用方法、shell注释
    Linux su命令:su命令语法、su root与su
    docker容器内使用apt报错E: List directory /var/lib/apt/lists/partial is missing.
    浅析事务是什么、mysql是如何实现事务提交和回滚的、保证事务持久性redo log的实现原理、保证事务一致性undo log的实现原理、事务ACID特性及其实现原理
    浅析前后端分离架构下的API安全问题:JWT保证token不被盗用的方案(即如何防范Replay Attacks)
    浅析如何保证缓存与数据库的双写一致性:4种更新缓存的设计模式理解
    浅析SpringCloud中断路器是什么、断路器的作用以及在Feign中使用断路器
    浅析后端微服务涉及到定时任务时如何解决多集群定时任务重复执行并发的方案对比
    Linux连续执行多条命令的写法区别
    Dockerfile中RUN/CMD/ENTRYPOINT命令区别
  • 原文地址:https://www.cnblogs.com/flowerPiggy/p/4054467.html
Copyright © 2020-2023  润新知