TDD的测试周期

简介: 简单概括了TDD的开发方式的周期,提到了如何一步步使得测试迅速工作的步骤,点明、强调了微小进步在TDD中的可贵之处。

测试驱动开发的编写周期

(简单的总体把握)

应该知道,没有测试,就没有功能代码。测试驱动开发这种编程方式怎么开始呢,那就是先写一个新的测试

梗概如下:

  1. 添加一个测试;

    /**
    要明白,现在这个测试里所用到的类和方法都是不存在的。此时的测试甚至是编译无法通过!
    */
    @Test
    public void testMovieRating() {
        Movie starWars = new Movie("Star Wars");
        starWars.addRating(3);
        starWars.addRating(5);
        assertEquals("Bad average rating", 4, starWars.getAverageRating());
    }
  1. 运行所有的测试并查看失败的;

    /**
    通过运行所有的测试,我们将会收到错误的信息提示,告诉了我们现在测试中存在的问题。可想见如下:
    1.不存在Movie类
    2.不存在addRating()
    3.不存在getAverageRating()
    如何解决?很简单,按照提示,利用开发环境(编译器如IDea)的强大功能迅速创建一个Movie类、方法。
    */
    public class Movie {
        public Movie(String name) {}
        public void addRating(int newRating) {}
        public int getAverageRating() { return 0;}
    }

可以看见上面示例,所有的类和方法都是一个外壳,仅仅提供了外部行为,内部的实现都是哑实现(有着返回值的方法都应该初步返回一个简单的默认值!)。可想见,现在测试已经通过了编译,再运行试试呢?失败!提示我们:Bad average rating 期待的是4,实际的是0。 为了使测试能够通过,我们要“不折手段”了!既然想要4,那么我们这样做:

public int getAverageRating() { return 4;}

现在,重新运行所有!测试呢:通过!!接下来要做的事情就是重构。

  1. 对测试进行微小的改动;(书中原话——测试驱动开发 Kent Beck)【为什么不是对功能代码进行微小修改,怎么是对测试呢。。】
  2. 通过重构去掉重复部分。(重复部分是指测试中的数据与程序之中的数据之间的重复)

    /**
    上面的功能代码仅仅能完成那个期待4的测试。要想程序更加通用,接下来我们要泛化程序。
    目标就是:让程序能够计算后返回电影评分的平均值。于是我们需要对程序里的4这个常量做出思考:
      要想泛化,就不能是常量(在这儿来看),所以要将它替换为一个变量。
      4从何来?可以想见:Movie类里有着添加评分的方法addRating(),
      所以4=(3+5)/2,即 平均分=总评分/评分次数。于是:
    */
    public class Movie {
        private int totalRating = 0;
        private int numberOfRatings = 0;
        public Movie(String name) {}
        public void addRating(int newRating) { 
            totalRating += newRating;
            numberOfRatings++; 
            /**
             从上往下,我们已经做了很多修改,记住:本应该修改就要重新测试,不过明显从前面到这儿的修改,
    不会出错,那么就省去每添一句新的代码就重新测试这样繁杂、死板的步骤吧。
    不过现在我们已经设计到了一个方法的很多修改,我想是时候去运行一遍测试,祈祷不会出现问题吧。
            */
            //很好,,,测试可以工作!那么继续修改
        }
        public int getAverageRating() { 
            // return 4;
            return totalRating / numberOfRatings;
            // 刚才我们已经把常量替换掉了!测试是否还能工作呢?运行,,通过!
            /**
            例子结束了,现在可以选择一件事情,就是再添加一个测试,来验证这个功能代码是否真的被我们泛化了。
            同时从这可以引申出,我们是否可以考虑在 return 4 的时候
            就编写这样一个新的不同的平均分(比如测试平均分为5)的测试,然后
            为了测试能够工作,而对功能代码进行泛化呢?
            所以这就有了选择,看你自己,是否愿意在 return 4 这样一个常量的时候去
            编写一个同样目的但测试的期待结果不同的新测试来强制提醒你将功能代码泛化;
            还是说愿意在之后写一个为了检验是否泛化的新测试!
            */
        }
    }

要明白:测试驱动开发的要点不在于采取了哪些措施,而在于能够取得这些微小进步本身。(微小进步,有多微小呢?它甚至使得我们每一次的前进步伐控制在了幅度非常小,比如仅仅创建一个类的外壳、方法的外壳、字段的创建,这样微小的前进步伐)因为如能够做到很小的改进,也一定可以完成你所需要规模的改进。

从上面例子归纳出:使指示条迅速变绿的三项策略:

  1. 伪实现:也就是那些微小进步的一个体现,通过创建出外壳,直接返回测试所期待的一个常量值来让测试通过,然后逐渐用变量取代它!
  2. 使用显明实现:直接键入真正的代码实现。
  3. 三角测量:目的是使得我们从不同角度去看待问题,从而得出结果,比如为了写出判断两个对象相等的功能代码,我们还可以测试其不相等的情况!

