2023年6月21日发(作者:)

性能测试-locust简介及使⽤1、JMeter和Locust的对⽐说明1)开源许可证⼯具许可范围的问题是最重要的问题之⼀,因为您可能想知道是否需要⽀付额外的第三⽅⼯具来完成负载测试。 如果某个⼯具是开源的,那么您⼏乎可以实现为性能测试设置的任何⽬标,⽽⽆需任何额外付款。 开源JMeter和Locust也不例外。JMeter和Locust都提供了许可软件许可证,该许可证⽀持免费软件,对软件的分发⽅式提出最低要求。 JMeter是由Apache开发的,它基于Apache License 2.0,⽽Locust是由⼀个由社区驱动的开发⼈员组成的⼩团队开发的 ,基于MIT许可证。 在这两种情况下,这些⼯具都是开源的,允许您⾃由使⽤它们,⽽不受任何使⽤限制。2)负载测试创建和维护性能测试⼯作流程有三个主要步骤:创建,运⾏和分析。 ⼀般第⼀步是最耗时的。编写JMeter性能测试的最常⽤⽅法是使⽤其GUI模式。 JMeter GUI模式提供了⼀个桌⾯客户端,允许您轻松创建测试,⽽⽆需编写单⾏代码(直到您需要创建棘⼿的测试)。 所以最简单的场景可能如下所⽰:JMeter⾮常简单,通常,即使是没有经验的⼯程师也可以毫⽆困难地上⼿。但是如果需要,您可以使⽤Java在GUI和⾮GUI模式下使⽤代码。 但是,由于脚本实现的复杂性(因为JMeter旨在与GUI模式⼀起使⽤)以及缺乏如何制作此类脚本的⽂档,因此这种⽅式在JMeter社区中并不流⾏。Locust则需要python编程基础。3)⽀持的协议理想情况下,您应该能够使⽤尽可能少的⼯具测试所有⼯具,只要它不会影响测试质量。使⽤JMeter,您可以使⽤完整的内置函数和第三⽅插件,在⼀个地⽅创建所有内容的性能测试。 您⽆需编码即可测试不同的协议甚⾄数据库。 这些包括JDBC,FTP,LDAP,SMTP等。JMeter还可以通过jar包扩展,⽐如加载jython,可以使⽤python脚本。根据⽂档,Locust主要⽤于基于HTTP Web的测试。但可以扩展其默认功能并创建⾃定义Python函数来测试可以使⽤Python编程语⾔进⾏测试的任何内容。4)并发⽤户数JMeter和Locust有完全不同的⽅式来处理机器资源。 JMeter有⼀个基于线程的模型,它为每个⽤户分配⼀个单独的线程。 每个步骤的线程分配和基准测试需要⼤量资源,这就是为什么JMeter对于您可以在⼀台机器上模拟的⽤户数量⾮常有限的原因。 您可以在⼀台计算机上运⾏的⽤户数取决于许多因素,如脚本复杂性,硬件,响应⼤⼩等。 如果您的脚本很简单,JMeter允许您在⼀台机器上运⾏多达数千个,但脚本执⾏逐渐变得不可靠。Locust有完全不同的⽤户模拟模型,它基于事件和异步⽅法(协程),以gevent coroutine作为整个过程的基⽯。 这种实现允许Locust框架在⼀台机器上轻松模拟数千个并发⽤户,即使是在⾮常规的笔记本电脑上,也可同时运⾏内部有许多步骤的复杂测试。5)增强灵活性这两个⼯具提供相对相同的⽣成负载的⽅式 - 您可以指定在性能测试期间要使⽤的⽤户数以及它们应该加速的速度。在JMeter中,您可以在指定字段的“线程组”控制器中配置负载:但是JMeter还有其他插件,可以让您配置⾮常灵活的负载。 最好的⽅法之⼀是使⽤Ultimate Thread Group ,它允许⽤户制作⾮常具体的加载模式:6)脚本录制这是JMeter具有强⼤优势的地⽅,因为它具有脚本录制的内置功能,⽽Locust根本没有此功能。 除此之外,还有许多第三⽅插件可以为JMeter制作脚本录制。 记录此类脚本最⽅便的⽅法之⼀是使⽤BlazeMeter chrome扩展。7)测试监控JMeter和Locust都提供了强⼤的内置功能来监控性能脚本并分析您的测试结果。 JMeter有许多不同的元素叫做监听器。 每个侦听器都提供特定类型的监视,你也可以使⽤许多现有的⾃定义监听器扩展默认库。另⼀⽅⾯,JMeter监听器在其运⾏的机器上消耗⼤量资源。这就是为什么通常,JMeter是以⾮GUI模式执⾏的,没有任何监听器或监控过程,在这种情况下,可使⽤3⽅⼯具,如BlazeMeter 。Locust的监测能⼒稍弱,不过⼏乎提供了所有可⽤于监控基本负载的信息。在脚本运⾏期间,Locust运⾏⼀个简单的Web服务器,2、编写Locust⽰例代码locust_ locust import HttpUser, TaskSet, taskclass WebsiteTasks(TaskSet): def on_start(self): ("/login", { "username": "test", "password": "123456" }) @task(2) def index(self): ("/") @task(1) def about(self): ("/about/") tasks = {index: 2, about: 1} # 与装饰器效果⼀致class WebsiteUser(HttpUser): # task_set = WebsiteTasks # Usage of _set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks]) tasks = [WebsiteTasks] host = "" min_wait = 1000 max_wait = 50003、Locust类详细讲解在Locust类中,具有⼀个client属性,它对应着虚拟⽤户作为客户端所具备的请求能⼒,也就是我们常说的请求⽅法。通常情况下,我们不会直接使⽤Locust类,因为其client属性没有绑定任何⽅法。因此在使⽤Locust时,需要先继承Locust类,然后在继承⼦类中的client属性中绑定客户端的实现类。对于常见的HTTP(S)协议,Locust已经实现了HttpUser(1.0之前使⽤HttpLocust)类,其client属性绑定了HttpSession类,⽽HttpSession⼜继承⾃n。因此在测试HTTP(S)的Locust脚本中,我们可以通过client属性来使⽤Python requests库的所有⽅法,包括GET/POST/HEAD/PUT/DELETE/PATCH等,调⽤⽅式也与requests完全⼀致。另外,由于n的使⽤,因此client的⽅法调⽤之间就⾃动具有了状态记忆的功能。常见的场景就是,在登录系统后可以维持登录状态的Session,从⽽后续HTTP请求操作都能带上登录态。⽽对于HTTP(S)以外的协议,我们同样可以使⽤Locust进⾏测试,只是需要我们⾃⾏实现客户端。在客户端的具体实现上,可通过注册事件的⽅式,在请求成功时触发t_success,在请求失败时触发t_failure即可。然后创建⼀个继承⾃Locust类的类,对其设置⼀个client属性并与我们实现的客户端进⾏绑定。后续,我们就可以像使⽤HttpUser类⼀样,测试其它协议类型的系统。原理就是这样简单!在Locust类中,除了client属性,还有⼏个属性需要关注下:tasks(1.0以下是task_set): tasks = [WebsiteTasks] Collection of python callables and/or TaskSet classes that the Locust user(s) willrun.指向⼀个TaskSet类的列表,TaskSet类定义了⽤户的任务信息,该属性为必填;**max_wait/min_wait: 每个⽤户执⾏两个任务间隔时间的上下限(毫秒),具体数值在上下限中随机取值,若不指定则默认间隔时间固定为1秒;host:被测系统的host,当在终端中启动locust时没有指定--host参数时才会⽤到;weight:同时运⾏多个Locust类时会⽤到,⽤于控制不同类型任务的执⾏权重。测试开始后,每个虚拟⽤户(Locust实例)的运⾏逻辑都会遵循如下规律:先执⾏WebsiteTasks中的on_start(只执⾏⼀次),作为初始化;从WebsiteTasks中随机挑选(如果定义了任务间的权重关系,那么就是按照权重关系随机挑选)⼀个任务执⾏;根据Locust类中min_wait和max_wait定义的间隔时间范围(如果TaskSet类中也定义了min_wait或者max_wait,以TaskSet中的优先),在时间范围中随机取⼀个值,休眠等待;重复2~3步骤,直⾄测试任务终⽌。4、TaskSet类详细讲解性能测试⼯具要模拟⽤户的业务操作,就需要通过脚本模拟⽤户的⾏为。在前⾯的⽐喻中说到,TaskSet类好⽐蝗⾍的⼤脑,控制着蝗⾍的具体⾏为。具体地,TaskSet类实现了虚拟⽤户所执⾏任务的调度算法,包括规划任务执⾏顺序(schedule_task)、挑选下⼀个任务(execute_next_task)、执⾏任务(execute_task)、休眠等待(wait)、中断控制(interrupt)等等。在此基础上,我们就可以在TaskSet⼦类中采⽤⾮常简洁的⽅式来描述虚拟⽤户的业务测试场景,对虚拟⽤户的所有⾏为(任务)进⾏组织和描述,并可以对不同任务的权重进⾏配置。在TaskSet⼦类中定义任务信息时,可以采取两种⽅式,@task装饰器和tasks属性。采⽤@task装饰器定义任务信息时,描述形式如下:class WebsiteTasks(TaskSet): def on_start(self): ("/login", { "username": "test", "password": "123456" }) @task(2) def index(self): ("/") @task(1) def about(self): ("/about/")采⽤tasks属性定义任务信息时,描述形式如下:class WebsiteTasks(TaskSet): def on_start(self): ("/login", { "username": "test", "password": "123456" }) # @task(2) def index(self): ("/") # @task(1) def about(self): ("/about/") tasks = {index: 2, about: 1} # 与装饰器效果⼀致在TaskSet⼦类中除了定义任务信息,还有⼀个是经常⽤到的,那就是on_start函数。这个和LoadRunner中的vuser_init功能相同,在正式执⾏测试前执⾏⼀次,主要⽤于完成⼀些初始化的⼯作。例如,当测试某个搜索功能,⽽该搜索功能⼜要求必须为登录态的时候,就可以先在on_start中进⾏登录操作;前⾯也提 到,HttpUser使⽤到了n,因此后续所有任务执⾏过程中就都具有登录态了。5、实战测试1)测试代码from locust import HttpUser, TaskSet, taskclass WebsiteTasks(TaskSet): def on_start(self): # ("/login", { "username": "test", "password": "123456" }) ("/login?key=00d91e8e0cca2b76f515926a36db68f5&phone=&passwd=123456") # @task(2) def videoCategory(self): ("/videoCategory") # @task(1) def videoRecommend(self): ("/videoRecommend?id=127398") def todayVideo(self): ("/todayVideo") def getJoke(self): ("/getJoke?page=1&count=2&type=video") def novelSearchApi(self): ("/searchPoetry?name=古风⼆⾸%20⼆") tasks = {videoCategory: 2, videoRecommend: 1, todayVideo: 2, getJoke: 3, novelSearchApi: 2} # 与装饰器效果⼀致class WebsiteUser(HttpUser): # /c__chao/article/details/78573737 # task_set = WebsiteTasks # Usage of _set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks]) tasks = [WebsiteTasks] host = "" min_wait = 1000 max_wait = 50002)测试结果截图①配置模拟的⽤户数量、每秒增加的⽤户数、测试地址②运⾏时数据③运⾏的异常信息④下载运⾏结果⑤TPS每秒请求数⑥响应时间⑦⽤户数3)测试时服务器的数据后续在做记录个⼈博客

