zoukankan      html  css  js  c++  java
  • Locust 性能测试工具安装使用说明

    1. 介绍

        它是一个开源性能测试工具。使用 Python 代码来定义用户行为。用它可以模拟百万计的并发用户访问你的系统。

    性能工具对比


    LoadRunner 是非常有名的商业性能测试工具,功能非常强大。使用也比较复杂,目前大多介绍性能测试的书籍都以该工具为基础,甚至有些书整本都在介绍 LoadRunner 的使用。

    Jmeter 同样是非常有名的开源性能测试工具,功能也很完善,在本书中介绍了它作为接口测试工具的使用。但实际上,它是一个标准的性能测试工具。关于Jmeter相关的资料也非常丰富,它的官方文档也很完善。

    Locust 同样是性能测试工具,虽然官方这样来描述它 “An open source load testing tool.” 。但其它和前面两个工具有着较大的不同。相比前面两个工具,功能上要差上不少,但它也并非优点全无。

    • Locust 完全基本 Python 编程语言,采用 Pure Python 描述测试脚本,并且 HTTP 请求完全基于 Requests 库。除了 HTTP/HTTPS 协议,Locust 也可以测试其它协议的系统,只需要采用Python调用对应的库进行请求描述即可。
    • LoadRunner 和 Jmeter 这类采用进程和线程的测试工具,都很难在单机上模拟出较高的并发压力。Locust 的并发机制摒弃了进程和线程,采用协程(gevent)的机制。协程避免了系统级资源调度,由此可以大幅提高单机的并发能力。

    正是基于这样的特点,使我选择使用Locust工具来做性能测试,另外一个原因是它可以让我们换一种方式认识性能测试,可能更容易看清性能测试的本质。

    我想已经成功的引起了你的兴趣,那么接下来就跟着来学习Locust的使用吧。

    2. Locust 安装

    Locust 是基于 Python 语言的一个性能测试库,如果要想使用它来做性能测试必须要先安装 Python 。
    python3.6 版本安装(略)

    方式一:通过 pip 命令安装

     
     
     
    1
     
     
     
    1
    pip install  locust
     
     

    方式二:GitHub下载安装

    GitHub项目地址:https://github.com/locustio/locust/

    将项目克隆下来,通过Python 执行 setup.py 文件

     
     
     
    1
     
     
     
    1
    python setup.py install
     
     
    最后,检查是否安装成功。命令窗口,输入 “locust --v” 查看版本

    3. Locust 使用入门

    编写第一个性能测试脚本

    创建一个locustfile.py 脚本文件
     
     
     
    13
     
     
     
    1
    from locust import HttpLocust, TaskSet, task
    2
    
    
    3
    # 定义用户行为
    4
    class UserBehavior(TaskSet):
    5
    
    
    6
        @task
    7
        def baidu_index(self):
    8
            self.client.get("/")
    9
    
    
    10
    class WebsiteUser(HttpLocust):
    11
        task_set = UserBehavior
    12
        min_wait = 3000
    13
        max_wait = 6000
     
     
    UserBehavior类继承TaskSet类,用于描述用户行为。
    baidu_index() 方法表示一个用户为行,访问百度首页。
    使用@task装饰该方法为一个事务。client.get()用于指请求的路径“/”,因为是百度首页,所以指定为根路径。

    WebsiteUser类用于设置性能测试。

    • task_set :指向一个定义的用户行为类。
    • min_wait :执行事务之间用户等待时间的下界(单位:毫秒)。
    • max_wait :执行事务之间用户等待时间的上界(单位:毫秒)。

    执行性能测试脚本

     
     
     
    3
     
     
     
    1
    locust -f ./locustfile.py --host=https://www.baidu.com
    2
    #[2019-07-04 15:40:11,348] tsbc.leaptocloud/INFO/locust.main: Starting web monitor at *:8089
    3
    #[2019-07-04 15:40:11,348] tsbc.leaptocloud/INFO/locust.main: Starting Locust 0.11.1
     
     
    • -f 指定性能测试脚本文件。
    • --host 指定被测试应用的URL的地址,注意访问百度使用的HTTPS协议。

    通过浏览器访问:http://127.0.0.1:8089(Locust启动网络监控器,默认为端口号为: 8089)

    设置模拟用户数。

    设置孵化率 每秒产生(启动)的虚拟用户数。

    点击 “启动” 按钮,开始运行性能测试。

    性能测试参数分析

    • Type: 请求的类型,例如GET/POST。
    • Name:请求的路径。这里为百度首页,即:https://www.baidu.com/
    • request:当前请求的数量。
    • fails:当前请求失败的数量。
    • Median:中间值,单位毫秒,一半的服务器响应时间低于该值,而另一半高于该值。
    • Average:平均值,单位毫秒,所有请求的平均响应时间。
    • Min:请求的最小服务器响应时间,单位毫秒。
    • Max:请求的最大服务器响应时间,单位毫秒。
    • Content Size:单个请求的大小,单位字节。

    4. Locust 脚本开发进阶

    Locust 中类的定义和使用

     

    HttpLocust 类

    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. 先执行WebsiteTasks中的on_start(只执行一次),作为初始化;
    2. WebsiteTasks中随机挑选(如果定义了任务间的权重关系,那么就是按照权重关系随机挑选)一个任务执行;
    3. 根据Locust类min_waitmax_wait定义的间隔时间范围(如果TaskSet类中也定义了min_wait或者max_wait,以TaskSet中的优先),在时间范围中随机取一个值,休眠等待;
    4. 重复2~3步骤,直至测试任务终止。
     
     
     
    20
     
     
     
    1
    from locust import HttpLocust, TaskSet, task
    2
    
    
    3
    class UserTask(TaskSet):
    4
    
    
    5
        @task
    6
        def tc_index(self):
    7
            self.client.get("/")
    8
    
    
    9
    class UserOne(HttpLocust):
    10
        task_set = UserTask
    11
        weight = 1
    12
        min_wait = 1000
    13
        max_wait = 3000
    14
        stop_timeout = 5
    15
        host = "https://www.baidu.com"
    16
    
    
    17
    class UserTwo(HttpLocust):
    18
        weight = 2
    19
        task_set = UserTask
    20
        host = "https://www.baidu.com"
     
     

     

    一个Locust实例被挑选执行的权重,数值越大,执行频率越高。在一个 locustfile.py 文件中可以同时定义多个 HttpLocust 子类,然后分配他们的执行权重,例如:

    然后在终端启动测试:


     
     
     
    1
     
     
     
    1
    locust -f locustfile.py UserOne UserTwo
     
     

     

    TaskSet 类

    性能测试工具要模拟用户的业务操作,就需要通过脚本模拟用户的行为。在前面的比喻中说到,TaskSet类好比蝗虫的大脑,控制着蝗虫的具体行为。

    具体地,TaskSet类实现了虚拟用户所执行任务的调度算法,包括规划任务执行顺序(schedule_task)、挑选下一个任务(execute_next_task)、执行任务(execute_task)、休眠等待(wait)、中断控制(interrupt)等等。在此基础上,我们就可以在TaskSet子类中采用非常简洁的方式来描述虚拟用户的业务测试场景,对虚拟用户的所有行为(任务)进行组织和描述,并可以对不同任务的权重进行配置。

    TaskSet子类中定义任务信息时,可以采取两种方式,@task装饰器tasks属性

    采用@task装饰器定义任务信息时,描述形式如下:


     
     
     
    8
     
     
     
    1
    from locust import TaskSet, task
    2
    class UserBehavior(TaskSet):
    3
        @task(1)
    4
        def test_job1(self):
    5
            self.client.get('/job1')
    6
        @task(2)
    7
        def test_job2(self):
    8
            self.client.get('/job2')
     
     
    采用tasks属性定义任务信息时,描述形式如下:

     
     
     
    8
     
     
     
    1
    from locust import TaskSet
    2
    def test_job1(obj):
    3
        obj.client.get('/job1')
    4
    def test_job2(obj):
    5
        obj.client.get('/job2')
    6
    class UserBehavior(TaskSet):
    7
        tasks = {test_job1:1, test_job2:2}
    8
        # tasks = [(test_job1,1), (test_job1,2)] # 两种方式等价
     
     
    在如上两种定义任务信息的方式中,均设置了权重属性,即执行test_job2的频率是test_job1的两倍。
    若不指定执行任务的权重,则相当于比例为1:1
    A:

     
     
     
    8
     
     
     
    1
    from locust import TaskSet, task
    2
    class UserBehavior(TaskSet):
    3
        @task
    4
        def test_job1(self):
    5
            self.client.get('/job1')
    6
        @task
    7
        def test_job2(self):
    8
            self.client.get('/job2')
     
     
    B:

     
     
     
    7
     
     
     
    1
    from locust import TaskSet
    2
    def test_job1(obj):
    3
        obj.client.get('/job1')
    4
    def test_job2(obj):
    5
        obj.client.get('/job2')
    6
    class UserBehavior(TaskSet):
    7
        tasks = [test_job1, test_job2]
     
     
    在TaskSet子类中除了定义任务信息,还有一个是经常用到的,那就是on_start函数。这个和LoadRunner中的vuser_init功能相同,在正式执行测试前执行一次,主要用于完成一些初始化的工作。例如,当测试某个搜索功能,而该搜索功能又要求必须为登录态的时候,就可以先在on_start中进行登录操作HttpLocust使用到了requests.Session,因此后续所有任务执行过程中就都具有登录态了。

    TaskSequence类

    TaskSequence类是一个TaskSet,但它的任务将按顺序执行。要定义此顺序,您应该执行以下操作:

     
     
     
    13
     
     
     
    1
    class MyTaskSequence(TaskSequence):
    2
        @seq_task(1)
    3
        def first_task(self):
    4
            pass
    5
    
    
    6
        @seq_task(2)
    7
        def second_task(self):
    8
            pass
    9
    
    
    10
        @seq_task(3)
    11
        @task(10)
    12
        def third_task(self):
    13
            pass
     
     
    在上面的示例中,顺序被定义为执行first_task,然后执行second_task,最后执行third_task 10次。如您所见,您可以@seq_task使用@task装饰器进行组合,当然您也可以在TaskSequences中嵌套TaskSet,反之亦然。

    公共库

    子目录可以是一种更清晰的方法(参见下面的示例),但是locust只会导入相对于放置运行的locustfile的目录的模块。如果您希望从项目根目录(即运行locust命令的位置)导入,请确保sys.path.append(os.getcwd())在导入任何公共库之前写入您的locust文件 - 这将使项目成为root(即当前正在工作)目录)可导入。
    项目根
    • __init__.py
    • common/
      • __init__.py
      • config.py
      • auth.py
    • locustfiles/
      • __init__.py
      • web_app.py
      • api.py
      • ecommerce.py
    使用上述项目结构,您的locust文件可以使用以下命令导入公共库:

     
     
     
    2
     
     
     
    1
    sys.path.append(os.getcwd())
    2
    import common.auth
     
     

     

    HttpSession类

    用于在请求之间执行Web请求和保留(会话)cookie的类(以便能够登录和退出网站)。记录每个请求,以便蝗虫可以显示统计信息。

    每个发出请求的方法还需要两个额外的可选参数,这些参数是特定于Locust的,并且在python-requests中不存在。这些是:

    • name - (可选)可以指定在Locust的统计信息中用作标签而不是URL路径的参数。这可用于将请求的不同URL分组到Locust统计信息中的单个条目中。
    • catch_response - (可选)布尔参数,如果设置,可用于发出请求,返回上下文管理器作为with语句的参数。这将允许根据响应内容将请求标记为失败,即使响应代码正常(2xx)。相反也有效,可以使用catch_response来捕获请求,然后将其标记为成功,即使响应代码不是(即500或404)。
    request方法网址名称=无catch_response = False** kwargs 

    构造并发送一个requests.Request返回requests.Response对象。

    参数:
    • 方法 - 新Request对象的方法
    • url - 新Request对象的URL 
    • name - (可选)可以指定在Locust的统计信息中用作标签而不是URL路径的参数。这可用于将请求的不同URL分组到Locust统计信息中的单个条目中。
    • catch_response - (可选)布尔参数,如果设置,可用于发出请求,返回上下文管理器作为with语句的参数。这将允许根据响应内容将请求标记为失败,即使响应代码正常(2xx)。相反也有效,可以使用catch_response来捕获请求,然后将其标记为成功,即使响应代码不是(即500或404)。
    • params - (可选)要在查询字符串中发送的字典或字节Request
    • data - (可选)在体内发送的字典或字节Request
    • headers - (可选)用于发送的HTTP头的字典Request
    • cookies - (可选)用于发送的Dict或CookieJar对象Request
    • files - (可选)用于多部分编码上载的字典'filename': file-like-objects
    • auth - (可选)Auth tuple或callable以启用Basic / Digest / Custom HTTP Auth。
    • timeoutfloat tuple) - (可选)等待服务器在放弃之前以浮点或(连接超时,读取超时)元组的形式发送数据的时间长度
    • allow_redirectsbool) - (可选)默认设置为True。
    • proxies - (可选)字典映射协议到代理的URL。
    • stream - (可选)是否立即下载响应内容。默认为False
    • 验证 - (可选)是否True,将验证SSL证书。还可以提供CA_BUNDLE路径。
    • cert - (可选)if String,ssl客户端证书文件(.pem)的路径。如果Tuple,('cert','key')配对。

    脚本增强

    设置响应断言
    性能测试也需要设置断言么? 某些情况下是需要,比如你在请求一个页面时,就可以通过状态来判断返回的 HTTP 状态码是不是 200。
     
     
     
    17
     
     
     
    1
    from locust import HttpLocust, TaskSet, task
    2
    
    
    3
    class UserTask(TaskSet):
    4
    
    
    5
        @task
    6
        def job(self):
    7
            with self.client.get('/', catch_response = True) as response:
    8
                if response.status_code == 200:
    9
                    response.failure('Failed!')
    10
                else:
    11
                    response.success()
    12
    
    
    13
    class User(HttpLocust):
    14
        task_set = UserTask
    15
        min_wait = 1000
    16
        max_wait = 3000
    17
        host = "https://www.baidu.com"
     
     

    catch_response = True :布尔类型,如果设置为 True, 允许该请求被标记为失败。

    通过 client.get() 方法发送请求,将整个请求的给 response, 通过 response.status_code 得请求响应的 HTTP 状态码。如果不为 200 则通过 response.failure('Failed!') 打印失败!

    Locust关联
    在某些请求中,需要携带之前从Server端返回的参数,因此在构造请求时需要先从之前的Response中提取出所需的参数。
     
     
     
    24
     
     
     
    1
    from lxml import etree
    2
    from locust import TaskSet, task, HttpLocust
    3
    class UserBehavior(TaskSet):
    4
        @staticmethod
    5
        def get_session(html):
    6
            tree = etree.HTML(html)
    7
            return tree.xpath("//div[@class='btnbox']/input[@name='session']/@value")[0]
    8
        @task(10)
    9
        def test_login(self):
    10
            html = self.client.get('/login').text
    11
            username = 'user@compay.com'
    12
            password = '123456'
    13
            session = self.get_session(html)
    14
            payload = {
    15
                'username': username,
    16
                'password': password,
    17
                'session': session
    18
            }
    19
            self.client.post('/login', data=payload)
    20
    class WebsiteUser(HttpLocust):
    21
        host = 'http://debugtalk.com'
    22
        task_set = UserBehavior
    23
        min_wait = 1000
    24
        max_wait = 3000
     
     
    Locust 参数化
    所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复。
    例如,模拟3用户并发注册账号,要求注册账号不重复,注册完毕后结束测试;
     
     
     
    31
     
     
     
    1
    from locust import TaskSet, task, HttpLocust
    2
    import queue
    3
    class UserBehavior(TaskSet):
    4
        @task
    5
        def test_register(self):
    6
            try:
    7
                data = self.locust.user_data_queue.get()
    8
            except queue.Empty:
    9
                print('account data run out, test ended.')
    10
                exit(0)
    11
            print('register with user: {}, pwd: {}'
    12
                .format(data['username'], data['password']))
    13
            payload = {
    14
                'username': data['username'],
    15
                'password': data['password']
    16
            }
    17
            self.client.post('/register', data=payload)
    18
    class WebsiteUser(HttpLocust):
    19
        host = 'http://debugtalk.com'
    20
        task_set = UserBehavior
    21
        user_data_queue = queue.Queue()
    22
        for index in range(100):
    23
            data = {
    24
                "username": "test%04d" % index,
    25
                "password": "pwd%04d" % index,
    26
                "email": "test%04d@debugtalk.test" % index,
    27
                "phone": "186%08d" % index,
    28
            }
    29
            user_data_queue.put_nowait(data)
    30
        min_wait = 1000
    31
        max_wait = 3000
     
     

    HttpRunner使用(v2.x) 

    介绍

    HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。

    安装

     
     
     
    1
     
     
     
    1
     pip install httprunner
     
     

    在 HttpRunner 安装成功后,系统中会新增如下 5 个命令:

    • httprunner: 核心命令
    • ate: 曾经用过的命令(当时框架名称为 ApiTestEngine),功能与 httprunner 完全相同
    • hrun: httprunner 的缩写,功能与 httprunner 完全相同
    • locusts: 基于 Locust 实现性能测试
    • har2case: 辅助工具,可将标准通用的 HAR 格式(HTTP Archive)转换为YAML/JSON格式的测试用例

    httprunner、hrun、ate 三个命令完全等价,功能特性完全相同,个人推荐使用hrun命令。

    运行如下命令,若正常显示版本号,则说明 HttpRunner 安装成功。

     
     
     
    2
     
     
     
    1
    (locust) [root@tsbc api]# hrun -V
    2
    2.1.3
     
     

    快速使用

    抓包
    使用Chrome或者火狐浏览器,打开要访问的API,同时使用打开开发工具【网络】,查看接口请求状态
    选中接口请求,右键导出保存为HAR格式文件,假设导出的文件名称为 demo-quickstart.har。
    生成测试用例

    为了简化测试用例的编写工作,HttpRunner 实现了测试用例生成的功能。

    首先,需要将抓取得到的数据包导出为 HAR 格式的文件,如:名称为 demo-quickstart.har。

    然后,在命令行终端中运行如下命令,即可将 demo-quickstart.har 转换为 HttpRunner 的测试用例文件。

     
     
     
    4
     
     
     
    1
    har2case docs/data/demo-quickstart.har -2y
    2
    INFO:root:Start to generate testcase.
    3
    INFO:root:dump testcase to YAML format.
    4
    INFO:root:Generate YAML testcase successfully: docs/data/demo-quickstart.yml
     
     
    使用 har2case 转换脚本时默认转换为 JSON 格式,加上 -2y 参数后转换为 YAML 格式。两种格式完全等价,YAML 格式更简洁,JSON 格式支持的工具更丰富,大家可根据个人喜好进行选择
    经过转换,在源 demo-quickstart.har 文件的同级目录下生成了相同文件名称的 YAML 格式测试用例文件 demo-quickstart.yml,其内容如下:
     
     
     
    41
     
     
     
    1
    - config:
    2
        name: testcase description
    3
        variables: {}
    4
    
    
    5
    - test:
    6
        name: /api/get-token
    7
        request:
    8
            headers:
    9
                Content-Type: application/json
    10
                User-Agent: python-requests/2.18.4
    11
                app_version: 2.8.6
    12
                device_sn: FwgRiO7CNA50DSU
    13
                os_platform: ios
    14
            json:
    15
                sign: 9c0c7e51c91ae963c833a4ccbab8d683c4a90c98
    16
            method: POST
    17
            url: http://127.0.0.1:5000/api/get-token
    18
        validate:
    19
            - eq: [status_code, 200]
    20
            - eq: [headers.Content-Type, application/json]
    21
            - eq: [content.success, true]
    22
            - eq: [content.token, baNLX1zhFYP11Seb]
    23
    
    
    24
    - test:
    25
        name: /api/users/1000
    26
        request:
    27
            headers:
    28
                Content-Type: application/json
    29
                User-Agent: python-requests/2.18.4
    30
                device_sn: FwgRiO7CNA50DSU
    31
                token: baNLX1zhFYP11Seb
    32
            json:
    33
                name: user1
    34
                password: '123456'
    35
            method: POST
    36
            url: http://127.0.0.1:5000/api/users/1000
    37
        validate:
    38
            - eq: [status_code, 201]
    39
            - eq: [headers.Content-Type, application/json]
    40
            - eq: [content.success, true]
    41
            - eq: [content.msg, user created successfully.]
     
     

    现在我们只需要知道如下几点:

    • 每个 YAML/JSON 文件对应一个测试用例(testcase)
    • 每个测试用例为一个list of dict结构,其中可能包含全局配置项(config)和若干个测试步骤(test)
    • config 为全局配置项,作用域为整个测试用例
    • test 对应单个测试步骤,作用域仅限于本身

    如上便是 HttpRunner 测试用例的基本结构。

       demo-quickstart.json

     
     
     
    58
     
     
     
    1
    [
    2
        {
    3
            "config": {
    4
                "name": "testcase description",
    5
                "variables": {}
    6
            }
    7
        },
    8
        {
    9
            "test": {
    10
                "name": "/api/get-token",
    11
                "request": {
    12
                    "url": "http://127.0.0.1:5000/api/get-token",
    13
                    "method": "POST",
    14
                    "headers": {
    15
                        "User-Agent": "python-requests/2.18.4",
    16
                        "device_sn": "FwgRiO7CNA50DSU",
    17
                        "os_platform": "ios",
    18
                        "app_version": "2.8.6",
    19
                        "Content-Type": "application/json"
    20
                    },
    21
                    "json": {
    22
                        "sign": "9c0c7e51c91ae963c833a4ccbab8d683c4a90c98"
    23
                    }
    24
                },
    25
                "validate": [
    26
                    {"eq": ["status_code", 200]},
    27
                    {"eq": ["headers.Content-Type", "application/json"]},
    28
                    {"eq": ["content.success", true]},
    29
                    {"eq": ["content.token", "baNLX1zhFYP11Seb"]}
    30
                ]
    31
            }
    32
        },
    33
        {
    34
            "test": {
    35
                "name": "/api/users/1000",
    36
                "request": {
    37
                    "url": "http://127.0.0.1:5000/api/users/1000",
    38
                    "method": "POST",
    39
                    "headers": {
    40
                        "User-Agent": "python-requests/2.18.4",
    41
                        "device_sn": "FwgRiO7CNA50DSU",
    42
                        "token": "baNLX1zhFYP11Seb",
    43
                        "Content-Type": "application/json"
    44
                    },
    45
                    "json": {
    46
                        "name": "user1",
    47
                        "password": "123456"
    48
                    }
    49
                },
    50
                "validate": [
    51
                    {"eq": ["status_code", 201]},
    52
                    {"eq": ["headers.Content-Type", "application/json"]},
    53
                    {"eq": ["content.success", true]},
    54
                    {"eq": ["content.msg", "user created successfully."]}
    55
                ]
    56
            }
    57
        }
    58
    ]
     
     

    首次运行测试用例

    运行测试用例的命令为hrun,后面直接指定测试用例文件的路径即可。
     
     
     
    1
     
     
     
    1
    $ hrun docs/data/demo-quickstart-1.yml
     
     
    执行性能测试使用locusts 命令执行,
     
     
     
    1
     
     
     
    1
    locusts -f docs/data/demo-quickstart-1.yml
     
     
    进阶使用参考官方文档:
    https://cn.httprunner.org/
     
  • 相关阅读:
    数据共享之死锁
    响应式菜单制作
    工作日志2014-07-01
    Thinkphp 无法使用->order() 排序的两种解决的方法!
    C#
    HDU1232 畅通project 并查集
    Cocos2d-x优化中图片优化
    1.3.4 设计并发友好的应用程序
    UIView的层介绍
    《鸟哥的Linux私房菜-基础学习篇(第三版)》(三)
  • 原文地址:https://www.cnblogs.com/tsbc/p/11139814.html
Copyright © 2011-2022 走看看