如何测试Boto3脚本:停用70天未登录/用密钥的AWS用户
针对AWS用户停用脚本的单元测试策略
结合你已经在做的代码重构(拆分独立函数),可以通过分层测试+依赖打桩的方式解决无法修改PasswordLastUsed字段的问题,具体策略如下:
1. 纯业务逻辑单元测试(核心优先)
对拆分出的纯逻辑函数(比如calculate_last_login)做全覆盖测试,完全不需要依赖AWS或Moto:
- 参数化覆盖边界场景:用测试框架的参数化功能(比如pytest的
@pytest.mark.parametrize),覆盖以下情况:- 刚好70天前的登录日期(验证不触发停用)
- 71天前的登录日期(验证触发停用)
PasswordLastUsed为None(用户从未登录,按业务规则判断是否触发停用)- 异常输入(比如未来日期、格式错误的日期字符串)
- 示例测试用例:
def test_calculate_last_login(): # 测试70天前的日期 seventy_days_ago = datetime.utcnow() - timedelta(days=70) assert calculate_last_login(seventy_days_ago) == 70 # 测试从未登录(None) assert calculate_last_login(None) > 70 # 按你的业务规则调整断言逻辑
2. AWS交互层的打桩测试
因为Moto和沙箱无法修改PasswordLastUsed和访问密钥的LastUsedDate,直接用Mock工具(比如unittest.mock或pytest-mock)打桩boto3客户端的返回值:
- Mock用户信息获取:模拟
iam.Client.get_user方法,返回自定义的PasswordLastUsed字段,验证脚本是否正确提取并传入计算函数:def test_get_user_last_login(mocker): # Mock boto3客户端 mock_iam = mocker.patch("boto3.client") mock_get_user = mock_iam.return_value.get_user # 构造自定义的PasswordLastUsed值 mock_get_user.return_value = { "User": { "UserName": "test-user", "PasswordLastUsed": datetime(2024, 1, 1, tzinfo=datetime.timezone.utc) } } # 调用你的函数 last_login = get_user_last_login("test-user") # 验证提取结果正确 assert last_login == datetime(2024, 1, 1, tzinfo=datetime.timezone.utc) - Mock访问密钥的最后使用时间:同理,模拟
list_access_keys和get_access_key_last_used方法,返回自定义的LastUsedDate,测试密钥过期判断逻辑。
3. 核心决策逻辑的独立测试
拆分出should_deactivate_user这类决策函数,接收last_login、last_key_used等参数,返回是否需要停用,单独测试所有组合场景:
- 登录过期但密钥未过期
- 密钥过期但登录未过期
- 两者都过期
- 两者都未过期
- 从未登录/从未使用密钥
4. 集成测试(可选,补充验证)
如果需要验证真实AWS环境的交互逻辑,可在沙箱中做以下操作:
- 创建测试用户,手动触发一次登录(比如用AWS CLI执行
aws s3 ls),生成真实的PasswordLastUsed字段 - 调用脚本扫描该用户,验证是否正确识别登录天数并执行对应操作
- 测试完成后清理测试用户
5. 异常场景测试
- Mock boto3调用抛出
ClientError(比如权限不足、网络错误),验证脚本的错误处理逻辑(比如日志记录、跳过出错用户) - 测试用户不存在、访问密钥已被删除等异常情况
内容的提问来源于stack exchange,提问作者tantan69
相关产品推荐
相关产品推荐

