oTree is a powerful framework for creating and deploying interactive experiments and games. While the basic bot functionality is useful for simple testing, oTree also offers advanced features to streamline and enhance your testing process. This article dives into these advanced bot capabilities, focusing on command-line execution, data export, test case management, and live page testing. Note that many of these features are not supported in oTree Studio.
One of the most significant advancements is the ability to run bots directly from the command line. This approach offers several advantages over running bots within a browser:
To run command-line bots, use the following command:
otree test mysession
This command runs bots for the session configuration named "mysession." You can specify the number of participants using:
otree test mysession 6
To test across all your session configurations, simply run:
otree test
After running your bot tests, you'll likely want to analyze the results. oTree provides a convenient way to export the data to a CSV file using the --export
option:
otree test mysession --export
To specify a particular folder for the exported data, use:
otree test mysession --export=myfolder
oTree offers otree browser_bots
which allows you to launch bots from the command line but still have them interact with the experiment in a browser environment. This is useful for testing features that rely on the browser's rendering and JavaScript execution.
Before using this feature, ensure that:
BROWSER_COMMAND
is appropriately configured in settings.py
.OTREE_REST_KEY
environment variable is set as described in the oTree REST API documentation.To run browser bots from the command line, use the following:
otree browser_bots mysession
This will launch Chrome tabs, run the bots, and automatically close the tabs upon completion, providing a report in the terminal.
For remote servers like Heroku, specify the server URL:
otree browser_bots mysession --server-url=https://YOUR-SITE.herokuapp.com
You can also specify the number of participants:
otree browser_bots mysession 6
And to test all session configurations:
otree browser_bots
The cases
attribute within your PlayerBot
class allows you to define different testing scenarios. This is particularly useful for testing various strategies or conditions within your experiment.
For example, in a public goods game, you might want to test three scenarios:
You can define these cases as follows:
class PlayerBot(Bot):
cases = ['basic', 'min', 'max']
def play_round(self):
yield (pages.Introduction)
if self.case == 'basic':
assert self.player.payoff == None
if self.case == 'basic':
if self.player.id_in_group == 1:
for invalid_contribution in [-1, 101]:
yield SubmissionMustFail(pages.Contribute, {'contribution': invalid_contribution})
contribution = {
'min': 0,
'max': 100,
'basic': 50,
}[self.case]
yield (pages.Contribute, {"contribution": contribution})
yield (pages.Results)
if self.player.id_in_group == 1:
if self.case == 'min':
expected_payoff = 110
elif self.case == 'max':
expected_payoff = 190
else:
expected_payoff = 150
assert self.player.payoff == expected_payoff
oTree will automatically run the bot three times, each time with a different value assigned to self.case
. Command-line bots are generally recommended when using test cases, as browser bots will only execute a single case.
The cases
list can contain any data type, including strings, integers, or even dictionaries.
error_fields
When using SubmissionMustFail
on forms with multiple fields, the error_fields
argument provides more specific feedback about which fields caused the submission to fail.
For example:
yield SubmissionMustFail(
pages.Survey,
dict(
age=20,
weight=-1,
height=-1,
),
error_fields=['weight', 'height']
)
This verifies that the weight
and height
fields contain errors, while age
does not. If the error_message
returns an error, then error_fields
will be ['__all__']
. This makes debugging and validating your forms much easier. You can find more information about error messages in the oTree Forms documentation.
Avoid assigning self.player
(or self.participant
, etc.) to a local variable within bots, especially if a yield
statement occurs in between. The data might not be updated correctly. Always access player or participant attributes directly using self.player.money_left
to ensure you're working with the most up-to-date data from the database.
call_live_method
To test real-time functionality within your oTree experiments, define a top-level function called call_live_method
in your tests.py
file. This function simulates a series of calls to your live_method
. (This feature is unavailable in oTree Studio.)
The call_live_method
function should take the following arguments:
method
: Simulates your player model's live method. For example, method(3, 'hello')
calls the live_method
on player 3 with data
set to 'hello'
.case
: As described in the Test Cases section.page_class
: The current page class (e.g., pages.MyPage
).round_number
For example:
def call_live_method(method, **kwargs):
method(1, {"offer": 50})
method(2, {"accepted": False})
method(1, {"offer": 60})
retval = method(2, {"accepted": True})
# you can do asserts on retval
call_live_method
is automatically executed when the fastest bot in the group reaches a page with a live_method
. You can use waiting pages to synchronize bots if needed.
By leveraging these advanced bot features, you can significantly improve the efficiency and robustness of your oTree experiment testing process. From faster command-line execution to detailed test case management and live page testing, oTree provides the tools you need to ensure your experiments are running smoothly and producing reliable results.