编写单元测试调用含argparse参数的方法时触发AttributeError
解决测试
count_users时的AttributeError及单元测试优化 错误原因分析
你遇到的AttributeError: 'dict' object has no attribute 'metrics'是因为:
- 你把argparse的
Action对象转换成了字典args,但字典仅支持[]键访问语法,不能用.属性访问(.是面向对象的属性调用方式) - 更核心的问题:测试
count_users根本不需要构造argparse解析器,这个函数的第二个参数metrics只是一个字符串(输出JSON的路径),而非argparse的Namespace对象。
修正后的测试代码
以下是修复错误并优化后的完整测试代码,包含完整的结果验证逻辑:
import tempfile import shutil import unittest from pyspark.sql import SparkSession, StructType, StructField, DecimalType from pyspark.sql import functions as F from decimal import Decimal # 假设你的业务代码已经导入count_users函数 # from your_module import count_users class TestUserCount(unittest.TestCase): def setUp(self): # 初始化SparkSession,放在setUp中复用 self.spark = SparkSession.builder \ .master("local[1]") \ .appName("test_count_users") \ .getOrCreate() def tearDown(self): # 测试结束后关闭SparkSession,释放资源 self.spark.stop() def test_count_users(self): # 1. 构造测试用的DataFrame df = self.spark.createDataFrame( data=[ (Decimal(0),), (Decimal(22),), ], schema=StructType( [ StructField("users", DecimalType(38, 4), True), ] ), ) # 2. 创建临时目录用于输出,避免生成垃圾文件 temp_dir = tempfile.mkdtemp() try: # 3. 直接调用count_users,传入临时目录作为metrics路径 count_users(df, temp_dir) # 4. 读取生成的JSON文件,验证统计结果是否正确 result_df = self.spark.read.json(temp_dir) user_count = result_df.select("user_count_values").first()[0] # 断言:users字段大于0的记录数应为1 self.assertEqual(user_count, 1) finally: # 5. 强制清理临时目录,保证测试环境干净 shutil.rmtree(temp_dir)
关键改进点
- 移除冗余的argparse代码:直接向
count_users传递字符串路径即可,测试无需重复构造命令行解析逻辑 - 使用临时目录:避免测试后残留无用文件,保证测试独立性
- 修正验证逻辑:原测试的
self.assertTrue(args["metrics"], 1)逻辑完全错误,现在改为验证生成的JSON文件中的统计值是否符合预期 - 统一管理SparkSession:通过
setUp和tearDown方法统一创建和销毁SparkSession,提升测试效率
额外补充
如果你的主逻辑中是通过argparse的Namespace对象传递参数(比如main函数中调用count_users(df, args.metrics)),测试main函数时才需要构造模拟的Namespace对象,示例如下:
def test_main(self): temp_dir = tempfile.mkdtemp() try: # 构造模拟的命令行参数对象 args = argparse.Namespace(metrics=temp_dir) # 调用main函数 main(args) # 验证结果逻辑同test_count_users... finally: shutil.rmtree(temp_dir)
内容的提问来源于stack exchange,提问作者Mike3355
相关产品推荐
相关产品推荐