实践中使用TDD时候,通常交替使用伪实现和显明实现:当所有事情变得顺畅时候,使用显明实现吧;一旦测试未通过,意外出现了红色指示条,那就做好备份回到伪实现!

END

2019年11月3日,11点26分

目录
相关文章
|
1月前
|
Java 测试技术 开发者
提高代码质量:深入实践测试驱动开发(TDD)
【8月更文挑战第14天】测试驱动开发是一种强大的软件开发方法,它通过先写测试再编写代码的方式,显著提高了代码质量。通过实践TDD,开发者可以编写出更可靠、更易于维护的代码,并加速开发进程。虽然TDD需要一定的学习和适应过程,但其带来的长期收益是不可估量的。如果你还没有尝试过TDD,现在就开始吧!
|
1月前
|
测试技术 Go
写出高质量代码的秘诀:Golang中的测试驱动开发(TDD)
写出高质量代码的秘诀:Golang中的测试驱动开发(TDD)
|
2月前
|
Java 测试技术
Java中的测试驱动开发(TDD)实践
Java中的测试驱动开发(TDD)实践
|
4月前
|
敏捷开发 测试技术
深入理解并应用测试驱动开发(TDD)
【5月更文挑战第30天】测试驱动开发(TDD)是一种先编写测试用例再写代码的方法论,核心是"先测试,后开发"。通过"红-绿-重构"的循环,确保代码正确性,提升简洁性和可维护性。TDD步骤包括编写测试用例、运行测试、编写实现代码、重构及循环迭代。它能提高代码质量,促进团队合作,降低维护成本,并适应敏捷开发。在开发实践中,应用TDD能有效提升效率和代码质量。
|
4月前
|
算法 测试技术 开发者
测试驱动开发(TDD)实战:从理论到实践
【5月更文挑战第8天】TDD实战指南:先测试后开发,确保代码质量与可维护性。核心思想是编写测试用例→实现代码→验证→重构。优点包括提高代码质量、促进设计思考和增强可测试性。实战步骤包括编写独立、明确的测试用例,遵循最小可用原则编写代码,运行测试并分析失败原因,以及在验证通过后进行代码重构与优化。通过TDD,开发者能提升编程技能和项目成功率。
|
4月前
|
测试技术 持续交付 Swift
【Swift开发专栏】Swift中的测试驱动开发(TDD)
【4月更文挑战第30天】Test-Driven Development (TDD) 是一种软件开发方法,强调先编写测试用例再写代码。通过测试驱动代码、简明设计、重构和持续集成的循环过程,TDD助力构建高质量Swift软件。在Swift中,使用XCTest框架进行TDD实践,包括编写测试用例、实现功能、运行测试和重构。TDD的优势在于提升代码质量、减少调试时间,且与持续集成相结合。然而,学习曲线和确保测试覆盖率是挑战。TDD不仅是技术实践,也是思维方式,随着Swift的发展,其应用将更广泛。
50 3
|
4月前
|
测试技术 开发者
【专栏】测试驱动开发(TDD)和行为驱动开发(BDD)的核心概念与实践
【4月更文挑战第27天】本文探讨了测试驱动开发(TDD)和行为驱动开发(BDD)的核心概念与实践。TDD强调先写测试用例,通过测试推动设计,确保代码质量与可维护性。BDD侧重软件行为和业务价值,提倡使用通用语言描述行为,减少沟通障碍。选择TDD或BDD取决于项目复杂性、团队技能和业务需求。理解两者差异有助于团队做出合适的选择,发挥测试的最大价值。
107 3
|
4月前
|
IDE Java 测试技术
Java 测试驱动开发(TDD)实践指南
【4月更文挑战第19天】测试驱动开发(TDD)在Java中强调先写测试用例再写代码,以提升代码质量和可维护性。核心原则是先写测试,确保代码功能正确,降低风险并促进良好设计。实践包括选择IDE,安装JUnit,明确需求,编写失败测试,写最小代码使测试通过,重构并重复该过程。编写测试用例应明确、独立且可重复。TDD能增强开发信心,提高效率,保证代码维护性。遵循指南,开发者能写出高质量代码,为未来开发打下基础。
120 9
|
4月前
|
测试技术 Python
Python中的单元测试与测试驱动开发(TDD)实践
Python中的单元测试与测试驱动开发(TDD)实践
129 0
|
4月前
|
自然语言处理 测试技术
测试驱动开发(TDD)与行为驱动开发(BDD)的比较与选择
在软件开发中,测试驱动开发(TDD)与行为驱动开发(BDD)是两种常见的开发方法。虽然它们都强调测试在开发过程中的重要性,但是两者之间存在一些差异。本文将对TDD和BDD进行比较,分析它们各自的优点和缺点,以及在实际开发中如何选择最适合的方法。