ApidogでEnd-to-endテストを実装してみた
ApidogでEnd-to-endテストを実装してみた
はじめに
APIの品質担保は開発者の重要な課題の一つです。サービスを運用していると、予期せぬところでバグが発生することがあります。特にサービスのコア機能となるAPIについては、高い品質を維持する必要があります。今回は、APIのドキュメント管理とテストを同時に行えるApidogを使って、コアとなるAPIのEnd-to-endテストを実装した経験を共有したいと思います。
Apidogとは
Apidogは、APIのドキュメント管理とテストを統合的に行えるツールです。主な特徴として:
- APIドキュメントの作成・管理機能
- APIテストの作成・実行機能
- 管理しているapiを簡単にインポートできる
- 多様な機能の実装が簡単
- 管理しているapiを簡単にインポートできる
- 多様なCI/CDプラットフォームとの連携
- コマンドライン
- Github Actions
- Jenkins
- Azure Pipelines
- など
導入の背景
私たちのサービスでは、予約システムを核としたビジネスを展開しています。システムの規模が大きくなるにつれて、以下のような課題が出てきました:
- 予期せぬバグの発生による影響
- コアとなる予約機能の品質担保の必要性
- 継続的なテスト実行の自動化ニーズ
これらの課題に対応するため、Apidogを導入してEnd-to-endテストを実装することにしました。
テスト実装内容
今回実装したテストの主な内容は以下の通りです:
1. 予約システムの基本機能テスト
予約システムの核となる以下の機能について、End-to-endでのテストを実装しました:(テスト環境のため、delayを長めにとってます)
- 新規予約の作成機能
- 予約のリスケジュール機能
- 予約のキャンセル機能
2. オンラインミーティングURL生成テスト
ロケーション選択時の会議URL生成について、以下のプラットフォーム別にテストを実装:
- Google Meet
- Zoom
- Microsoft Teams
各プラットフォームにおいて、正しいフォーマットのURLが生成されることを確認します。
Apidog では後処理で簡単に正規表現でURLのフォーマットをチェックする機能があります。
例えばZoomの場合以下の正規表現を使用します。
/^https:\/\/[\w-]+\.zoom\.us\/j\/\d+\?pwd=[\w.]+(&[\w]+=[\w.%]+)*$/
CI/CD連携
Apidogの強みの一つは、様々なCI/CDプラットフォームとの連携の容易さです。今回は、GitHub Actionsを利用して自動テストを実装しました。
name: Apidog API Tests
on:
workflow_dispatch:
inputs:
test-suite:
description: 'Select test suite to run'
required: true
type: choice
options:
- all
- [test1]
- [test2]
- [test3]
default: 'all'
environment:
description: 'Test environment'
required: true
type: choice
options:
- [your environment]
default: [default environment]
jobs:
api-tests:
runs-on: ubuntu-latest
env:
APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
steps:
- uses: jwalton/gh-find-current-pr@v1
id: findPr
with:
state: open
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install Apidog CLI
run: npm install -g apidog-cli
# Test 1: [your test 1]
- name: Run [your test 1]
id: [your id 1]
if: github.event.inputs.test-suite == 'all' || github.event.inputs.test-suite == [your test 1]
continue-on-error: true
run: |
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
[apidog information]
# Test 2: [your test 2]
- name: Run [your test 2]
id: [your id 2]
if: github.event.inputs.test-suite == 'all' || github.event.inputs.test-suite == [your test 2]
continue-on-error: true
run: |
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
[apidog information]
# Test 3: [your test 3]
- name: Run [your test 3]
id: [your id 3]
if: github.event.inputs.test-suite == 'all' || github.event.inputs.test-suite == [your test 3]
continue-on-error: true
run: |
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
[apidog information]
# Store test results as artifacts
- name: Upload Test Reports
if: always()
uses: actions/upload-artifact@v3
with:
name: apidog-test-reports-${{ github.run_id }}
path: apidog-report/
retention-days: 30
# Determine overall test status
- name: Check Test Results
id: check-results
if: always()
run: |
# Check test suite results
if [[ "${{ github.event.inputs.test-suite }}" == "all" ]]; then
if [[ "${{ steps.[your id 1].outcome }}" == "success" && \
"${{ steps.[your id 2].outcome }}" == "success" && \
"${{ steps.[your id 3].outcome }}" == "success" ]]; then
echo "status=success" >> $GITHUB_OUTPUT
else
echo "status=failure" >> $GITHUB_OUTPUT
# Exit with error code to fail the workflow
exit 1
fi
elif [[ "${{ github.event.inputs.test-suite }}" == [your test 1] ]]; then
echo "status=${{ steps.[your id 1].outcome }}" >> $GITHUB_OUTPUT
if [[ "${{ steps.[your id 1].outcome }}" != "success" ]]; then
exit 1
fi
elif [[ "${{ github.event.inputs.test-suite }}" == [your test 2] ]]; then
echo "status=${{ steps.[your id 2].outcome }}" >> $GITHUB_OUTPUT
if [[ "${{ steps.[your id 2].outcome }}" != "success" ]]; then
exit 1
fi
elif [[ "${{ github.event.inputs.test-suite }}" == [your test 3] ]]; then
echo "status=${{ steps.[your id 3].outcome }}" >> $GITHUB_OUTPUT
if [[ "${{ steps.[your id 3].outcome }}" != "success" ]]; then
exit 1
fi
fi
# Comment test results on PR
- uses: actions/github-script@v7
if: always()
id: set-result
with:
script: |
if (process.env.GITHUB_ISSUE_NUMBER) {
github.rest.issues.createComment({
issue_number: process.env.GITHUB_ISSUE_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Apidog API tests results:
status: ${process.env.TEST_STATUS === 'success' ? ':green_circle:' : ':red_circle:'}
suite: ${process.env.TEST_SUITE}
environment: ${process.env.ENVIRONMENT}
jobUrl: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`
})
}
env:
GITHUB_ISSUE_NUMBER: ${{ steps.findPr.outputs.pr }}
TEST_STATUS: ${{ steps.check-results.outputs.status }}
TEST_SUITE: ${{ github.event.inputs.test-suite }}
ENVIRONMENT: ${{ github.event.inputs.environment }}
GitHub Actions で該当ブランチ(テスト環境へデプロイ後)を選択して実行すると、結果レポート及び結果コメントが該当PRへ生成されます。
まとめ
Apidogを使ったEnd-to-endテストの導入により、以下の成果が得られました:
- コア機能の品質担保
- テスト実行の自動化
- APIドキュメントとテストの一元管理
CI/CD連携により、継続的な品質モニタリングが可能になりました。
今後の展望
今後は以下の項目について検討を進めていく予定です:
- テストカバレッジの拡大
- テスト環境デプロイと連携し、完全自動化
APIのテスト自動化は、サービスの品質を保つ上で重要な要素です。Apidogはその実現のための強力なツールとして、検討の価値があると考えています。
今回使用したAPIについて
今回使用したAPIはApidogで公開しております、ぜひご利用頂けたら幸いです。
詳しくは以下のリンクをご確認ください。
最後に
Jicooではエンジニアを全方位的に募集しておりますので、ご興味ありましたらカジュアル面談も可能ですので応募いただけると嬉しいです!
ここまで読んでいただいて、ありがとうございました。
Discussion