如何用Pytest对AWS私有子网进行多值断言与表格驱动测试?
解决pytest断言多个值与表格驱动测试的问题
咱们先拆解你遇到的两个核心问题:目标函数返回值错误,以及测试逻辑和表格驱动测试的实现问题,一步步来修复:
1. 先修复get_private_subnet_ids()的核心bug
你的函数现在每次匹配到符合条件的子网时,都会把private_subnet_ids这个列表直接覆盖成单个字符串(子网ID),而不是把ID添加到列表里。这就是为什么最后返回的总是最后一个匹配到的子网ID,而不是完整的列表。
修复后的函数代码:
def get_private_subnet_ids(accountid): # 补全函数定义里缺失的accountid参数 private_subnet_ids = [] vpc_client = aws_assumed_session_client(account_id=accountid, aws_service='ec2') subnets = vpc_client.describe_subnets() for subnet in subnets['Subnets']: if 'Tags' in subnet: for tag in subnet['Tags']: if tag['Key'] == 'Name' and tag['Value'].startswith('my-private'): # 把单个ID添加到列表,而非覆盖整个列表 private_subnet_ids.append(subnet['SubnetId']) print("[DEBUG]Queried Private Subnet ID's: {}".format(private_subnet_ids)) return private_subnet_ids
注意:原来的函数里调用
aws_assumed_session_client时用到了accountid,但函数定义里没声明这个参数,我已经补全了,避免运行报错。
2. 重构测试函数,实现表格驱动测试
pytest里的表格驱动测试通常用@pytest.mark.parametrize来实现,这样每个预期子网都会作为独立的测试用例执行,报错也能精准定位到具体哪个子网有问题。同时修正你的断言逻辑:
修复后的测试代码:
import pytest @pytest.mark.parametrize("expected_subnet", [ "subnet-0b6aaaf1ce07xx03", "subnet-0e54fda8f811fxxd8", "subnet-08f6d70b65a5cxx38" # 去掉了这里的前导空格,避免字符串匹配失败 ]) def test_sharing_private_subnets_exist(account_id, expected_subnet): """Tests to verify if expected private subnets exist in target account (table-driven test)""" # 一次获取完整的实际子网列表,避免重复调用AWS API actual_subnets = get_private_subnet_ids(account_id) # 断言预期子网在实际返回的列表中 assert expected_subnet in actual_subnets, f"Subnet {expected_subnet} does not exist in the target account"
关键修改点:
- 用
@pytest.mark.parametrize实现表格驱动:把每个预期子网作为参数传入测试函数,pytest会自动为每个参数生成独立的测试用例,这就是表格驱动测试的核心。 - 优化断言逻辑:先一次性获取完整的实际子网列表,再逐个检查预期子网是否在列表中,避免重复调用AWS接口,同时逻辑更清晰。
- 清理预期值:去掉了第三个预期子网的前导空格,避免因为字符串不一致导致无意义的断言失败。
3. 测试运行的注意事项
确保你的pytest命令能正确传递accountid参数,如果用了fixture来处理account_id,要保证fixture配置正确,比如:
def pytest_addoption(parser): parser.addoption("--accountids", action="store", help="Target AWS account ID") @pytest.fixture(scope="session") def account_id(request): return request.config.getoption("--accountids")
然后用你原来的命令运行即可:
pytest test_vpc_subnets.py --accountids 75381674129
为什么原来的测试会报错?
看你的报错信息:assert 'subnet-08f6d70b65a5cxx38' in 'subnet-0e54fda8f811fxxd8'——这说明你的get_private_subnet_ids()返回的是单个字符串,而不是列表,所以in操作变成了检查子字符串,而不是列表成员,这就是函数bug导致的连锁问题。
内容的提问来源于stack exchange,提问作者StarJedi
相关产品推荐
相关产品推荐

