TDD简介:
TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程。
TDD的原理是在开发功能代码之前,先编写单元测试用例代码,确定代码确定需要编写什么产品代码。
TDD的目的不仅仅是测试软件,测试工作保证代码质量仅仅是其中一部分,而且是在开发过程中帮助客户和程序员去除模棱两可的需求。TDD首先考虑使用需求(对象、功能、过程、接口等),主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证。
TDD开发过程:每次只考虑一个需求。首先编写一个测试代码,看看是否通过;然后编写实现这个测试的代码,运行所有测试并验证它们是否全部通过;最后,通过重构改进代码。不断重复此过程,直到成功实现所有需求。
优缺点:
优点:在任意一个开发节点都可以拿出一个可以使用,含少量bug并具一定功能和能够发布的产品。
缺点:增加代码量。测试代码是系统代码的两倍或更多,但是同时节省了调试程序及挑错时间。
使用python自带函数库,解决如下题目:
给定两个正数‘i’和‘v’,使用加、减、乘、除运算符对‘i’进行运算,使结果为‘v’,要求用到的运算符个数最少。例如:
输入:i=7,v=99 输出字符串:7*7+7*7+7/7
- 运算符只支持加、减、乘、除,不支持括号,不支持负号;
- 运算符的优先定义:乘/除同级,加/减同级;乘/除 高于 加/减;同等级按照从左到右的方式结合;
- i位于2到98之间;
- 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模块,对已存在的脚本文件代码测试。
编写测试用例的步骤:
- 先导入unittest模块;
- 创建一个类(任意名)继承unittest.TestCase;
- 编写需要测试的代码对函数进行各方面的测试。我们先只用上面一个函数举例即只包含一个方法的测试用例,主要检查函数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'。
-
上述代码以x=3,target=19为例,输出为:
-
Ran 1 test in 0.001s
OK
说明输出结果正确。