如何为依赖用户输入凭证的Python包编写GitLab CI测试?
处理依赖凭证的Python包GitLab CI测试方案
一、分层拆分测试,降低真实凭证依赖
- 单元测试:Mock底层调用,专注逻辑验证
不用碰真实凭证,只测你的包的业务逻辑层。用unittest.mock或pytest-mock模拟keyring的凭证获取,以及S3/Hive/Trino客户端的返回结果就行。
比如测试S3读取功能时,直接mock掉boto3.client的get_object方法,返回预设的测试数据,验证你的包是否正确处理这个结果:from unittest.mock import patch import my_package def test_s3_read(): with patch('my_package.boto3.client') as mock_client: mock_get = mock_client.return_value.get_object mock_get.return_value['Body'].read.return_value = b'test content' result = my_package.read_s3('test-bucket', 'test-key') assert result == 'test content' - 集成测试:用隔离的测试环境
申请公司内部的测试环境——比如专门的测试S3桶、Hive/Trino测试集群,这些环境权限有限,就算凭证出问题影响也小,专门用来跑需要真实资源访问的集成测试。
二、GitLab CI安全获取凭证的两种方式
- 直接用GitLab项目变量存凭证
去GitLab项目的「设置」→「CI/CD」→「变量」里添加敏感凭证(比如AWS_ACCESS_KEY_ID、TRINO_PASSWORD),记得勾选「保护」和「掩码」,这样变量不会在CI日志里明文显示,只有受保护分支能访问。
在.gitlab-ci.yml里直接引用这些变量:integration_test: script: - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY - pytest tests/integration/ - 对接公司内部密钥管理器
如果公司用了HashiCorp Vault、AWS Secrets Manager这类工具,在CI里用对应的CLI拉取凭证:
比如用Vault的话,先通过GitLab变量存好Vault的角色ID和密钥ID,然后登录Vault读取测试凭证:integration_test: script: - vault login -method=approle role_id=$VAULT_ROLE_ID secret_id=$VAULT_SECRET_ID - export AWS_ACCESS_KEY_ID=$(vault kv get -field=access_key secret/test/aws) - export AWS_SECRET_ACCESS_KEY=$(vault kv get -field=secret_key secret/test/aws) - pytest tests/integration/
三、适配keyring在CI环境的使用
CI环境一般是无头Linux,默认的keyring后端用不了,两种解决办法:
- CI环境优先读环境变量
在你的包加个判断:如果检测到CI环境变量(GitLab CI会自动设置),就直接从环境变量拿凭证,不走keyring。这样本地用户正常用keyring,CI里用环境变量:import os import keyring def get_aws_creds(): if os.getenv('CI'): return { 'access_key': os.getenv('AWS_ACCESS_KEY_ID'), 'secret_key': os.getenv('AWS_SECRET_ACCESS_KEY') } else: return { 'access_key': keyring.get_password('my_package', 'aws_access_key'), 'secret_key': keyring.get_password('my_package', 'aws_secret_key') } - 用keyring的替代后端
安装keyrings.alt包,它提供了基于文件或环境变量的后端,在CI里指定使用这个后端:
这种方式是临时明文存到文件,但CI跑完就销毁,变量本身也是掩码的,风险可控。test_job: before_script: - pip install keyrings.alt script: - export PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring - export KEYRING_FILE=/tmp/ci_keyring - echo -e "[my_package]\naws_access_key=$AWS_ACCESS_KEY_ID\naws_secret_key=$AWS_SECRET_ACCESS_KEY" > $KEYRING_FILE - pytest tests/
四、额外建议
- 最小权限原则:给测试凭证分配最小必要权限,比如只能读写测试桶,碰不到生产资源。
- 限制测试触发分支:只在主分支或专门的测试分支跑集成测试,别每次提交都触发真实资源访问。
- 清理测试数据:集成测试后自动删掉创建的测试数据,避免测试环境资源堆积。
内容的提问来源于stack exchange,提问作者user2395059
相关产品推荐
相关产品推荐

