从脚本中可以看出,脚本主要包含两个类,一个是 `UserLocust`(继承自 `HttpLocust`,而 `HttpLocust`继承自 `Locust`),另一个是 `UserCollects`(继承自 `TaskSet`)。事实上,在 `Locust`的测试脚本中,所有业务测试场景都是在 `Locust`和 `TaskSet`两个类的继承子类中进行描述的。
那如何理解 `Locust`和 `TaskSet`这两个类呢?
简单地说,`Locust类`就好比是一群蝗虫,而每一只蝗虫就是一个类的实例。相应的,`TaskSet类`就好比是蝗虫的大脑,控制着蝗虫的具体行为,即实际业务场景测试对应的任务集。
接下来,我将分别对 `Locust`和 `TaskSet`两个类进行详细介绍。
**class HttpLocust(Locust)**
在 `Locust类`中,具有一个 `client`属性,它对应着虚拟用户作为客户端所具备的请求能力,也就是我们常说的请求方法。通常情况下,我们不会直接使用 `Locust`类,因为其 `client`属性没有绑定任何方法。因此在使用 `Locust`时,需要先继承 `Locust类`,然后在继承子类中的 `client`属性中绑定客户端的实现类。
对于常见的 `HTTP(S)`协议,`Locust`已经实现了 `HttpLocust`类,其 `client`属性绑定了 `HttpSession`类,而 `HttpSession`又继承自 `requests.Session`。因此在测试 `HTTP(S)`的 `Locust脚本`中,我们可以通过 `client`属性来使用 `Python requests`库的所有方法,包括 `GET/POST/HEAD/PUT/DELETE/PATCH`等,调用方式也与 `requests`完全一致。另外,由于 `requests.Session`的使用,因此 `client`的方法调用之间就自动具有了状态记忆的功能。常见的场景就是,在登录系统后可以维持登录状态的 `Session`,从而后续HTTP请求操作都能带上登录态。
而对于 `HTTP(S)`以外的协议,我们同样可以使用 `Locust`进行测试,只是需要我们自行实现客户端。在客户端的具体实现上,可通过注册事件的方式,在请求成功时触发 `events.request_success`,在请求失败时触发 `events.request_failure`即可。然后创建一个继承自 `Locust类`的类,对其设置一个 `client`属性并与我们实现的客户端进行绑定。后续,我们就可以像使用 `HttpLocust类`一样,测试其它协议类型的系统。
原理就是这样简单!
在 `Locust类`中,除了 `client`属性,还有几个属性需要关注下:
* `task_set`: 指向一个 `TaskSet`类,`TaskSet`类定义了用户的任务信息,该属性为必填;
* `max_wait/min_wait`: 每个用户执行两个任务间隔时间的上下限(毫秒),具体数值在上下限中随机取值,若不指定则默认间隔时间固定为1秒;
* `host`:被测系统的host,当在终端中启动 `locust`时没有指定 `--host`参数时才会用到;
* `weight`:同时运行多个 `Locust类`时会用到,用于控制不同类型任务的执行权重。
测试开始后,每个虚拟用户(`Locust实例`)的运行逻辑都会遵循如下规律:
1. 先执行 `userCollects`中的 `on_start`(只执行一次),作为初始化;
2. 从 `userCollects`中随机挑选(如果定义了任务间的权重关系,那么就是按照权重关系随机挑选)一个任务执行;
3. 根据 `Locust类`中 `min_wait`和 `max_wait`定义的间隔时间范围(如果 `TaskSet类`中也定义了 `min_wait`或者 `max_wait`,以 `TaskSet`中的优先),在时间范围中随机取一个值,休眠等待;
4. 重复 `2~3`步骤,直至测试任务终止。
**class TaskSet**
再说下 `TaskSet类`。
性能测试工具要模拟用户的业务操作,就需要通过脚本模拟用户的行为。在前面的比喻中说到,`TaskSet类`好比蝗虫的大脑,控制着蝗虫的具体行为。
具体地,`TaskSet类`实现了虚拟用户所执行任务的调度算法,包括规划任务执行顺序(`schedule_task`)、挑选下一个任务(`execute_next_task`)、执行任务(`execute_task`)、休眠等待(`wait`)、中断控制(`interrupt`)等等。在此基础上,我们就可以在 `TaskSet`子类中采用非常简洁的方式来描述虚拟用户的业务测试场景,对虚拟用户的所有行为(任务)进行组织和描述,并可以对不同任务的权重进行配置。