TDD(Test Drived Develop)实战

TDD简介:      

       TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程。

       TDD的原理是在开发功能代码之前,先编写单元测试用例代码,确定代码确定需要编写什么产品代码。

       TDD的目的不仅仅是测试软件,测试工作保证代码质量仅仅是其中一部分,而且是在开发过程中帮助客户和程序员去除模棱两可的需求。TDD首先考虑使用需求(对象、功能、过程、接口等),主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证。

       TDD开发过程:每次只考虑一个需求。首先编写一个测试代码,看看是否通过;然后编写实现这个测试的代码,运行所有测试并验证它们是否全部通过;最后,通过重构改进代码。不断重复此过程,直到成功实现所有需求。

优缺点:

      优点:在任意一个开发节点都可以拿出一个可以使用,含少量bug并具一定功能和能够发布的产品。

      缺点:增加代码量。测试代码是系统代码的两倍或更多,但是同时节省了调试程序及挑错时间。

 使用python自带函数库,解决如下题目: 

给定两个正数‘i’和‘v’,使用加、减、乘、除运算符对‘i’进行运算,使结果为‘v’,要求用到的运算符个数最少。例如:

输入:i=7,v=99
输出字符串:7*7+7*7+7/7
  1. 运算符只支持加、减、乘、除,不支持括号,不支持负号;
  2. 运算符的优先定义:乘/除同级,加/减同级;乘/除 高于 加/减;同等级按照从左到右的方式结合;
  3. i位于2到98之间;
  4. v位于1到10的9次方的2倍之间。

解析:

首先,优先考虑乘法(指数增长最快),将x的每个组合看成一块,(每一个块都应该是 x 的次幂,形如: x / x(表示1),x,x * x,x * x * x,....;不用考虑形如 x * x / x 的表达式,因为一定有更优的方式达到相同的效果)。找到最接近target的指数块(lo = int(math.log(t,x)) ),然后比较target与x^lo(po = pow(x, lo))的大小,分三种情况:

(1)二者相等,直接输出;

(2)target > po,则二者相差target-po,然后递归;

(3)target < po,则二者相差po*x - target,然后递归;

直到target < x,则分两种情况进行比较,前后逼近,取最优。

具体算法如下:

def main(x, target):
    import functools
    import math
    #比较字符串中使用('+','-','*','/')的总个数,输出个数较少的
    def CompareLen(str1,str2):
        sum1,sum2 = 0,0
        for i in {'+','-','*','/'}:
            sum1 = sum1 + str1.count(i)
            sum2 = sum2 + str2.count(i)
        if sum1 < sum2:
            return str1
        else:
            return str2
        
    @functools.lru_cache(None)
    #递归+动态规划
    def dp(t):
        if t==0:
            return ''
        if t < x: #目标值小于除数
            str1 = (str(x) + '/' + str(x) + '+') * t
            str1 = str1[:-1]
            str2 = str(x) + ('-' + str(x) + '/' + str(x)) * (x-t)
            return CompareLen(str1,str2)
        
        lo = int(math.log(t,x))  
        po = pow(x, lo)  
        
        str3 = (str(x) + '*') * lo
        str3 = str3[:-1]
        if t == po: #target恰好是x的指数,直接输出
            return str3
        res = str3 + '+' + dp(t-po) #target不是x的指数,相差(target-po)或者(po*x-t)
        left = po * x - t
        if left < t: #只需讨论left < t,否者直接取res
            if '-' not in dp(left):
                s1 = dp(left)
                s1 = s1.replace('+','-')
                str4 = str3 + '*' + str(x) + '-' + s1
            else:
                s2 = dp(left)
                s2 = s2.replace('-','+')
                str4 = str3 + '*' + str(x) + '-' + s2
            res = CompareLen(res,str4) #比较使用符号的总数
        if res[-1] not in {'+','-','*','/'}:    
            return res
        else:
            return res[:-1]
    return dp(target)

x,target = map(int,input().split())
print(main(x,target))

下面使用python调用unittest模块,对已存在的脚本文件代码测试。

