最近和团队同学们分享了测试驱动开发实践,把分享的内容同步在博客上,主要分为三个方面,简单介绍软件测试的发展历程,为什么需要使用TDD,TDD的在编码中的实践。

一,软件测试的发展历程

调试为主:  怎么知道程序满足了需求? 一个多职的情况下,不会区分调试和测试。
证明为主:  证明软件的工作是正确; 计算机应用数量,成本和复杂性都大幅度提升,测试就显得很必要了,当前阶段是为了测试是否满足需求。
破坏为主:  发现错误而执行的活动  ; 不仅为了证明软件做了该做的事情,也要保证它没做不该做的事情,这会使测试更加全面,更容易发现问题。
评估为主:  测试是以评价一个程序或者系统属性为目标的任何一种活动,测试是对软件质量的度量
预防为主:  测试是为了度量和提高被测软件的质量,对测试软件进行工程设计、实施和维护的整个生命周期

测试车轮图列出了针对不同场景的测试方法

二,为什么我们需要使用TDD

测试可以划分为白盒测试和黑盒测试,测试同学更偏向的是黑盒测试,开发同学做的自测,单元测试即白盒测试,黑盒和白盒都有各自的优劣。

TDD的设计原则

YAGNI,DRY,KISS,OCCAM原则代表TDD的思维核心,因为他们旨在于简化代码,而最后一个原则专注于类的编写和依赖关系。不管是不是基于TDD这些原则都适用。

在没有使用TDD之前,我们大部分乃至全部测试手动的,或者根本没有测试; 虽然使用是自动化测试,但并为测出真正问题; 编写自动化测试时间太晚 无法重构代码,担心破坏即有的功能, 维护成本高 ,上线时间长, 文档从来不是最新的 ,运行回顾测试的时间太长, 为了搞清楚方法定义耗时长。

使用TDD后,带来的明显好处是减少调试必要性,缩短上线时间,简化重构工作,利于更好设计,降低耦合度, 测试用例即文档, 代码测试覆盖率高。

同时使用TDD能够统一大家的开发规范,写出可读性,可为维护性更高,低bug的代码,提高产品上线的时间,提高团队和个人的效率,我们可以有更多的时间可以去做优化或提高自己的事情;

三,TDD的测试实践

红灯-绿灯-重构,过程是TDD最重要的组成部分,是最主要的支柱。如果没有它,TDD的其它方面根本行不通。 
      红灯:处于红灯状态,代码有问题。
      绿灯:一切都和预期一致,但不是最佳状态
      重构:因为都是处于绿灯状态,我们可以放心的去重构它,让它变的更好。

我们需要实现一个井字游戏,需求是当超过了棋盘的范围,应该抛出异常,操作流程如下:

@Rule
public ExpectedException expectedException = ExpectedException.none();@Test
public void playThrowException() {TicTacToe ticTacToe = new TicTacToe();//期望抛出非法操作异常expectedException.expect(IllegalArgumentException.class);//当前代码是报红的,因为方法不存证ticTacToe.play(3,2);
}

1. 首先编写一个测试,每次添加一个新功能的时候,我们应该首先做的是编写一个测试,在编写代码前专注于需求和代码设计。测试是可执行的文档,以后能够帮助理解代码目的及其背后的意图。当前,我们处于的是红灯状态,执行测试以失败告终,即测试对代码的期望和代码实际功能有一定的差距。因为我们没有实现具体的需求。 如果通过了,则代表这个功能已存在,就意味着这个测试没有意义,我们应该删除它。

public class TicTacToe {public void play(int x, int y) {if (x > 2 || y > 2 || x < 0 || y < 0) {throw new IllegalArgumentException("超出棋盘范围");}}
}

2.编写实现代码,这个阶段的目标是编写代码使最后一个测试通过。不要试图让代码完美无缺,也不要为编写花过多时间。即使编写的不好也没有关系,后面我们还有重构改进的阶段。这个阶段,我们依然处于红灯状态。虽然编写的代码可能让所有的测试都通过,但这种假设还未得到证实。

3.运行所有测试,而不是只运行最后编写的那个测试,这个很重要。因为可能你刚编写的测试通过,但是可能它破坏了整个应用程序的完整性。如果整个测试集执行速度缓慢,就昭示着测试编写得不好或者代码耦合度太高。耦合度太高将导致难以隔离外部依赖,进而增加执行测试所需的时间。在这个阶段,我们处于绿灯状态:所有的测试都通过了,且应用程序的行为符合预期。

4. 重构,前面的步骤都是必不可少的,但是这一步是可选的。虽然很少在每个周期结束后都进行重构,但是迟早需要甚至必须这样做。并非每个测试都需要重构;没有明确规定说什么时候该重构,什么时候不用重构。一旦认为可以更佳或更优的方式重写代码,那就是最佳的重构的时机。

5.重复所有的步骤都完成后(重构是可选的),在重复它们  1-4 过程。

