如何在单元测试中添加自动测试,验证包示例脚本运行无错
如何在单元测试中添加示例脚本运行验证?
当然可以!我来给你分享两种常见单元测试框架下的实现方案,完美满足你只验证示例脚本能无错误执行的需求——不用断言返回值,只要脚本跑完没报错就算通过。
先明确项目结构参考
假设你的项目结构大概是这样的(方便后续代码路径定位):
your_package/ ├── your_package/ # 你的核心包代码 ├── examples/ # 存放示例脚本的文件夹 │ ├── example1.py │ ├── example2.py │ └── subdir/ │ └── example3.py └── tests/ # 单元测试文件夹 └── test_examples.py # 我们要写的测试文件
方案一:用Pytest实现(推荐,更简洁)
在tests/test_examples.py中写入以下代码:
import os import sys import subprocess import pytest # 获取examples文件夹的绝对路径,避免相对路径问题 EXAMPLES_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "examples") def get_example_scripts(): """遍历examples文件夹,获取所有需要测试的.py脚本""" scripts = [] for root, _, files in os.walk(EXAMPLES_DIR): for file in files: # 只处理.py结尾、非下划线开头的文件(排除临时文件/缓存) if file.endswith(".py") and not file.startswith("_"): scripts.append(os.path.join(root, file)) return scripts # 参数化测试:每个示例脚本对应一个独立的测试用例 @pytest.mark.parametrize("script_path", get_example_scripts()) def test_example_script_runs(script_path): # 用当前测试环境的Python解释器运行脚本,捕获输出 result = subprocess.run( [sys.executable, script_path], capture_output=True, text=True, check=False ) # 断言脚本执行返回码为0(无错误),失败时打印错误输出方便排查 assert result.returncode == 0, f"示例脚本 {script_path} 运行失败,错误输出:\n{result.stderr}"
代码说明
- 用
sys.executable代替硬编码的python,确保使用当前测试环境的解释器,避免环境不一致问题 - 自动遍历所有子文件夹里的脚本,不用手动逐个添加
- 每个脚本是独立的测试用例,运行时能清晰看到哪个脚本失败
- 失败时会打印脚本的错误输出,快速定位问题
方案二:用Unittest实现
如果你习惯用Python内置的unittest框架,可以这样写:
import os import sys import subprocess import unittest EXAMPLES_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "examples") def get_example_scripts(): scripts = [] for root, _, files in os.walk(EXAMPLES_DIR): for file in files: if file.endswith(".py") and not file.startswith("_"): scripts.append(os.path.join(root, file)) return scripts class TestExamples(unittest.TestCase): pass # 动态生成测试方法:每个脚本对应一个test_*方法 for script_path in get_example_scripts(): def make_test(script): def test_func(self): result = subprocess.run( [sys.executable, script], capture_output=True, text=True, check=False ) self.assertEqual( result.returncode, 0, f"示例脚本 {script} 运行失败,错误输出:\n{result.stderr}" ) return test_func # 给测试类添加命名规范的测试方法(比如test_example_example1) test_method_name = f"test_example_{os.path.basename(script_path).replace('.py', '')}" setattr(TestExamples, test_method_name, make_test(script_path)) if __name__ == "__main__": unittest.main()
代码说明
- 因为unittest没有pytest那样便捷的参数化,所以用动态生成测试方法的方式,每个脚本对应一个独立的测试用例
- 方法命名清晰,运行测试时能直接看到是哪个示例脚本出了问题
额外注意事项
- 如果某些示例脚本不需要测试,可以在
get_example_scripts函数里添加过滤规则(比如排除特定文件名/文件夹) - 如果示例脚本需要命令行参数,可以在
subprocess.run的参数列表里追加,比如[sys.executable, script_path, "--input", "data.txt"] - 确保测试环境安装了示例脚本依赖的所有包,否则会因为依赖缺失导致测试失败
内容的提问来源于stack exchange,提问作者5Ke
相关产品推荐
相关产品推荐

