見出し画像

負荷テストツールLocust学習2:Locustを書いてみる

はじめに

こんにちは、SHIFT DevOps推進部2グループの李です。
前回はLocustの概要とインストールの方法について紹介しました。
今回は実際に書いてみようと思います。
LocustはどんなIDEツールでも開発できますが、本記事はVisual Studio Codeを使用させていただきます。

下記が今回使用するソフトウェアです。

内容を5つのシリーズに分けて紹介したいと思います。

連載目次:

  1. (前回)負荷テストツールLocust学習1:Locustとは

  2. (今回)負荷テストツールLocust学習2:Locustを書いてみる

  3. 負荷テストツールLocust学習3:Locustのパラメータ

  4. 負荷テストツールLocust学習4:LocustのGUIとCLI

  5. 負荷テストツールLocust学習5:Locustの分散モード

テスト対象

このシリーズのテスト対象は無料に使えるオープンソースの天気APIです。
APIで世界中の任意の場所の天気情報を取得できます。
ログインと認証も不要です。
詳しくは下記のURLのドキュメントを参考にしてください。

公式サイト:

初めてのLocust

Locustのコードを書く前に、まずは任意の場所で「locust_practice」フォルダを作ってください。
そしてVisual Studio Codeで該当フォルダを開いて、右クリックで「locust_test.py」を作成して、下記のコードを入力してください。

from locust import between, task, HttpUser
class TestCase(HttpUser):
    wait_time = between(0, 3)

    def on_start(self):
        pass

    @task
    def temperature(self):
        self.client.get("/forecast?latitude=35.69&longitude=139.70&hourly=temperature_2m", headers={})

    def on_stop(self):
        pass

上記コードの解説:
TestCaseはHttpUserを継承したクラスです。
HttpUserはHTTPリクエストを使うために必要なライブラリなので、HTTPリクエストを使用する場合はHttpUserを継承してください。

3行目のwait_timeでHttpUserを継承したクラスにはwait_timeの指定が必要です。wait_timeとはユーザの操作を模擬して、操作と操作の間に0秒から3秒の時間を待つことです。

今回の例は1つのリクエストのみなので待ち時間はないですが、複数リクエストの場合はリクエスト間に待ち時間が発生します。

続けて、on_startとon_stopの2つ関数はLocustに必要な関数です。
これは開始時と終了時に実行するイベントです。
最後のtemperatureの関数の上のデコレータの「@task」は、テスト項目として宣言して、中身はgetメソッドを使って、空のヘッダーでURL「https://api.open-meteo.com/v1/forecast?latitude=35.69&longitude=139.70&hourly=temperature_2m 」にアクセスして新宿の気温を取得します。

Locustの実行方法

コードの作成が完了しましたら、ターミナルに「locust -f locust_test.py」コマンドを入力して、実行してみましょう。

Locustのサーバーが開始されましたら、ブラウザのURLに「http://localhost:8089/ 」を入力して、LocustのGUIテスト画面を開きます。

テストGUIを開いたら、上記の画面が表示されます。
ここで3つの設定値を下表のように入力し、「Start swarming」をクリックします。

実行するとAPI「/forecast?latitude=35.69&longitude=139.70&hourly=temperature_2m」のテストレポートがリアルタイムで確認できます。
統計レポート以外にも統計図、エラーレポートも確認できます。

※実行中のスクリプトを中止する場合はターミナルで「Ctrl+C」を入力します。

ランダム処理と順次処理

スクリプトに複数のリクエストが存在する場合、リクエストの実行順はとても重要です。Locustでランダム処理と順序処理の2つの処理を実行してみます。

ここからはランダム処理と順次処理の書き方を紹介します。
先にランダム処理の書き方を紹介させていただきます。

from locust import TaskSet, between, task, HttpUser
class TestCase(TaskSet):
    def on_start(self):
        pass

    @task(1)
    def temperature(self):
        self.client.get("/forecast?latitude=35.69&longitude=139.70&hourly=temperature_2m", headers={})

    @task(5)
    def windspeed(self):
        self.client.get("/forecast?latitude=35.69&longitude=139.70&hourly=windspeed_10m", headers={})

    def on_stop(self):
        pass

class Run(HttpUser):
    tasks = {TestCase:1}
    wait_time = between(0, 3)

上記コードの解説:
まずは前段のコードと違ってクラスを2つに分けました。
これは処理の順番を指定するためにクラスを継承することが必要なためです。

続けて、TestCaseの継承クラスをTaskSetに変更します。
TaskSetはテスト実行時にクラス内の関数から任意の関数を選んで実行するクラスです。

TestCaseクラスの中身はリクエストに関する内容のみで書いて、実行に関するコードはRunクラスに移動しました。
TestCaseクラスにはwindspeed関数を追加しました。
デコレータの「@task」後ろに付いてある数字はウェイトです。
この例でwindspeedが選ばれる確率はtemperatureの5倍なので、windspeedリクエスト数はtemparatureリクエスト数の5倍となります。

RunクラスはHTTPリクエストを発信するためにHttpUserを継承します。
中身のtasksに「TestCase」を指定して、確率を1にします。
HttpUserのtasksは複数のクラスを指定できて、コロンの後ろに付いてある数字はウェイトです。
Locustは関数単位だけではなく、クラス単位でもウェイトの指定ができます。

次は順次処理の書き方を紹介します。

from locust import SequentialTaskSet, between, task, HttpUser
class TestCase(SequentialTaskSet):
    def on_start(self):
        pass

    @task(1)
    def temperature(self):
        self.client.get("/forecast?latitude=35.69&longitude=139.70&hourly=temperature_2m", headers={})

    @task(5)
    def windspeed(self):
        self.client.get("/forecast?latitude=35.69&longitude=139.70&hourly=windspeed_10m", headers={})

    def on_stop(self):
        pass

class Run(HttpUser):
    tasks = {TestCase:1}
    wait_time = between(0, 3)

上記コードの解説:
ランダム処理の内容とほぼ同じですが、継承クラスはTaskSetからSequentialTaskSetに変更しました。
SequentialTaskSetはクラス内の関数と同じ順序で実行するクラスです。
デコレータの「@task」後ろに付いてある数字の意味も変わって、1回temperatureを実行したら、5回windspeedを実行します。

次回のお知らせ

今回はLocustの基本的な書き方について紹介しました。いかがですか?
Locustにはまだたくさん機能がありますので、興味がある方は是非Locustのドキュメントを確認してみてください。

次回はLocustのパラメータについて紹介したいと思います。

最後までお読みいただきありがとうございました。また次回の記事でお会いしましょう!

参考資料:

  1. 無料天気API:https://open-meteo.com/

  2. Locustのドキュメント:https://docs.locust.io/en/stable/

《併せて読みたいシリーズ記事》


執筆者プロフィール:李 嘉興
社会人になって以来、数年間システムエンジニアとして多数のプロジェクトの開発(要件定義~リリース)を経験したのち、2021年7月にSHIFTに入社。
システムエンジニアの仕事と全く違う分野の自動化とCICDを経験しつつ、未来のキャリアのため日々奮闘中。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/