Python 2.7单元测试失败原因排查求助(附代码与目录结构)
排查Python 2.7单元测试失败:Calculator类evaluate方法问题
先理清楚你的场景:你用Python 2.7开发了一个Calculator类,放在3kyu/Calculator.py里,单元测试放在tester/Calculator_test.py,但测试一直失败却找不到原因。我帮你拆解问题,从代码逻辑到测试排查一步步来。
首先看你的Calculator.py代码问题
先把你的代码贴出来方便分析:
class Calculator(object): def evaluate(self, string): calc_lt = string.split(' ') result = '' for val in calc_lt: try: if val in ('()+-*/') or float(val): result += val except ValueError: return False return round(eval(result),4)
这段代码里有几个致命逻辑错误,这大概率是测试失败的核心原因:
运算符/括号的判断逻辑完全错误
当处理到运算符(比如+)或者括号(()时,float(val)会直接抛出ValueError,触发except分支直接返回False。举个例子,输入"2 + 3",split后得到['2', '+', '3'],处理到'+'时,float('+')报错,直接返回False,根本走不到eval步骤,测试用例自然失败。eval拼接的冗余操作
你把输入字符串split再拼接,其实完全没必要——原字符串"2 + 3"本身就可以直接传给eval,split再拼接反而没有任何作用,还引入了出错的可能。错误处理范围太窄
除了非数字/非运算符的输入,eval还可能抛出其他错误(比如语法错误、除零错误),你的代码只捕获了ValueError,会导致这些情况直接崩溃而不是返回预期结果。
修复后的Calculator.py代码
针对上面的问题,我调整了代码逻辑,保证基本的计算功能和错误处理:
class Calculator(object): def evaluate(self, string): # 先定义允许出现的字符:数字、运算符、括号、小数点、空格 allowed_chars = set('0123456789.()+-*/ ') # 检查输入字符是否合法 for char in string: if char not in allowed_chars: return False try: # 直接用原字符串eval,避免split拼接的冗余操作 calculation_result = eval(string) # 按要求保留4位小数 return round(calculation_result, 4) except (SyntaxError, ZeroDivisionError, ValueError): # 捕获语法错误(比如括号不匹配)、除零错误、非法数值错误 return False
单元测试的编写建议
你的测试代码没写完,我给你补一个基础的测试用例模板,放在tester/Calculator_test.py里:
import unittest import sys # 把项目根目录加入sys.path,确保能导入3kyu模块 sys.path.append('../') from 3kyu.Calculator import Calculator class TestCalculator(unittest.TestCase): def setUp(self): # 每个测试用例前初始化Calculator实例 self.calculator = Calculator() def test_basic_addition(self): self.assertEqual(self.calculator.evaluate("2 + 3"), 5.0) def test_basic_multiplication(self): self.assertEqual(self.calculator.evaluate("2 * 3"), 6.0) def test_expression_with_parentheses(self): self.assertEqual(self.calculator.evaluate("(2 + 3) * 4"), 20.0) def test_decimal_calculation(self): self.assertEqual(self.calculator.evaluate("2.5 + 3.75"), 6.25) def test_invalid_input(self): self.assertFalse(self.calculator.evaluate("2 + a")) def test_division_by_zero(self): self.assertFalse(self.calculator.evaluate("5 / 0")) if __name__ == '__main__': unittest.main()
排查测试失败的实用步骤
如果修复后还是有问题,按下面的方法定位:
- 运行测试时显示详细日志:在项目根目录执行
python -m unittest tester.Calculator_test -v,这样能看到每个测试用例的执行结果,以及具体的失败原因(比如是断言错误还是代码抛出异常)。 - 添加调试打印:在Calculator的evaluate方法里,打印输入的string、中间变量,看执行流程是否符合预期,比如:
def evaluate(self, string): print("Input string:", string) # 后续代码... - 检查模块导入问题:确保运行测试时是在项目根目录,或者已经把根目录加入sys.path,避免出现
ImportError。
内容的提问来源于stack exchange,提问作者Cian
相关产品推荐
相关产品推荐