2023年6月21日发(作者:)

性能测试-locust简介及使⽤1、JMeter和Locust的对⽐说明1)开源许可证⼯具许可范围的问题是最重要的问题之⼀,因为您可能想知道是否需要⽀付额外的第三⽅⼯具来完成负载测试。 如果某个⼯具是开源的,那么您⼏乎可以实现为性能测试设置的任何⽬标,⽽⽆需任何额外付款。 开源JMeter和Locust也不例外。JMeter和Locust都提供了许可软件许可证,该许可证⽀持免费软件,对软件的分发⽅式提出最低要求。 JMeter是由Apache开发的,它基于Apache License 2.0,⽽Locust是由⼀个由社区驱动的开发⼈员组成的⼩团队开发的 ,基于MIT许可证。 在这两种情况下,这些⼯具都是开源的,允许您⾃由使⽤它们,⽽不受任何使⽤限制。2)负载测试创建和维护性能测试⼯作流程有三个主要步骤:创建,运⾏和分析。 ⼀般第⼀步是最耗时的。编写JMeter性能测试的最常⽤⽅法是使⽤其GUI模式。 JMeter GUI模式提供了⼀个桌⾯客户端,允许您轻松创建测试,⽽⽆需编写单⾏代码(直到您需要创建棘⼿的测试)。 所以最简单的场景可能如下所⽰:JMeter⾮常简单,通常,即使是没有经验的⼯程师也可以毫⽆困难地上⼿。但是如果需要,您可以使⽤Java在GUI和⾮GUI模式下使⽤代码。 但是,由于脚本实现的复杂性(因为JMeter旨在与GUI模式⼀起使⽤)以及缺乏如何制作此类脚本的⽂档,因此这种⽅式在JMeter社区中并不流⾏。Locust则需要python编程基础。3)⽀持的协议理想情况下,您应该能够使⽤尽可能少的⼯具测试所有⼯具,只要它不会影响测试质量。使⽤JMeter,您可以使⽤完整的内置函数和第三⽅插件,在⼀个地⽅创建所有内容的性能测试。 您⽆需编码即可测试不同的协议甚⾄数据库。 这些包括JDBC,FTP,LDAP,SMTP等。JMeter还可以通过jar包扩展,⽐如加载jython,可以使⽤python脚本。根据⽂档,Locust主要⽤于基于HTTP Web的测试。但可以扩展其默认功能并创建⾃定义Python函数来测试可以使⽤Python编程语⾔进⾏测试的任何内容。4)并发⽤户数JMeter和Locust有完全不同的⽅式来处理机器资源。 JMeter有⼀个基于线程的模型,它为每个⽤户分配⼀个单独的线程。 每个步骤的线程分配和基准测试需要⼤量资源,这就是为什么JMeter对于您可以在⼀台机器上模拟的⽤户数量⾮常有限的原因。 您可以在⼀台计算机上运⾏的⽤户数取决于许多因素,如脚本复杂性,硬件,响应⼤⼩等。 如果您的脚本很简单,JMeter允许您在⼀台机器上运⾏多达数千个,但脚本执⾏逐渐变得不可靠。Locust有完全不同的⽤户模拟模型,它基于事件和异步⽅法(协程),以gevent coroutine作为整个过程的基⽯。 这种实现允许Locust框架在⼀台机器上轻松模拟数千个并发⽤户,即使是在⾮常规的笔记本电脑上,也可同时运⾏内部有许多步骤的复杂测试。5)增强灵活性这两个⼯具提供相对相同的⽣成负载的⽅式 - 您可以指定在性能测试期间要使⽤的⽤户数以及它们应该加速的速度。在JMeter中,您可以在指定字段的“线程组”控制器中配置负载:但是JMeter还有其他插件,可以让您配置⾮常灵活的负载。 最好的⽅法之⼀是使⽤Ultimate Thread Group ,它允许⽤户制作⾮常具体的加载模式:6)脚本录制这是JMeter具有强⼤优势的地⽅,因为它具有脚本录制的内置功能,⽽Locust根本没有此功能。 除此之外,还有许多第三⽅插件可以为JMeter制作脚本录制。 记录此类脚本最⽅便的⽅法之⼀是使⽤BlazeMeter chrome扩展。7)测试监控JMeter和Locust都提供了强⼤的内置功能来监控性能脚本并分析您的测试结果。 JMeter有许多不同的元素叫做监听器。 每个侦听器都提供特定类型的监视,你也可以使⽤许多现有的⾃定义监听器扩展默认库。另⼀⽅⾯,JMeter监听器在其运⾏的机器上消耗⼤量资源。这就是为什么通常,JMeter是以⾮GUI模式执⾏的,没有任何监听器或监控过程,在这种情况下,可使⽤3⽅⼯具,如BlazeMeter 。Locust的监测能⼒稍弱,不过⼏乎提供了所有可⽤于监控基本负载的信息。在脚本运⾏期间,Locust运⾏⼀个简单的Web服务器,2、编写Locust⽰例代码locust_ locust import HttpUser, TaskSet, taskclass WebsiteTasks(TaskSet): def on_start(self): ("/login", { "username": "test", "password": "123456" }) @task(2) def index(self): ("/") @task(1) def about(self): ("/about/") tasks = {index: 2, about: 1} # 与装饰器效果⼀致class WebsiteUser(HttpUser): # task_set = WebsiteTasks # Usage of _set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks]) tasks = [WebsiteTasks] host = "" min_wait = 1000 max_wait = 50003、Locust类详细讲解在Locust类中,具有⼀个client属性,它对应着虚拟⽤户作为客户端所具备的请求能⼒,也就是我们常说的请求⽅法。通常情况下,我们不会直接使⽤Locust类,因为其client属性没有绑定任何⽅法。因此在使⽤Locust时,需要先继承Locust类,然后在继承⼦类中的client属性中绑定客户端的实现类。对于常见的HTTP(S)协议,Locust已经实现了HttpUser(1.0之前使⽤HttpLocust)类,其client属性绑定了HttpSession类,⽽HttpSession⼜继承⾃n。因此在测试HTTP(S)的Locust脚本中,我们可以通过client属性来使⽤Python requests库的所有⽅法,包括GET/POST/HEAD/PUT/DELETE/PATCH等,调⽤⽅式也与requests完全⼀致。另外,由于n的使⽤,因此client的⽅法调⽤之间就⾃动具有了状态记忆的功能。常见的场景就是,在登录系统后可以维持登录状态的Session,从⽽后续HTTP请求操作都能带上登录态。⽽对于HTTP(S)以外的协议,我们同样可以使⽤Locust进⾏测试,只是需要我们⾃⾏实现客户端。在客户端的具体实现上,可通过注册事件的⽅式,在请求成功时触发t_success,在请求失败时触发t_failure即可。然后创建⼀个继承⾃Locust类的类,对其设置⼀个client属性并与我们实现的客户端进⾏绑定。后续,我们就可以像使⽤HttpUser类⼀样,测试其它协议类型的系统。原理就是这样简单!在Locust类中,除了client属性,还有⼏个属性需要关注下:tasks(1.0以下是task_set): tasks = [WebsiteTasks] Collection of python callables and/or TaskSet classes that the Locust user(s) willrun.指向⼀个TaskSet类的列表,TaskSet类定义了⽤户的任务信息,该属性为必填;**max_wait/min_wait: 每个⽤户执⾏两个任务间隔时间的上下限(毫秒),具体数值在上下限中随机取值,若不指定则默认间隔时间固定为1秒;host:被测系统的host,当在终端中启动locust时没有指定--host参数时才会⽤到;weight:同时运⾏多个Locust类时会⽤到,⽤于控制不同类型任务的执⾏权重。测试开始后,每个虚拟⽤户(Locust实例)的运⾏逻辑都会遵循如下规律:先执⾏WebsiteTasks中的on_start(只执⾏⼀次),作为初始化;从WebsiteTasks中随机挑选(如果定义了任务间的权重关系,那么就是按照权重关系随机挑选)⼀个任务执⾏;根据Locust类中min_wait和max_wait定义的间隔时间范围(如果TaskSet类中也定义了min_wait或者max_wait,以TaskSet中的优先),在时间范围中随机取⼀个值,休眠等待;重复2~3步骤,直⾄测试任务终⽌。4、TaskSet类详细讲解性能测试⼯具要模拟⽤户的业务操作,就需要通过脚本模拟⽤户的⾏为。在前⾯的⽐喻中说到,TaskSet类好⽐蝗⾍的⼤脑,控制着蝗⾍的具体⾏为。具体地,TaskSet类实现了虚拟⽤户所执⾏任务的调度算法,包括规划任务执⾏顺序(schedule_task)、挑选下⼀个任务(execute_next_task)、执⾏任务(execute_task)、休眠等待(wait)、中断控制(interrupt)等等。在此基础上,我们就可以在TaskSet⼦类中采⽤⾮常简洁的⽅式来描述虚拟⽤户的业务测试场景,对虚拟⽤户的所有⾏为(任务)进⾏组织和描述,并可以对不同任务的权重进⾏配置。在TaskSet⼦类中定义任务信息时,可以采取两种⽅式,@task装饰器和tasks属性。采⽤@task装饰器定义任务信息时,描述形式如下:class WebsiteTasks(TaskSet): def on_start(self): ("/login", { "username": "test", "password": "123456" }) @task(2) def index(self): ("/") @task(1) def about(self): ("/about/")采⽤tasks属性定义任务信息时,描述形式如下:class WebsiteTasks(TaskSet): def on_start(self): ("/login", { "username": "test", "password": "123456" }) # @task(2) def index(self): ("/") # @task(1) def about(self): ("/about/") tasks = {index: 2, about: 1} # 与装饰器效果⼀致在TaskSet⼦类中除了定义任务信息,还有⼀个是经常⽤到的,那就是on_start函数。这个和LoadRunner中的vuser_init功能相同,在正式执⾏测试前执⾏⼀次,主要⽤于完成⼀些初始化的⼯作。例如,当测试某个搜索功能,⽽该搜索功能⼜要求必须为登录态的时候,就可以先在on_start中进⾏登录操作;前⾯也提 到,HttpUser使⽤到了n,因此后续所有任务执⾏过程中就都具有登录态了。5、实战测试1)测试代码from locust import HttpUser, TaskSet, taskclass WebsiteTasks(TaskSet): def on_start(self): # ("/login", { "username": "test", "password": "123456" }) ("/login?key=00d91e8e0cca2b76f515926a36db68f5&phone=&passwd=123456") # @task(2) def videoCategory(self): ("/videoCategory") # @task(1) def videoRecommend(self): ("/videoRecommend?id=127398") def todayVideo(self): ("/todayVideo") def getJoke(self): ("/getJoke?page=1&count=2&type=video") def novelSearchApi(self): ("/searchPoetry?name=古风⼆⾸%20⼆") tasks = {videoCategory: 2, videoRecommend: 1, todayVideo: 2, getJoke: 3, novelSearchApi: 2} # 与装饰器效果⼀致class WebsiteUser(HttpUser): # /c__chao/article/details/78573737 # task_set = WebsiteTasks # Usage of _set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks]) tasks = [WebsiteTasks] host = "" min_wait = 1000 max_wait = 50002)测试结果截图①配置模拟的⽤户数量、每秒增加的⽤户数、测试地址②运⾏时数据③运⾏的异常信息④下载运⾏结果⑤TPS每秒请求数⑥响应时间⑦⽤户数3)测试时服务器的数据后续在做记录个⼈博客