APIのテストでtavernを使ってCognitoの認証情報使ったテストがしたかったので、調べた内容です。
やりたいこと
- Cognitoから認証で取得したID Tokenを利用してAPIをテストしたい
- Cognitoの認証情報はSecretsManagerに保存する
- 環境毎に変数定義したい
ディレクトリ構成
簡単な構成として以下のようなものを作りました。
$ tree
.
├── config
│ ├── dev.yaml
│ └── prd.yaml
├── helper
│ └── auth.py
├── pyproject.toml
└── tests
├── __init__.py
└── myapi.tavern.yaml
config/
の下は環境毎の設定ファイルを置いています。テスト実行時に引数でファイルを指定します。
config/dev.yaml
variables:
aws:
secretName: tavern/test/dev # SecretsManagerのSecret名
region: ap-northeast-1 # AWS Region
service:
baseUrl: https://your.domain.com # APIのBaseUrl
helper/
の下にはヘルパー関数を置いて、SecretsManagerから取得した情報を元にID TokenをCognitoから取得しています。引数なども渡せます。
ちなみにSecretsManagerには以下のように認証情報置いています。
helper/auth.py
import ast
from dataclasses import dataclass
import boto3
from box import Box
@dataclass(frozen=True)
class CognitoCredentials:
client_id: str
username: str
password: str
def _get_secrets(secret_name:str,aws_region:str) -> CognitoCredentials:
"""
Get the secret from AWS Secrets Manager
"""
secretsmanager = boto3.client("secretsmanager", region_name=aws_region)
response = secretsmanager.get_secret_value(SecretId=secret_name)
secret = ast.literal_eval(response["SecretString"])
return CognitoCredentials(
client_id=secret["clientid"],
username=secret["username"],
password=secret["password"],
)
def get_authorization_header(secret_name:str,aws_region:str) -> Box:
"""
Get the Cognito ID token
"""
cred = _get_secrets(secret_name,aws_region)
cognito_idp_client = boto3.client("cognito-idp", region_name=aws_region)
res = cognito_idp_client.initiate_auth(
AuthFlow="USER_PASSWORD_AUTH",
AuthParameters={
"USERNAME": cred.username,
"PASSWORD": cred.password,
},
ClientId=cred.client_id,
)
id_token = res["AuthenticationResult"]["IdToken"]
return Box({"Authorization": id_token})
tests/
の下にテストファイルを置きます。
-
{}
の記法でconfig/
の下のyamlファイルの値を変数として埋め込めます -
function
で指定した関数にextra_kwargs
で引数を渡しています
test_name: Call API with Cognito ID token
stages:
- name: Cognitoから取得したIDトークンを使ってAPIを実行
request:
url: "{service.baseUrl:s}/some/api"
method: GET
headers:
$ext:
function: helper.auth:get_authorization_header
extra_kwargs:
secret_name: "{aws.secretName:s}"
aws_region: "{aws.region:s}"
response:
status_code: 200
pyproject.tomlではpytestの設定を追加しています。tavernで利用されます。
pyproject.toml
[project]
name = "tavern-cognito-token"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"boto3>=1.36.21",
"tavern[pytest]==2.11.0",
]
[tool.pytest.ini_options]
addopts = "-ra -s --log-cli-level=INFO"
testpaths = ["tests"]
実行してみる
以下のように --tavern-global-cfg
でconfig配下の設定ファイルを指定して実行することで、環境切り替えつつテストが可能です。
uv run py.test --tavern-global-cfg=./config/dev.yaml