机器人¶
机器人模拟参与人游玩你的应用。它们点击按钮,填写表单,确保一切运行正常。
这一特性是为那些希望oTree能够自动测试他们应用的懒人设计的。并且oTree Studio甚至可以为你设计模拟代码,使得整个过程(编写和运行机器人程序)变得非常容易。
运行bots¶
- 将bots添加到你的应用中(参考下面的代码)
- 在你的session config中,设置
use_browser_bots=True
。 - 运行服务器并创建一个会话。一旦开始链接被打开,页面会使用浏览器bots自动进行。
编写测试¶
在oTree Studio中,前往你应用的“Test”部分。单击按钮以自动编写bots代码。如果你想要改进生成的代码(比如加入 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
,诸如此类。
编写bots时请忽略等待页面。
轮次¶
你的bot代码应当每次仅模拟一轮。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中使用3个参数,如 expect(self.player.budget, '<', 100)
。这会验证 self.player.budget
比100小。你可以使用下面的这些运算符: '<'
,'<='
,'=='
,'>='
,'>'
,'!='
,'in'
,'not in'
。
测试表单验证¶
如果你使用了 form validation,你应当测试你的应用是否正确地防止了来自用户的错误输入,测试可通过 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)
Bot会提交 MyPage
两次。如果第一次提交 成功,那么一个错误会被抛出,因为这本不应该成功。
检查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检查¶
如果bot试图提交一个在页面HTML实际上不存在的表单或者页面HTML缺少了提交按钮,一个错误会被抛出。
然而,bot系统并不能识别被JavaScript动态添加的字段和按钮。在这种情况下,你应当禁用HTML检查,即设置 check_html=False
。例如,修改下面的代码:
yield pages.MyPage, dict(foo=99)
为:
yield Submission(pages.MyPage, dict(foo=99), check_html=False)
(如果你在 Submission
中不设置 check_html=False
,那么两段代码是等价的。)
模拟页面超时¶
你可以在 Submission
中设置 timeout_happened=True
:
yield Submission(pages.MyPage, dict(foo=99), timeout_happened=True)
高级特性¶
参见 Bots: 高级特性