20200924-3 单元测试,结对
作业要求参见:https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11243
结对对象:蒋慧
说明:编程语言 python 编程工具 pycharm
要求1 对每个功能,先给出测试用例,然后再编码功能。请注意把测试用例视为功能需求完成的检验指标。 (40分)
功能一:
序号 | 测试用例 | 预期结果 |
1 | 在命令行输入f4并回车。 | 输出第一道四则运算题,换行输出“?”,用户可在“?”后输入答案。 |
2 | 输入正确答案并回车。 | 提示“答对啦,你真是个天才!”,并换行输出下一道随机产生的四则运算题,换行输出“?”。 |
3 | 输入错误答案并回车。 | 提示“再想想吧,答案似乎是xxx(正确答案)喔!”,并输出下一道随机四则运算题,换行输出“?”。 |
4 | 回答完20道题并回车。 | 提示“你一共答对xxx(回答正确题数)道题,共20道题。”,并结束程序。 |
功能二:
序号 | 测试用例 | 预期结果 |
1 | 在命令行输入f4并回车。 | 随机生成一个带括号的四则运算题,换行输出“?”,用户可在“?”后输入答案。 |
2 | 输入正确答案并回车。 | 提示“答对啦,你真是个天才!”,并换行输出下一道随机产生的带括号四则运算题,换行输出“?”。 |
3 | 输入错误答案并回车。 | 提示“再想想吧,答案似乎是xxx(正确答案)喔!”,并输出下一道带有括号的四则运算题,换行输出“?”。 |
4 | 回答完20道题并回车。 | 提示“你一共答对xxx(回答正确题数)道题,共20道题。”,并结束程序。 |
功能三:
序号 | 测试用例 | 预期结果 |
1 | 在命令行输入f4 -c -3 | 提示“题目数量必须是 正整数。” |
2 | 在命令行输入f4 -c 3.5 | 提示“题目数量必须是 正整数。” |
3 | 在命令行输入f4 -c test | 提示“题目数量必须是 正整数。” |
4 | 在命令行输入f4 -c 10 | 生成.txt文件,文本中有10道不重复的题目及其答案。 |
TDD(UnitTest)测试用例:
序号 | 测试用例 | 预期结果 |
1 | 执行生成表达式函数:judeExpression() |
提示“create success 生成的表达式为: (2/10+4)*6” |
2 | 输入一个带括号的表达式:(1+8)*3+0,输入此表达式的正确答案:27 |
提示“answer same |
要求2 在博客报告测试用例全部fail 到 全部pass 的过程,报告事实 (fail到修改代码或者测试用例,到pass) 以及收获。 除了最初的框架,测试用例中存在一次性pass没有经过fail的,也报告一次性通过,给出如此优秀地实现了这部分功能的代码。由2位同学中的一位发布博客提交到作业,指明自己的结对伙伴;另一位在作业中引用这一博客,指明自己的结对伙伴。(40分)
功能一:
测试用例1-4:一次性pass 运行结果达到预期
运行截图:
主要代码:
生成表达式:
def expression(): op = ['+', '-', '*', '/'] num1 = random.randint(1, 10) num2 = random.randint(1, 10) num3 = random.randint(1, 10) num4 = random.randint(1, 10) op1 = random.choice(op) op2 = random.choice(op) op3 = random.choice(op) formula = str(num1) + str(op1) + str(num2) + str(op2) + str(num3) + str(op3) + str(num4) return formula
将正确答案按要求的形式输出:
def answer(fraction): n1 = fraction.numerator n2 = fraction.denominator if len(str(float(fraction))) > 15: # 如果正确结果无限,则以带分数形式输出 sub = int(n1 / n2) n1 = n1 % n2 if sub == 0: return '%d/%d' % (n1, n2) # 如果带分数的sub部分为0,则不输出这部分 else: return '%d %d/%d' % (sub, n1, n2) elif n2 == 1: # 结果是整数,原样输出 return n1 else: return float(fraction) # 结果是有限小数,原样输出
表达式求值并与输入答案对比:
n = 0 for f1 in ret: print(f1+'=') print('?', end="") result = Fraction(eval(input())).limit_denominator() # 输入的值转分数 answer = Fraction(eval(f1)).limit_denominator() # eval()计算表达式的值并转分数 if result == answer: n += 1 print('答对啦,你真是个天才!') else: print('再想想吧,答案似乎是{}喔!'.format(answer(answer))) print('你一共答对%d道题,共20道题。' % n)
功能二:
测试用例1-3:运行结果达到预期
运行截图:
测试用例4:运行没有达到预期结果,没有处理除数为0的情况。
运行截图:
由此发现:功能1产生表达式中随机数产生的范围是1-10,没考虑0的情况,修改范围为0-10
添加表达式判断代码:
def judeExpression(): i = 0 while(i != 1): try: a = expression() eval(a) i = i + 1 except: i = i return a
在function12()中将expression()修改为judeExpression():
def function12(): ret = [] # 存放表达式 for i in range(20): ret.append(judeExpression())
在expression()添加测试代码:
ret = ['1+4/0+3', '1+2*6/2'] formula = random.choice(ret) return formula
修改后测试截图:
功能三:
测试用例1:运行结果没有达到预期,没有相应提示
运行截图:
在function3(num)函数中添加判断参数的代码:
def function3(num): if num.isnumeric(): # str.isnumeric()判断是否只有数字 ret = [] # 存放表达式 for i in range(int(num)): ret.append(judeExpression()) n = 0 for f1 in ret: n = n + 1 if n == 1: if os.path.exists("题目输出.txt"): os.remove("题目输出.txt") answer = Fraction(eval(f1)).limit_denominator() # eval()计算表达式的值并转分数 formula = f1 + '=' + "\t\t" + str(answer(answer)) # 将表达式、空格、答案连接 writeFile(formula) else: print("题目数量必须是 正整数。")
修改后运行截图:
测试用例2-4:运行结果达到预期
运行截图:
收获:在单元测试的过程中,我和蒋慧同学发现了很多问题,除了上述提到的,在整合功能12及3到一个文件f4.py中时,发现根据作业要求功能12不需在命令行输参数,而功能3则需要输参数,最后是通过argparse解决的。通过完成此作业,我发现单元测试是非常有必要的,可以检测出自己之前没有发现的bug,进而改进程序。
要求4 使用coding.net做版本控制。checkin 前要求清理 临时文件、可执行程序,通常执行 build-clean可以达到效果。(5分)
代码地址:https://e.coding.net/zhangwenyan1/arithmetic0/arithmetic.git