TaskSet类
如果Locust类代表了一窝蜜蜂,那么TaskSet类可以比作蜜蜂的头脑。每个Locust类都有一个对应TaskSet的task_set属性集
TaskSet是任务的集合。这些任务可以被python正常调用-如果在对一个拍卖网站做负载测试-可以做些任务“加载启动页”,“搜索一些产品”,“投标”。
当负载测试开始后,由Locust类产出的每个实例将会开始执行它们的TaskSet。接下来每个TaskSet会选取其中的一个task并且调用它。在Locust类的min_wait 和max_wait的范围内随机选取一个值作为等待时间(除非min_wait/max_wait已经在TaskSet中被定义,这样就会使用TaskSet中的值)。然后它会选取调用一个新的task,然后等待,如此往复。
任务的声明
为一个TaskSet声明任务的典型方式是使用task装饰器
这是个例子:
from locust import Locust, TaskSet, task
class MyTaskSet(TaskSet):
@task
def my_task(self):
print "Locust instance (%r) executing my_task" % (self.locust)
class MyLocust(Locust):
task_set = MyTaskSet
@task 使用了可选的权重语句被用来定义任务的执行比率。在下面的例子中task2执行次数是task1的两倍:
from locust import Locust, TaskSet, task
class MyTaskSet(TaskSet):
min_wait = 5000
max_wait = 15000
@task(3)
def task1(self):
pass
@task(6)
def task2(self):
pass
class MyLocust(Locust):
task_set = MyTaskSet
tasks 属性
使用task属性来声明任务是比较方便的,通常来说这个是最好的方式。但是,也可以通过设置tasks属性来定义TaskSet下的不同任务(使用@task装饰器实际上只是提供了tasks属性的参数输入)。
tasks属性可以是可供python调用的列表,或者可调用的<可调用的:整型>字典。任务可以用来接受参数并且可被python调用-用来执行task的TaskSet类的实例。这里又个非常简单的例子(这个文件不会进行任何负载测试)
from locust import Locust, TaskSet
def my_task(l):
pass
class MyTaskSet(TaskSet):
tasks = [my_task]
class MyLocust(Locust):
task_set = MyTaskSet
如果tasks属性被定义为一个列表,那么每次执行任务的时候,列表项会被随机选取作为tasks属性。如果tasks是个字典-可被调用的键名和整数作为值-那么将随机选取任务进行执行,被选取的机率由任务键所对应的值决定。如下:
{my_task: 3, another_task:1}
my_task 相对 another_task的执行机率 是3:1.
TaskSets 可以被嵌套
TaskSets的一个非常重要的属性是它们可以被嵌套,因为真实的网站通常被划分为多个小单位并且以分级的方式建立。因此嵌套的TaskSets允许我们以更加真实的方式定义虚拟用户的行为。例如我们以如下的结构定义TaskSets:
- Main user behaviour
- Index page
- Forum page
- Read thread
- Reply
- New thread
- View next page
- Browse categories
- Watch movie
- Filter movies
- About page
嵌套TaskSets的方式就像使用tasks属性去定义一个任务,但是它不是调用一个python函数而是指向了另外一个TaskSet
class ForumPage(TaskSet):
@task(20)
def read_thread(self):
pass
@task(1)
def new_thread(self):
pass
@task(5)
def stop(self):
self.interrupt()
class UserBehaviour(TaskSet):
tasks = {ForumPage:10}
@task
def index(self):
pass
在上面的例子中,当UserBehaviour的TaskSet在执行过程中ForumPage被选中执行的话,然后ForumPage的TaskSet就会执行。接下来ForumPage的TaskSet从它的任务中选择一个执行,然后等待,如此往复。
上面例子中需要注意的一点是对ForumPage的stop方法中self.interrupt()的调用。它的作用是停止执行ForumPage的任务集,而继续执行UserBehavior的实例。如果在ForumPage中没有引用 interrupt()方法,Locust一旦开始了ForumPage任务就永远不会停下。但是有了interrrupt函数,我们就可以通过和任务权重的绑定来定义虚拟用户离开forum的概率。
也可以通过@task装饰器件声明一个嵌套的TaskSet,将它内嵌在一个类中,就像声明一般的task一样:
class MyTaskSet(TaskSet):
@task
class SubTaskSet(TaskSet):
@task
def my_task(self):
pass
on_start 函数
TaskSet类可以有选择地声明一个on_start函数。这样,当一个虚拟用户开始执行TaskSet类的时候就可以调用它。
关于Locust实例,或者父类TaskSet的实例
一个TaskSet实例的locust属性指向了它的Locust实例,并且parent属性指向它的父类TaskSet(它会指向在基类TaskSet中的Locust实例)。