Python行数统计程序运行正常但PyTest测试失败,如何排查?
问题原因及解决方法:PyTest测试is_input_valid函数始终触发参数数量错误
问题根源
你的is_input_valid函数设计时预期接收列表类型的参数(对应命令行启动时的sys.argv,格式为[脚本名, 目标文件名]),但测试用例中传入的是字符串(比如"filename foo.bar")。
当传入字符串时,len(cl_arg)计算的是字符串的字符长度,而非命令行参数的个数。例如"filename foo.bar"的长度远大于2,所以函数直接进入最后的else分支,触发"Too few or many command-line arguments"的异常。
另外,单个with pytest.raises块里放多个函数调用的写法有问题:第一个调用触发异常后,后续代码不会执行,导致后面的断言实际没跑。
解决方法
1. 修改测试用例,传入正确格式的列表参数
把测试中传给is_input_valid的字符串改成列表,模拟sys.argv的结构(第一个元素是脚本名,第二个是目标文件名),同时拆分多个断言到独立的测试块或使用参数化:
from lines import is_input_valid, count_loc import pytest @pytest.mark.parametrize("args", [ ["filename", "foo.bar", "lang.py"], # 超过2个参数 ["filename"] # 不足2个参数 ]) def test_input(args): with pytest.raises(SystemExit, match="Too few or many command-line arguments"): is_input_valid(args) @pytest.mark.parametrize("args", [ ["filename", "foo.bar"], ["filename", "file.txt"] ]) def test_file_name(args): with pytest.raises(SystemExit, match="File is not a python(.py) file"): is_input_valid(args) def test_file_exists(): with pytest.raises(SystemExit) as e: is_input_valid(["filename", "abdcgr.py"]) assert str(e.value) == "File does not exist" def test_count_loc(): assert count_loc("fuel.py") == 20
2. (可选)优化原函数的参数校验逻辑
可以给is_input_valid函数加一层参数类型校验,避免非列表参数传入时出现混淆:
def is_input_valid(cl_arg)->str: # 新增:校验参数类型是否为列表 if not isinstance(cl_arg, list): sys.exit("Invalid argument format") if len(cl_arg) == 2: if cl_arg[1].endswith('.py'): # 用endswith比切片更健壮,支持.py结尾的长文件名 if os.path.isfile(cl_arg[1]): filename = cl_arg[1] else: sys.exit("File does not exist") else: sys.exit("File is not a python(.py) file") else: sys.exit("Too few or many command-line arguments") return filename
另外,原count_loc函数中row[0].lstrip()可能会引发索引错误(当行是空字符串时row[0]会报错),可以优化判断逻辑:
def count_loc(filename:str)->int: counter = 0 with open(filename) as file: for row in file: stripped_row = row.strip() # 跳过空行和注释行 if stripped_row and not stripped_row.startswith('#'): counter += 1 return counter
内容的提问来源于stack exchange,提问作者YoYo
相关产品推荐
相关产品推荐

