CH04_构筑测试体系

重构是很有价值的工具,但只有重构还不行。要正确地进行重构,前提是得有一套稳固的测试集合,以帮我们发现难以避免的疏漏。即便有工具可以帮我自动完成一些重构,很多重构手法依然需要通过测试集合来保障。

自测代码的价值

程序员编写代码的时间仅占所有时间中很少的一部分,有些时间花在设计上,但是,花费在调试上的时间是最多的。修复bug通常是比较快的,但找出bug所在却是一场噩梦。当修复一个bug时,常常会引起另一个bug,却在很久之后才会注意到它。到时候又要花上大把时间去定位问题。

撰写测试代码的最好时机是在开始动手编码之前。

使用测试框架

测试常用的是断言(assert),不同的编程语言都有自己的测试框架。

c++

使用assert需要包含头文件

#include 

assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。

也可以使用c++相关的测试框架,如:Google Test、Boost.Test、CTest

c#

c# 项目中可通过Visual Studio 快速创建单元测试工程,也可以在代码中针对某个类快捷创建单元测试。

// 来源于网络上的测试代码示例
[TestMethod()]
public void GetTriangle_Test()
{
    // arrange  
    string[] sideArr = { "5", "5", "5" }; // 准备传给待测试方法的数据
    string expected = "等边三角形";

    // act  
    var actual = UnitTestClass.GetTriangle(sideArr); // 调用测试方法
    // assert  
    Assert.AreEqual(expected, actual); 
}

Python

python 通过unittest模块进行单元测试(以前没有用过)

# 来源于Python官网的测试代码示例
import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

探测边界条件

测试不能都聚焦于正常的行为上,把测试推到这些条件的边界处也是不错的实践,这可以检查操作出错时软件的表现。

直白一点就是:测试时不能只测试正常的场景,更应该测试不正常的场景。例如页面上的输入,输入正常、符合规则的数据表现正常,如果输入不符合规则的数据还能正常吗?(这也是大多数程序员测试自己的程序测不出来问题,换个人测试问题一堆的原因)

把测试集中在可能出错的地方。当测试数量达到一定程度之后,继续增加测试带来的边际效用会递减。

你可能感兴趣的:(重构)