Assert未抛出ValueError:代码修改后无法触发异常的排查求助
问题:修改代码后不再抛出异常,如何修复?
诊断出ValueError断言失败的问题后,我根据评论修改了代码,但现在代码不会抛出异常了。代码哪里出问题了?该如何修复?
实际代码
def main(): fraction=input("Fraction: ") fraction_converted=convert(fraction) output=gauge(fraction_converted) print(output) def convert(fraction): while True: try: X,Y=fraction.split("/") x=int(X) y=int(Y) f=x/y if f<=1: p=int(f*100) return p else: fraction=input("Fraction: ") pass except (ValueError, ZeroDivisionError): raise def gauge(percentage): if percentage<=1: return "E" elif percentage>=99: return "F" else: return str(percentage)+"%" if __name__=="__main__": main()
测试代码
from fuel import convert, gauge import pytest def test_correct_input(): assert convert("1/2")==50 and gauge(50)=="50%" assert convert("1/4")==25 and gauge(25)=="25%" assert convert("0/4")==0 and gauge(0)=="E" assert convert("4/4")==100 and gauge(100)=="F" def test_zero_division(): with pytest.raises(ZeroDivisionError): convert("1/0") def test_value(): with pytest.raises(ValueError): convert("cat/dog")
问题分析
- convert函数职责越界:该函数本该只负责分数转百分比的逻辑,但现在内部嵌入了
while True循环和input调用,导致测试时传入无效参数(比如"5/4"),函数不会抛出异常,反而会阻塞等待用户输入,完全不符合测试预期。 - 无效分数未触发异常:当输入的分数大于1时,代码只是重新获取输入,没有抛出
ValueError,但测试用例明确要求这种情况属于无效输入,需要抛出异常。 - 循环逻辑干扰异常抛出:
while True循环存在时,部分无效场景会被循环覆盖,无法触发预期的异常抛出逻辑。
修复方案
把用户输入的循环逻辑移到main函数中,让convert只专注于转换逻辑,遇到无效输入直接抛出异常:
def main(): while True: try: fraction = input("Fraction: ") fraction_converted = convert(fraction) output = gauge(fraction_converted) print(output) break # 输入有效则退出循环 except (ValueError, ZeroDivisionError): continue # 输入无效则重新获取 def convert(fraction): X, Y = fraction.split("/") x = int(X) y = int(Y) if y == 0: raise ZeroDivisionError if x > y: raise ValueError # 用round避免int截断导致的精度问题 p = round(x / y * 100) return p def gauge(percentage): if percentage <= 1: return "E" elif percentage >= 99: return "F" else: return f"{percentage}%" if __name__ == "__main__": main()
修复说明
- 拆分职责:
main负责循环获取用户输入、处理异常并重试;convert只做字符串转百分比的纯逻辑转换,无效输入直接抛出对应异常,完全匹配测试用例要求。 - 明确异常触发条件:主动判断分母为0、分子大于分母的情况,抛出对应异常,覆盖所有无效输入场景。
- 优化百分比计算:用
round替代int,避免类似3/7这种情况被截断为42%(实际应为43%)的精度问题,结果更准确。
现在运行测试代码,所有用例均可通过:
test_correct_input:正常转换场景返回正确结果;test_zero_division:传入"1/0"会抛出ZeroDivisionError;test_value:传入"cat/dog"(转int失败)或"5/4"(分子大于分母)都会抛出ValueError。
内容的提问来源于stack exchange,提问作者python_beginner
相关产品推荐
相关产品推荐

