🤩

PostmanでGithub Actionsのintegration-testをやってみた

2022/05/12に公開

https://zenn.dev/marumarumeruru/articles/074195f0273ee0
の続き

Newman

Newmanは、PostmanのCLIツールです。
https://learning.postman.com/docs/running-collections/using-newman-cli/command-line-integration-with-newman/
PostmanのGUIでテストを作成し、そのテストをexportし、Newmanで実行するという流れです。

トークンを生成して渡すところで苦労したので、やり方をメモしておきます

環境変数の設定

Postmanでテストを実装する際に、環境変数を利用してテストを作成するために、まず環境変数を設定します

API呼び出し

環境変数に設定した変数は{{BASEURL}}のように囲みます

Test作成

Testsのタグで、右のスペニットを選択し、少し編集して、テストが通るようにします
Sendボタンでテスト実行します

Test ResultsでPASSするようになったら、Exportします

生成されたjsonをtests/integration-test/にそのままコミットします

hello.postman_collection.json
{
	"info": {
		"_postman_id": "xxxxxxxx",
		"name": "hello",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "New Request",
			"event": [
				{
					"listen": "prerequest",
					"script": {
						"exec": [
							""
						],
						"type": "text/javascript"
					}
				},
				{
					"listen": "test",
					"script": {
						"exec": [
							"",
							"pm.test(\"Status code is 200\", function () {",
							"    pm.response.to.have.status(200);",
							"});",
							"",
							"pm.test(\"body check\", function () {",
							"    var jsonData = pm.response.json();",
							"    pm.expect(jsonData).to.eql({",
							"        \"message\": \"hello world\"",
							"    })",
							"});",
							""
						],
						"type": "text/javascript"
					}
				}
			],
			"request": {
				"auth": {
					"type": "noauth"
				},
				"method": "GET",
				"header": [
					{
						"key": "Content-Type",
						"value": "application/json; charset=UTF-8",
						"type": "text"
					},
					{
						"key": "Authorization",
						"value": "{{ID_TOKEN}}",
						"type": "text"
					}
				],
				"url": {
					"raw": "{{BASEURL}}hello",
					"host": [
						"{{BASEURL}}hello"
					]
				}
			},
			"response": []
		}
	]
}

pipeline.yaml編集

https://zenn.dev/marumarumeruru/articles/8cc700d0300ca7
で未実装だった、integration-testの部分を下記のようにします

pipeline.yaml
  integration-test:
    if: github.ref == 'refs/heads/master'
    needs: [deploy-testing]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install Dependencies
        run: npm install -g newman
      - name: Assume the testing pipeline user role
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.TESTING_REGION }}
          role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }}
          role-session-name: integration-test
          role-duration-seconds: 3600
          role-skip-session-tagging: true
      - name: Set env
        run: |
          BASEURL=$(aws cloudformation describe-stacks --stack-name ${TESTING_STACK_NAME} | jq -r '.Stacks[] | .Outputs[] | select(.OutputKey == "HttpApiUrl") | .OutputValue') 
          echo "BASEURL=${BASEURL}" >> $GITHUB_ENV
          USERPOOL=$(aws cloudformation describe-stacks --stack-name ${TESTING_STACK_NAME} | jq -r '.Stacks[] | .Outputs[] | select(.OutputKey == "UserPoolId") | .OutputValue') 
          echo "USERPOOL=${USERPOOL}" >> $GITHUB_ENV
          USERPOOL_CLIENT=$(aws cloudformation describe-stacks --stack-name ${TESTING_STACK_NAME} | jq -r '.Stacks[] | .Outputs[] | select(.OutputKey == "UserPoolClientId") | .OutputValue') 
          echo "USERPOOL_CLIENT=${USERPOOL_CLIENT}" >> $GITHUB_ENV
      - name: Create testuser
        run: |
          aws cognito-idp sign-up --client-id ${USERPOOL_CLIENT} --username testuser --password password
          # user confirme
          aws cognito-idp admin-confirm-sign-up --user-pool-id ${USERPOOL}  --username testuser
      - name: Create id_token
        run: |
          ID_TOKEN=$(aws cognito-idp admin-initiate-auth --user-pool-id ${USERPOOL} --client-id ${USERPOOL_CLIENT} --auth-flow ADMIN_NO_SRP_AUTH --auth-parameters USERNAME=testuser,PASSWORD=password | jq -r '.AuthenticationResult | .IdToken')
          echo "ID_TOKEN=${ID_TOKEN}" >> $GITHUB_ENV
      - name: Hello Api test
        run: |
          newman run tests/integration-test/hello.postman_collection.json --env-var "BASEURL=${BASEURL}" --env-var "ID_TOKEN=${ID_TOKEN}"
      - name: Delete testuser
        run: |
          aws cognito-idp admin-delete-user --user-pool-id ${USERPOOL} --username testuser

まず、newmanを実行するために、npmでnewmanを入れています。

npm install -g newman

その後、pipelineユーザーにAssume Roleして、
CloudFormationのOutputの情報を取得し、環境変数に保存します
環境変数はそのままではstepをまたげないので、$GITHUB_ENVに書き出すことで、引き継ぎできるようになります
https://docs.github.com/ja/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable

testuserを作成し、IdTokenを生成し、環境変数経由で渡すようにしています。
最後に次回実行のためにtestuserを削除しています

権限追加

そのままだと下記のエラーが出るので、PipelineExecutionRolePermissionsのポリシーに権限追加します

AdminConfirmSignUp権限不足
An error occurred (AccessDeniedException) when calling the AdminConfirmSignUp operation: User: arn:aws:sts::***:assumed-role/aws-sam-cli-managed-develop-PipelineExecutionRole-124710FBH2EXG/integration-test is not authorized to perform: cognito-idp:AdminConfirmSignUp on resource: arn:aws:cognito-idp:ap-northeast-1:***:userpool/ap-northeast-1_nDXupMdct because no identity-based policy allows the cognito-idp:AdminConfirmSignUp action
AdminInitiateAuth権限不足
An error occurred (AccessDeniedException) when calling the AdminInitiateAuth operation: User: arn:aws:sts::***:assumed-role/aws-sam-cli-managed-develop-PipelineExecutionRole-124710FBH2EXG/integration-test is not authorized to perform: cognito-idp:AdminInitiateAuth on resource: arn:aws:cognito-idp:ap-northeast-1:***:userpool/ap-northeast-1_nDXupMdct because no identity-based policy allows the cognito-idp:AdminInitiateAuth action
AdminDeleteUser権限不足
An error occurred (AccessDeniedException) when calling the AdminDeleteUser operation: User: arn:aws:sts::***:assumed-role/aws-sam-cli-managed-develop-PipelineExecutionRole-124710FBH2EXG/integration-test is not authorized to perform: cognito-idp:AdminDeleteUser on resource: arn:aws:cognito-idp:ap-northeast-1:***:userpool/ap-northeast-1_nDXupMdct because no identity-based policy allows the cognito-idp:AdminDeleteUser action
PipelineExecutionRolePermissionsの修正
cognito-idp:AdminConfirmSignUp
cognito-idp:AdminInitiateAuth
cognito-idp:AdminDeleteUser

実行

masterにpushするか、featureブランチをmasterにマージした際にAPIのテストが実行できるようになりました!

Discussion