编写测试用例的步骤:

  1. 先导入unittest模块;
  2. 创建一个类(任意名)继承unittest.TestCase;
  3. 编写需要测试的代码对函数进行各方面的测试。我们先只用上面一个函数举例即只包含一个方法的测试用例,主要检查函数main()运行之后是否符合我们的预期。
    import unittest
    from TDD import main
    
    class MainTest(unittest.TestCase):
        """用于测试TDD.py"""
        #setUp初始化
        #s = main(x,target) #自己函数的输出
        def setUp(self):
            print("\n")
            print("test_case_start")
            pass
        #销毁
        def tearDown(self):
            pass
        #具体的测试用例,使用test开头
        def test_tdd(self):
            """是否能正确处理给出的数字"""
            main_str = main(3,19)  #将函数返回的结果存储到变量main_str中
            print(main_str)
            self.assertEqual(main_str,'3*3+3*3+3/3')#断言方法,用来核实得到的结果是否与我们预期的一致。
       
    
    if __name__ == '__main__':
        unittest.main()

    上面的测试代码是为检查输出的结果是否等于和智能却的结果,如果正确输出'OK'。

  4. 上述代码以x=3,target=19为例,输出为:

  5. Ran 1 test in 0.001s

    OK

说明输出结果正确。 

测试驱动的编程是 XP 困扰程序员的一个方面。对于测试驱动的编程意味着什么以及如何去做,大多数人都做出了不正确的假设。这个月,XP 方面的讲师兼 Java 开发人员 Roy Miller 谈论了测试驱动的编程是什么,它为什么可以使程序员的生产力和质量发生巨大变化,以及编写测试的原理。请在与本文相随的 论坛中提出您就本文的想法,以飨笔者和其他读者。(您也可以单击本文顶部或底部的“讨论”来访问该论坛。) 最近 50 年来,测试一直被视为项目结束时要做的事。当然,可以在项目进行之中结合测试,测试通常并不是在 所有编码工作结束后才开始,而是一般在稍后阶段进行测试。然而,XP 的提倡者建议完全逆转这个模型。作为一名程序员,应该在编写代码 之前编写测试,然后只编写足以让测试通过的代码即可。这样做将有助于使您的系统尽可能的简单。 先编写测试 XP 涉及两种测试: 程序员测试和 客户测试。测试驱动的编程(也称为 测试为先编程)最常指第一种测试,至少我使用这个术语时是这样。测试驱动的编程是让 程序员测试(即单元测试 ― 重申一下,只是换用一个术语)决定您所编写的代码。这意味着您必须在编写代码之前进行测试。测试指出您 需要编写的代码,从而也 决定了您要编写的代码。您只需编写足够通过测试的代码即可 ― 不用多,也不用少。XP 规则很简单:如果不进行程序员测试,则您不知道要编写什么代码,所以您不会去编写任何代码。 测试驱动开发(TDD)是极限编程的重要特点,它以不断的测试推动代码的开发,既简化了代码,又保证了软件质量。本文从开发人员使用的角度,介绍了 TDD 优势、原理、过程、原则、测试技术、Tips 等方面。 背景 一个高效的软件开发过程对软件开发人员来说是至关重要的,决定着开发是痛苦的挣扎,还是不断进步的喜悦。国人对软件蓝领的不屑,对繁琐冗长的传统开发过程的不耐,使大多数开发人员无所适从。最近兴起的一些软件开发过程相关的技术,提供一些比较高效、实用的软件过程开发方法。其中比较基础、关键的一个技术就是测试驱动开发(Test-Driven Development)。虽然TDD光大于极限编程,但测试驱动开发完全可以单独应用。下面就从开发人员使用的角度进行介绍,使开发人员用最少的代价尽快理解、掌握、应用这种技术。下面分优势,原理,过程,原则,测试技术,Tips等方面进行讨论。 1. 优势 TDD的基本思路就是通过测试来推动整个开发的进行。而测试驱动开发技术并不只是单纯的测试工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值