ボット

ボットはアプリへの参加者をシミュレートします。ボットが、各ページをクリックしたり、フォームに入力したりすることで、あなたのアプリが正常に動作することを確認できます。

この機能を使うことで、oTreeがアプリを自動的にテストしてくれます。また、oTree Studioでは、ボットのコードを設計することもできますので、ボットの作成から実行まで、ほとんど手間がかかりません。

ボットの実行

  • ボットを追加します。 (下記参照)
  • セッションコンフィグで、 use_browser_bots=True を設定します。
  • サーバを起動し、セッションを作成します。スタートリンクが開かれると、ブラウザ上でボットが自動的にページを実行します。

テストの記述

oTree Studioで、アプリの「テスト」セクションに移動します。ボタンをクリックすると、ボットのコードが自動生成されます。生成されたコードを改良したい場合(例えば、 expect() ステートメントの追加など)は、以下のセクションをお読みください。

テキストエディタをお使いの場合は、tests.py にアクセスしてください。 tests.py の例は こちら

ページの送信

ページ毎に yield を記述する必要があります。例えば、以下のようになります:

yield pages.Start
yield pages.Survey, dict(name="Bob", age=20)

ここでは、まず、フォームを含まない Start ページを送信しています。次のページには2つのフォームフィールドがあるので、辞書型を送信しています。

このテストのシステムでは、ボットがページに対して無効な入力をした場合や、間違った順序でページを送信した場合には、エラーが発生します。

if 文を使い、任意のプレイヤーやラウンドを指定して実行できます。例えば、以下のようになります:

if self.round_number == 1:
    yield pages.Introduction
if self.player.id_in_group == 1:
    yield pages.Offer, dict(offer=30)
else:
    yield pages.Accept, dict(offer_accepted=True)

if 文では self.player, self.group, self.round_number などを使用することができます。

ボットを記述する際には、WaitPage は無視します。

ラウンド

ボットのコードは、一度に1ラウンドだけ実行するように記述します。oTreeはそのコードに書かれた動作を NUM_ROUNDS 回自動的に実行します。

expect()

expect() 関数を使用することで、コードが期待通りに動作していることを確認できます。

例えば、以下のように使用できます:

expect(self.player.num_apples, 100)
yield pages.Eat, dict(apples_eaten=1)
expect(self.player.num_apples, 99)
yield pages.SomeOtherPage

self.player.num_apples が99でない場合は、エラーで警告されます。

expect(self.player.budget, '<', 100) のように、3つの引数を指定できます。この例では、 self.player.budget が100より小さいことを検証しています。次の演算子を使うことができます: '<', '<=', '==', '>=', '>', '!=', 'in', 'not in'

フォーム検証のテスト

フォームの検証 を使用している場合には、 SubmissionMustFail() を使用して、アプリがユーザーからの無効な入力を正しく拒否しているかどうかをテストする必要があります。

例えば、このようなページがあるとします:

class MyPage(Page):

    form_model = 'player'
    form_fields = ['int1', 'int2']

    @staticmethod
    def error_message(player, values):
        if values["int1"] + values["int2"] != 100:
            return 'The numbers must add up to 100'

以下のようにして、正常に動作しているかどうかを確認することができます:

yield SubmissionMustFail(pages.MyPage, dict(int1=99, int2=0))
yield pages.MyPage, dict(int1=99, int2=1)

このボットは MyPage を2回送信します。1回目の送信が 成功 してしまった場合、エラーが発生するようになっています。

HTML のチェック

self.html には、これから送信しようとしているページの HTML が格納されています。これは expect() と一緒に使用することができます:

if self.player.id_in_group == 1:
    expect(self.player.is_winner, True)
    print(self.html)
    expect('you won the game', 'in', self.html)
else:
    expect(self.player.is_winner, False)
    expect('you did not win', 'in', self.html)
yield pages.Results
# etc...

self.html は、 yield 文の実行後に次のページの HTML で更新されます。改行や余分なスペースは無視されます。

HTML の自動チェック

ボットが、ページの HTML に実際にはないフォームを送信しようとしたり、ページの HTML に送信ボタンがないのに送信しようとする場合、エラーが発生します。

ただし、JavaScriptで動的に追加されたフィールドやボタンは、ボットシステムでは確認できません。このような場合には、Submissioncheck_html=False を指定して、HTML チェックを無効にしてください。例えば、以下を:

yield pages.MyPage, dict(foo=99)

次のように変更します:

yield Submission(pages.MyPage, dict(foo=99), check_html=False)

( check_html=False を指定せずに Submission を使用した場合、2つのコードサンプルは同等のものになります。)

ページタイムアウトのシミュレート

Submission では timeout_happened=True を指定できます:

yield Submission(pages.MyPage, dict(foo=99), timeout_happened=True)

高度な機能

ボット: 高度な機能 を参照してください。