このドキュメントは、あるプロジェクトにおける性能テストの自動化への取り組みを、事例としてまとめたものになります。
本ドキュメントが、性能テスト自動化に取り組む際のアプローチや採用技術についての参考情報となることを目的としています。
このドキュメントで取り上げるプロジェクト(以降、プロジェクトAと記載)の概要を、記載します。
プロジェクトAの概要
プロジェクトAにおける、システム全体の構成イメージを、以下に記載します。
システムの構成要素
プロジェクトAを構成する、システム的な要素を以下に記載します。
プロジェクトAの特徴
このプロジェクトには、以下のような特徴があります。
最初のリリースでプロジェクト完了ではなく、その後に利用できる手続きを増やしていく、継続的に開発が行われていくプロジェクトとなります。
本ドキュメントには、最初のリリースが終わり、2つ目の機能の開発の途中までに実施された取り組みを反映しています。
元々が実店舗で行っていた手続きをスマホアプリ化したものなので、大量のアクセスが想定されるようなシステムではありません。
性能目標としては、以下を目標値としています。
プロジェクトAでは、エンドユーザーに対して利用可能な手続きを順次増やしていきます。
今後追加する手続きが、どのような実現・実装方式となるかは未定ですが、既存の手続きと同じ環境に追加されることは十分に想定されます。この時、既存の手続きにも性能に問題がない状態であることを都度確認する必要があります。 そして、その確認範囲には、過去にリリースした手続き分を含む可能性があります。この繰り返しを効率よく実施するため、性能テストの自動化に取り組みました。
プロジェクトAには、以下の3つの環境が存在します。
名称 | 用 |
---|---|
本番環境 | 開発したシステムが本番稼働する環境 |
準本番環境 | 開発・保守用途の環境。冗長構成されていない点を除いて、本番環境と同等の構成 |
開発環境 | CI/CD、チケット管理、ソースコードリポジトリなどを含む、開発環境 |
性能テストは、これら3つの環境のうち、準本番環境を使用して実施します。 実施タイミングは、リリースの大体1週間前から開始するようにしています。並走することは滅多にありませんが、性能テスト実施時は他のテストを実施できません。並走する可能性がある場合は、事前にスケジュールの調整を行います。
PaaSとしてPCFを採用しているので、同じくPivotal社が主に開発しているConcourseというOSSのCI/CDツールを採用しています。相性の良さもありますが、ジョブやパイプラインなどをYAMLで記述するため、Gitで構成管理できます。これにより、ジョブやパイプラインのレビューを開発フローに組み込める、属人化の防止、スケールのしやすさなどのメリットがあります。Concourseはいずれの環境にも設置してあり、アプリケーションのビルド・テスト・デプロイを実行するためのパイプラインが設定してあります。パイプラインとはConcourse上で実行するジョブの定義と、ジョブの実行に必要な設定を定義したもので、設定ファイルとして作成します。環境によってConcourseに設定してあるパイプラインの内容は異なります。準本番環境のConcourseは、準本番環境へのデプロイと、Concourse上のジョブとして性能テストを実施するように構成しています。
このドキュメント執筆時には2つの手続きが対象となっているため、それぞれの手続きに対してテストシナリオを作成して、実行しています。性能テストツールにはJMeterを採用しているので、JMeterのシナリオとして作成しています。
JMeterは性能テスト用のシナリオが作成できること、過去のプロジェクトでの採用経験があることから採用しました。テストシナリオには、端末(スマホ)にインストールしたアプリケーションから、サーバーに対する画面表示や画像送信などを行う操作を定義します。この操作を、以下の条件で実行します。
秒間同時リクエスト数 | テスト実行時間 | テスト開始時点のデータ量 |
---|---|---|
2 req / sec | 60時間 | 100,000件 |
長時間のテストとなっているのは、システムが大量のユーザーから頻繁にアクセスされるような性質でないことと(性能目標参照)、確認内容としてロングランテストの意味合いも兼ねることにしているためです。このため、テストの実行時間(60時間)が長いものになっています。
性能テストシナリオを、極力人手を介さずに実行できるように構成します。ソースコード等はGitLab(Git)を使用して管理しており、この中に以下を含むリポジトリを作成しています。
性能テストでは、上述した通りConcourseを使用しています。 Concourseの性能テスト用のジョブは、以下の用に構成されています。
最後に、アップロードされた結果を、開発者が目視で確認、評価を実施します。
このフローを、以下に図示します。
また、Concourse上でのジョブを表示したものを、以下に記載します。
次は、データのクリーニングおよびセットアップを実施するための、SQLを実行するジョブの様子です。
次は、データセットアップ後に、Apache JMeterで性能テストを実行するジョブの様子です。
これらのジョブは、以下のようなYAMLファイルで作成されています。
execute-sql.yml(データのセットアップを行うConcourseのPipeline定義)
※一部、内容を加工、削除しています
※データベースの接続情報などは、{{}}
でパラメーター化されていますが、これは外部の設定から取り込みます。
groups:
- name: stag
jobs:
- run-sql-stag
params:
dbInfoStag: &DB_INFO_STAG
DB_USERNAME: app_stg_test
DB_URL: {{availability-maintenance-datasource-url}}
DB_PASSWORD: ((spring-datasource-password))
DB_SCHEMA: {{db-schema-stag}}
SQL_FILE_PATH: execute-sql/run.sql
CA_CERT_PATH: ops-resource/concourse/sql/ca-bundle.pem
resources:
- name: ops-resource
type: git
source:
uri: {{gitlab-uri-concourse}}
branch: {{gitlab-branch-master}}
private_key: ((gitlab-private_key.private_key))
username: {{gitlab-username}}
password: ((gitlab-password))
- name: execute-sql
type: git
source:
uri: {{gitlab-uri-execute-sql-for-staging}}
branch: {{gitlab-branch-master}}
private_key: ((gitlab-private_key.private_key))
username: {{gitlab-username}}
password: ((gitlab-password))
jobs:
- name: run-sql-stag
plan:
- aggregate:
- get: ops-resource
- get: execute-sql
- task: runsql
config:
platform: linux
image_resource:
type: docker-image
source:
repository: mysql
inputs:
- name: ops-resource
- name: execute-sql
run:
path: ops-resource/concourse/script/run-sql.sh
params:
<<: *DB_INFO_STAG
run:
path: ops-resource/concourse/script/run-sql.sh
{{}}
でパラメーター化されていますが、これは外部の設定から取り込みます。resources:
- name: repo-scenario
type: git
source:
uri: {{gitlab-uri-jmeter-scenario}}
branch: {{gitlab-branch-master}}
private_key: ((gitlab-private_key.private_key))
username: {{gitlab-username}}
password: ((gitlab-password))
- name: repo-result
type: git
source:
uri: {{gitlab-uri-jmeter-result}}
branch: {{gitlab-branch-master}}
private_key: ((gitlab-private_key.private_key))
username: {{gitlab-username}}
password: ((gitlab-password))
jobs:
- name: jmeter
plan:
- get: repo
resource: repo-scenario
- get: result
resource: repo-result
- task: run-jmeter
config:
platform: linux
image_resource:
type: docker-image
source:
repository: justb4/jmeter
inputs:
- name: repo
outputs:
- name: out
run:
path: bash
args:
- -c
- |
set -e
cd repo
echo "==== jmeter start ===="
export EXPORT_DIR="../out"
sh run.sh
echo "==== jmeter end ===="
cd ../out
ls
- task: git-push
config:
platform: linux
image_resource:
type: docker-image
source:
repository: getourneau/alpine-bash-git
inputs:
- name: result #clone用のGit
- name: out #前タスクの出力を入力にする.
outputs:
- name: updated-result
run:
path: bash
args:
- -c
- |
set -e
git clone result updated-result
cd updated-result
export TZ=JST-9
date_dir=`date +"%Y%m%d_%H%M%S"`
mkdir report/$date_dir
mv -f ../out/* ./report/$date_dir
git config --global user.email "xxxxx@email.com"
git config --global user.name "xxxxx"
git add -A
git commit -m "` date +"%Y/%m/%d %H:%M:%S"` Update result"
- put: repo-result
params:
repository: updated-result
- task: run-jmeter
テスト結果をGitLabにアップロードするタスクがあります。
- task: git-push
run:
path: bash
args:
- -c
- |
set -e
cd repo
echo "==== jmeter start ===="
export EXPORT_DIR="../out"
sh run.sh
echo "==== jmeter end ===="
cd ../out
ls
run:
path: bash
args:
- -c
- |
set -e
git clone result updated-result
cd updated-result
export TZ=JST-9
date_dir=`date +"%Y%m%d_%H%M%S"`
mkdir report/$date_dir
mv -f ../out/* ./report/$date_dir
git config --global user.email "xxxxx@email.com"
git config --global user.name "xxxxx"
git add -A
git commit -m "` date +"%Y/%m/%d %H:%M:%S"` Update result"
ここで、性能テストの結果としてアップロードされるレポートには、HTMLとCSVの2種類のファイル形式があります。
このように、性能テストの実施と結果の格納までは自動化しており、結果の評価自体は目視で実施するという形にしています。
また、ここで収集される性能テストの結果にはインフラ面でのリソースの使用状況などは含まれていません。この点については、後に取得して、テスト結果と突き合わせて確認する必要があります。
インフラのリソースは、CPU使用率、メモリ使用率、ディスク容量などを確認しています。
性能テストは何度か実行することになりますが頻度は低く、実行結果の確認自体も負荷が低いため、費用対効果の観点から手動部分を残しています。
このドキュメントでは、プロジェクトAにおける性能テストの自動化の取り組みについて記載しました。自動化の範囲は、以下の一連の流れを対象としたものです。
範囲が限定的ではありますが、費用対効果が高い箇所については繰り返し実行できるように整備できました。性能テストを実施する上でこのようなセットアップは多くの時間を要しますし、スキルも必要です。 性能テストの実施自体も手動では時間がかかりますし、ミスがつきものです。
自動化によって、準備や実施の時間を大幅に短縮し、誰でもミスなく実施できるようになっています。今後は、プロジェクトの追加開発により必要な手続きが追加されるに伴い、性能テストのシナリオやデータのセットアップスクリプトを拡充していく方針です。仕組みは今回整えたので、機能追加時には低コストで既存部分含めた性能テストを実施できるようになっています。結果、より多くの時間を本質的なサービス改善や機能追加に使えるようになりました。
本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。
Copyright 2021 TIS Inc.keyboard_arrow_up