最后需要注意的是,TDD的单元测试和传统的单元测试不一样,主要是编写时机,传统做法是先实现代码,后编写单元测试,而TDD中的顺序相反,先编写测试。未使用TDD的情况,单元测试是用于验证既有代码。 而在TDD中,应该将单元测试作为驱动开发和设计的动力,他们定义最小可能单元的行为,指定有待实现的微型需求。测试指出了你接下来该做什么以及该做到什么程度为止,至于要完成的工作量,则随测试类型(单元,功能,集成测试等)而异。
       TDD中,单元测试指定接下来应完成尽可能小的任务(KISS 设计原则 keep it simple stupid 保持简单)。通过编写范围很小的简单测试,可以确保这样测试实现起来也同样简单。通过要求测试不使用外部依赖,可以确保实现代码严格遵守关注点分离原则。
      总之,未使用TDD的情况下,单元测试的主要目标是验证既有代码;而在TDD中,单元测试是预先编写的,其主要目标是定义需求和设计,而验证只是副产品。与实现后在编写测试相比,这样做的一个结果是产品质量更高。TDD 迫使我们详细地考虑需求和设计,编写整洁而可行的代码,以及创建可执行的需求并频繁重构。另外,这样编写的单元测试代码覆盖率极高,每当对代码进行修改后,都可使用它们进行回归测试。

参考:
软件测试发展简史
《JAVA测试驱动开发》
《测试架构师修炼之道》

TDD测试驱动开发入门实践相关推荐

  1. Java重构与TDD测试驱动开发实际案例一-陈勇-专题视频课程

    Java重构与TDD测试驱动开发实际案例一-2117人已学习 课程介绍         本课程将高深的重构与TDD理论埋藏在一个实际案例中,深入浅出地演示了重构与TDD的完整步骤. 在这个真实的案例中 ...

  2. 谈谈个人对 TDD (测试驱动开发) 的理解

    文章目录 介绍 我心中的 TDD 如何做 Tasking 举个例子 - Tasking 纵向拆分 Story 背景 Story -- 粗略版 Story -- 清晰版 Story -- 扩充 Task ...

  3. TDD 测试驱动开发与精益

    1「引子」 2000年的时候,开始学软件工程,听到极限编程 (eXtreme Programming) 里面强调要测试驱动开发TDD (Test Driven Development). 后面在做培训 ...

  4. tdd测试驱动开发课程介绍_测试驱动开发的实用介绍

    tdd测试驱动开发课程介绍 by Luca Piccinelli 通过卢卡·皮奇内利 测试驱动开发很难! 这是不为人知的事实. (Test Driven Development is hard! Th ...

  5. TDD 测试驱动开发工具、框架、快捷键和测试覆盖率

    文章目录 TDD 测试驱动开发工具.框架.快捷键和测试覆盖率 TDD 测试驱动开发工具与框架 资源链接 IntellijIdea 快捷键 Intellij 中查看测试覆盖率 Intellij 的 Li ...

  6. TDD测试驱动开发学习心得

    TDD测试驱动开发学习心得 1:一些名词 TDD:Test-Driven Development 测试驱动开发 BDD:Behavior Driven Development 行为驱动开发 黑盒测试: ...

  7. 【架构 Flutter实践 Clean架构 TDD测试驱动开发---1.0】

    ----------- 2022-11-12 补充 ----------- 最近在开发中尝试用了clean架构,感觉就是 麻烦...太多模板代码,很容易过度开发. 我认为了解这些理念是很重要的,但应该 ...

  8. TDD 测试驱动开发笔记

    文章目录 测试驱动开发 TDD(Test Driven Development) 是什么 有什么用 执行步骤 例子 先写测试 运行测试:测试失败 修复:编写必要代码使测试通过 重构 参考 测试驱动开发 ...

  9. TDD测试驱动开发的基础

    ★ 如果您需要软件并且需要快速,那么测试驱动开发(TDD)可能是解决方案.TDD致力于快速将软件从计算机推向市场,是当今顶级软件开发和软件测试公司正在使用的最有效方法之一. " 什么是测试驱 ...

最新文章

  1. Geo-CNN的三维点云
  2. EnterpriseDB Migration 迁移工具使用测试(2)
  3. 三大新闻机构起诉FBI,FBI与苹果大战续集开幕?
  4. mysql 分库分表 ~ 方案选择浅谈
  5. FLEX SharedObject介绍及应用
  6. 一个用JAVA实现的线段树类--泛型 重构.
  7. swift operation
  8. 【6 插值方法】实例实战篇
  9. 两数之和—leetcode2
  10. IDE设置jdk和maven
  11. vlc android 移植版编译
  12. Android 平台电容式触摸屏的驱动基本原理
  13. python螺旋圆的绘制_python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)...
  14. virtualbox+oracle linux 6.3 下安装oracle 11.2.3.0
  15. 怎么把图片上的字去掉_视频片头怎么减掉,电脑如何剪切掉视频的开头「视频批量剪辑」...
  16. 环境变量PATH cp命令 mv命令 文档查看cat/more/less/head/tail
  17. 联想笔记本linux无线网卡,科学网—配置lenovo E430 + Ubuntu 13.04无线网卡 - 彭友松的博文...
  18. matlab怎么做跳动的桃心曲线,用matlab画跳动的爱心
  19. 【uni-app】uni-app实现手写签名效果:
  20. css实现背景图片的毛玻璃效果

热门文章

  1. Android 适配魅族去掉smartbar
  2. 2021年最新【阿里、头条、美团】【软件测试】面试题( 吐血整理 )
  3. No unique bean of type [com.ebei.qpi.backend.dao.AreaDao] is defined: Unsatisfi
  4. unsafe原理 java_Unsafe原理
  5. UI测试常见问题的总结
  6. 8.计算各商品销售金额
  7. 实验4 Linux安装与配置实验报告(部分英文)
  8. AttributeUsage属性
  9. Python将JSON文件转Excel的方法
  10. 富满电子华为鸿蒙,富满电子(300671)07月20日14:30大单揭秘