IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

一个简单的例子让你认识测试驱动

生生不息 2012-09-18 23:34:10 累计浏览 1,795 次
本机暂存

    前两天在一淘数据测试中启动了一个测试人员成长项目,叫做测试技术革新,其实就是一个系列培训计划。主要目的是为了帮助我们的测试人员成长,让他们可以更加胜任未来的自动化测试需要。

     在为测试技术革新项目挑选合适的主题的时候,我想到了测试驱动的开发过程。原因是这个过程既让测试人员可以了解一种好的开发过程,而又和测试本职工作相关,而且也比较容易理解。

     所以下面就是我对于测试驱动开发的一个过程介绍。

    什么是测试驱动开发?测试驱动开发(test driven development (TDD))是一个测试结果导向,可迭代的开发过程。我们直接从一个实例开始对测试驱动开发的讲解。

     假设,你被要求开发一个函数,lz_array_merge($new, $old),这个函数的目的是将$new数组里面的每一个内容,都覆盖给$old数组。第一个版本不考虑迭代,但是不排除迭代的可能性。

     那么如果是测试驱动开发,我们怎么做呢?

     首先先介绍一下测试驱动的开发流程,最重要的就是测试先行,而每一个小的迭代,只需要以让测试用例通过为前提。那么我们这个简单的小函数如果按照测试驱动开发,我们就会分成若干天作为迭代。

    第一天:

     测试用例:如果$new为空数组,那么直接返回空数组。

     测试代码:

    include(‘underTestFile.php’);

    $new = array();

    $old = array(

     'apple' => 60

     'banana'   => 100,

     );

    $ret = lz_array_merge($new, $old);

    print_r($ret);

    ?>

     测试期望:空数组。

     第一天的测试用例写完了,那么第一天的任务就变得非常简单:只要可以让这个测试用例通过,那么第一天的任务就算是完成了。所以我们进行第一天代码的编写:

    function lz_array_merge($new, $old)

    {

     if(count($new) == 0)

     return array();

    }

    ?>

     第二天:

     第一天的任务很顺利,我们接下来进行第二天的任务:

     测试用例:如果$old数组为空,就返回空数组。

     【注】:有读者问为什么这个函数$new不为空也不覆盖,这其实是我对这个函数的一个特定定义,我希望$new数组以$old数组为原形进行修改,也就是不希望$new数组给$old数组添加自己的元素。所以才会有这个测试用例。

     测试代码:

    include(‘underTestFile.php’);

    $new = array(

     'apple' => 60

     'banana'   => 100,

     );

    $old = array();

    $ret = lz_array_merge($new, $old);

    print_r($ret);

    ?>

     期望结果:空数组

     那么第二天的任务就变得简单了,我们只需要让这个测试用例和之前的一个测试用例都通过,那么就算是完成了。

     开发代码:

    function lz_array_merge($new, $old)

    {

     if(count($new) == 0)

    return array();

     if(count($old) == 0)

     return array();

    }

    ?>

     运行一下,测试用例通过了。很好,第二天的任务也完成了。但是还没到下班时间?那么我们来review一下我们写的代码,看看有没有可以精简的地方,既然都是返回空数组,我们是不是可以把这些东西放到一起?当然是可以的,所以重构:

    function lz_array_merge($new, $old)

    {

     if(count($new) == 0 || count($old) == 0)

    return array();

    }

    ?>

     再次运行测试用例,通过。我们可以放心的下班,因为我们的目的达到了,就是让两个测试用例通过。

     第三天:

     第三天是重头戏,早早的开始编写测试用例,因为第三天的测试用例是最重要的。

     测试用例:都不为空的话,$old里面的元素被$new分别覆盖

     测试代码:

    include(‘underTestFile.php’);

    $new = array(

     'banana'   => 60,

     );

    $old = array(

     'apple' => 60,

     'banana'   => 100,

     );

    $ret = lz_array_merge($new, $old);

    print_r($ret);

    ?>

     预期结果是:

    $result = array(

     'apple' => 100,

     'banana'   => 100,

     );

    ?>

     那么我们开始编写代码:

    function lz_array_merge($new, $old)

    {

     if(count($new) == 0 || count($old) == 0)

    return array();

    foreach($new as $key => $value)

    {

    $old[$key] = $value;

    }

    return $old;

    }

    ?>

     运行测试,发现三个测试用例都通过了,这让我们兴奋不已,第三天搞定了!但是依旧,我们要有一个重构的习惯,看一下有没有哪些可以去掉的代码。我们发现,判断数组是否为空是不需要的,那么我们就重构代码如下:

    function lz_array_merge($new, $old)

    {

    foreach($new as $key => $value)

    {

    $old[$key] = $value;

    }

    return $old;

    }

    ?>

     至此,我们三天的工作就完成了。一个完整的TDD流程也就走过一次了。

    这里也许你会问根据我们第三天的重构,我们前两天完全是没有必要的啊!没有产出一行代码。我不这么看,我认为前两天最大的贡献是我们产出了可被回归的自动化测试用例,以及测试驱动本身的流程,我们的代码得到了最好的保护。

    经过这个流程,也许你会对测试驱动的过程有一个比较好的认识。总结一下测试驱动的优点:

      可回归的自动化代码产出

      在开发前思考开发的调用

      开发人员有了边界,每天的工作就是测试用例的完成

      为其他开发人员提供了开发代码调用的示例

同分类推荐文章

  1. 科技爱好者周刊(第 401 期):如何赚到10亿美元 (2026-06-26 08:05:38)
  2. 如何做决策 - 从 Go 的一个 issue 说起 (2026-06-26 08:00:00)
  3. Seven Player:Windows上播放115网盘视频的增强工具 (2026-06-09 00:06:47)

查看更多 开发者 文章 →

建议继续学习

  1. 测试驱动开发(TDD)跟敏捷开发有冲突 (累计阅读 4,671)
  2. 什么是重构,什么不是重构 (累计阅读 4,614)
  3. web项目和单元测试 (累计阅读 4,236)
  4. 实践中的重构 (累计阅读 3,998)
  5. 如何设计软件模块的自动化测试? (累计阅读 3,007)
  6. TDD并不是看上去的那么美 (累计阅读 2,960)
  7. 你真正需要的代码测试覆盖率是多少? (累计阅读 2,947)
  8. 我心中的好程序员 (累计阅读 2,809)
  9. 结对编程实践 (累计阅读 2,791)
  10. 我们需要专职的QA吗? (累计阅读 2,792)