使用JMeter进行RESTful API测试

在哪里设置实现最优脚本重用的属性java

因为支持云的应用程序一般能够轻松、快速地进行复制和部署,因此能够在多种环境中对其进行测试。若是您须要在多个环境中测试和运行自动化脚本,那么能够在 JMeter 中使用一个独立的属性文件为链接资源(如,应用服务器和数据库)定义数据(包括登陆凭据),这样作颇有好处。正则表达式

在 JMETER_HOME/bin 目录下的三个文件中定义 JMeter 的属性和变量。在启动 JMeter 时,它会按如下顺序加载这些文件:算法

  1. jmeter.properties
  2. 一个可选的用户定义的属性文件
  3. system.properties

当 JMeter 正在运行的时候,若是要添加任何新属性或改变现有的属性,则必须先关闭 JMeter,而后从新启动它,使更改生效。数据库

jmeter.properties 文件存储与 JMeter 应用程序自己有关的属性。这个文件中仅 保留了特定于 JMeter 程序的属性或特定于框架的属性。建立一个单独的文件(文件名由您选择),用该文件来存储测试环境特定的属性和变量,它们对于和接受测试的应用程序有关联的全部脚原本说是全局的属性和变量 — 例如,管理员的用户名/密码。在 jmeter.properties 文件中,取消对 user.properties 设置的注释,并将 user.properties 的值设置为所建立的文件的名称。清单 1 中的示例将该值设置为 myuser.properties:编程

清单 1. 在 jmeter.properties 文件中指定一个用户属性文件json

# Should JMeter automatically load additional JMeter properties?
# File name to look for (comment to disable)
user.properties=myuser.properties

清单 2 中的示例用户属性文件显示了在用户属性文件中定义变量所用的格式。(在该定义中,等号左边的任何地方都不容许有空格;必要时,属性值能够包含空格)。服务器

清单 2. 示例用户属性文件网络

#----------------------------------------------------------------
# FVT API Test Environment parameters
#----------------------------------------------------------------
#
# --- Login Credentials
USER_LOGIN=admin@in.ibm.com
USER_PASSWORD=password
#
# --- Application Server
APP_SERVER=localhost
APP_PORT=80
APP_CONTEXT=ctx
PROTOCOL=http
#
# --- Database Server${DB_NAME}
DB_HOST=localhost
DB_PORT=50000
DB_NAME=dbname
DB_USER=dbadmin
DB_PASSWORD=dbpassword

应保留 JMeter 的第三个属性文件 system.properties,以便必须为全部脚本定义的全系统属性可以使用它。例如,若是您的全部脚本都使用某个特定的数据库服务器,那么您能够在 system.propterties 文件中指定相关的属性。架构

JMeter 的 User Defined Variables 控制面板(如图 1 所示)显示了 JMeter 脚本如何读取在用户属性文件中定义的属性。并发

图 1. JMeter 脚本如何读取在用户属性文件中定义的配置数据

JMeter User Defined Variables 控制面板的屏幕截图,显示了 JMeter 脚本如何读取已在用户属性文件中定义的属性

控制面板的 Value 列中的每一个项目的格式为:

${__property(VARIABLE_NAME,VARIABLE_NAME)}

例如,来自用户属性文件的 USER_LOGIN 变量被读取为脚本中的 ${__property(USER_LOGIN, USER_LOGIN)} 函数。括号中的第一个 USER_LOGIN 是在属性文件中定义的变量的名称(而且已在控制面板的 Name 列中列出)。若是属性文件中没有定义变量,那么第二个实例是默认值或回退值。

什么时候在属性文件中定义一个变量,什么时候将它定义为 JMeter 脚本里面的一个变量,这些并无严格的规定。但有两个准则能够帮助您在多个 JMeter 脚本中实现一致性,并减小没必要要的重复变量定义:

  • 若是在几个脚本一致地使用相同的值,那么能够在用户属性文件或 system.properties 文件中定义数据。这方面的示例包括系统变量(例如,数据库名称和服务器名称),以及执行范围的变量(例如,日志级别)。
  • 若是一些脚本使用一个在各脚本中可能会变化的值,那么能够将它定义为一个脚本变量,或在外部数据文件中定义它,例如,逗号分隔值(CSV)文件。

使用 JSON 模板文件实现有效负载分离

许多云 API 要求使用 JSON 有效负载做为输入。JSON 定义了一组结构化的元素,能够将它们嵌套在其余元素中。每个元素定义一个或多个名称/值对。功能测试包括以指定格式反复提供数据。例如,在一个典型的 REST API 调用中,JSON 有效负载在 REST HTTP 请求的主体中传递,而且一般包含硬编码的数据。硬编码的数据一般会在多个测试中重复,并分散在整个脚本中。

这种方法的一个常见问题是,若是 JSON 结构(或数据)发现变化(也许是由于 API 参数的更改),那么您必须进入 JMeter 测试,找到 HTTP 请求的主体,并修改 JSON 结构(和数据),以知足新的要求。若是在使用此 JSON 结构的多个 JMeter 测试用例中有数千个 HTTP 请求,那么必须执行许多重复的编辑。

更好的方法是建立一个 JSON 结构模板,并定义数据目的地的替换字符串。JSON 模板不包含任何硬编码的数据值,而是定义在脚本运行时随实际数据一块儿加载的引用变量。而后,模板被读入 JMeter 脚本中的某个变量,并在 HTTP 请求主体中被替换。

清单 3 显示了定义一个 JSON 有效负载的传统方式:

清单 3. JMeter 测试计划中的静态 JSON 定义

{
   "Customer":{
      "CustomerType":"DIRECT",
      "CustomerNumber":"1234567890",
      "Organization":{
         "OrgName":"IBM",
         "Phone":"999-999-9999",
         "AddressSet":[

            {
               "AddressLine1":"Tech Park One",
               "AddressLine2":"",
               "AddressType":"MAILING",
               "City":"Pune",
               "Country":"India",
               "State":"Maharashtra",
               "StateCode":"MH",
               "PostalCode":"411006"
            }
         ],
         "Contact":{
            "FamilyName":"Gilra",
            "GivenName":"Shalini",
            "EmailAddress":"shagilra@in.ibm.com",
            "NamePrefix":"Miss",
            "LanguagePreference":"EN_US",
            "WorkPhone":"999-9999"
         }
      }
   }
}

清单 4 显示了在模板中定义 JSON 的动态方式:

清单 4. 在外部 JSON 模板文件中的动态 JSON 定义

{ 
   "Customer":{ 
      "CustomerType":"${__eval(${STR_CUSTOMERTYPE})}", 
      "CustomerNumber":"${__eval(${STR_CUSTOMERNUMBER})}", 
      "Organization":{ 
         "OrgName":"${__eval(${STR_ORGNAME})}", 
         "Phone":"${__eval(${STR_PHONE})}", 
         "AddressSet":[ 
            { 
               "AddressLine1":"${__eval(${STR_ADDRESSLINE1})}", 
               "AddressLine2":"${__eval(${STR_ADDRESSLINE2})}", 
               "AddressType":"${__eval(${STR_ADDRESSTYPE})}", 
               "City":"${__eval(${STR_CITY})}", 
               "Country":"${__eval(${STR_COUNTRY})}", 
               "State":"${__eval(${STR_STATE})}", 
               "StateCode":"${__eval(${STR_STATECODE})}", 
               "PostalCode":"${__eval(${STR_POSTALCODE})}", 
            } 
         ], 
         "Contact":{ 
            "FamilyName":"${__eval(${STR_FAMILYNAME})}", 
            "GivenName":"${__eval(${STR_GIVENNAME})}", 
            "EmailAddress":"${__eval(${STR_EMAILADDRESS})}", 
            "NamePrefix":"${__eval(${STR_NAMEPREFIX})}", 
            "LanguagePreference":"${__eval(${STR_LANGUAGEPREFERENCE})}", 
            "WorkPhone":"${__eval(${STR_WORKPHONE})}", 
         } 
      } 
   } 
}

清单 3 中的 JSON 实体只包含硬编码的数据。相反,清单 4 中的模板只包含引用变量的名称,因此,任何 JMeter 测试计划均可以使用模板。实际数据被单独存储在 CSV 数据文件中,咱们将在 下一节 讨论它。

请注意,清单 4 中的 JSON 为每一个已定义的替代变量调用了 JMeter __eval() 函数。增长的这一步骤使得在运行时执行 JMeter 脚本的时候能够对变量进行计算。

图 2 和图 3 显示了如何在 JMeter 测试脚本中指定 JSON 实体模板文件。图 2 显示了 HTTP Request 控制面板:

图 2. 在测试中使用一个模板文件的内容

JMeter HTTP Request 控制面板的屏幕截图,配置该面板,以便在测试中使用某个模板文件的内容

在图 2 的示例中,CUSTOMER_JSON 变量表示整个JSON Customer 元素。该变量被封闭在 _eval() 函数中,显示为 HTTP 请求的主体(在 Parameters 选项卡上的 Send Parameters With the Request 标题下)。而后,在图 2 中,请求主体是 ${_eval(${CUSTOMER_JSON})}。

在 User Parameters 控制面板中定义 CUSTOMER_JSON 变量,如图 3 所示:

图 3. 在 JMeter 脚本中读取 JSON 模板文件

用于 JMeter 测试的 User Parameters 控制面板的屏幕截图,显示了该脚本如何读取一个 JSON 模板文件

在图 3 中,CUSTOMER_JSON 变量被设置为 FileToString(),并使用指向 JSON 模板文件的路径做为参数。JSON 实体模板文件的全部内容都被读入 CUSTOMER_JSON 变量。所以,JSON 实体模板文件的内容是在运行时计算的,所定义的全部替代字符串都被翻译成为它们定义的数据。(下一节 将说明替代变量如何与实际数据相关联)。

由于 JMeter 的 JSON 实体模板文件对于 JMeter 测试脚本是外部文件,因此您能够将它们存储在一个单独的目录,好比 JMETER_HOME/tests/jsontemplates。当您访问 JMeter 测试计划中的某个 JSON 实体模板时,可指定相对于 JMeter BIN 目录的名称,例如:

../tests/jsontemplates/customer_template.json

您也能够将模板存储在 JMETER_HOME 目录之外的地方,在这种状况下,您必须提供绝对路径。

使用 CSV Data Set Config 元素的数据抽象

虽然将测试数据与 JMeter 测试计划分开在最初看起来像是执行了额外的工做,可是更简洁的测试中的分离结果也更容易管理。在须要修改测试时,就能够快速实现一些好处。某些数据可能仍然位于本地,存在于每一个测试计划中,但大多数的测试数据抽象到外部文件中 — 在属性文件(正如咱们前面讨论过的)或一个 CSV 数据配置文件中。所产生的测试套件更易于维护,并且在大多数状况下,不须要编辑 JMeter 测试计划就能够修改任何数据值。

JMeter 使​​用 CSV 文件存储以逗号分隔的数据行。JMeter 框架的 CSV Data Set Config 功能提供了一种在运行时动态读取 CSV 文件测试数据的方法。将测试数据存储为 CSV 另一个好处是,您能够存储多行表明多个数据对象/变量的数据,或循环处理的屡次迭代的数据。JMeter 2.3.4 及更高版本还支持提供一个 CSV 标题 做为文件的第一行。而后,使用标题的分隔字符串名称存储所定义的数据值。一般状况下,随后每一行的数据都表明循环的一次迭代。从这个意义上讲,该脚本主要是 “数据驱动的”,测试人员能够修改 CSV 文件中的数据,无需对 JMX 脚本进行任何更改。

测试人员还能够跨多个测试线程共享数据,并在多个 CSV 文件中存储测试数据。例如,若是有一个测试用一组用户凭据登陆,而后为该用户建立一个订单,那么您能够建立两个 CSV 文件:一个用于保存用户凭据,另外一个用于保存订单信息。有时候,可能须要建立多个 JMX 脚原本访问 CSV 文件。在这种状况下,您必须将 CSV 文件放在多个脚本均可以访问的位置。

在一个 CSV 文件内定义的迭代数据一般与变量名称有关联。您能够在标题中定义这些变量名称,用逗号分隔,而且它们一对一地与数据值的数量相匹配。当 JMeter 处理文件的每一行时,它会将适当的数据值分配给与该位置有关联的变量名称。清单 5 显示了样例 CSV 文件的内容:

清单 5. 样例 CSV 文件 (customer.csv)

"STR_TESTCASE","STR_CUSTOMERTYPE","STR_CUSTOMERNUMBER","STR_ORGNAME","STR_PHONE",
"STR_ADDRESSLINE1","STR_ADDRESSLINE2","STR_ADDRESSTYPE","STR_CITY","STR_COUNTRY",
"STR_STATE","STR_STATECODE","STR_POSTALCODE","STR_FAMILYNAME","STR_GIVENNAME",
"STR_EMAILADDRESS","STR_NAMEPREFIX","STR_LANGUAGEPREFERENCE","STR_WORKPHONE", 

"Testcase1","DIRECT","1234567890","IBM","999-999-9999","Tech Park One","","MAILING",
"Pune","India","Maharashtra","MH","411006","Gilra","Shalini","shagilra@in.ibm.com","Miss",
"EN_US","999-9999", 

"Testcase2","DIRECT","1234567891","IBM","999-999-9999","Tech Park One","","MAILING",
"Pune","India","Maharashtra","MH","411006","Prakash","Prem","premprakash@in.ibm.com",
"Mr","EN_US","999-9999", 

"Testcase3","DIRECT","1234567892","IBM","999-999-9999","550, Kings Street","","MAILING",
"Littleton","United States","MA","MA","1460-1250","Tuohy","Tom","tuohy@us.ibm.com","Mr",
"EN_US","999-9999",

在 JMeter 处理 清单 5 中的 CSV 文件时,对于第一次迭代,会将 Pune 分配给 STR_CITY 变量,将 India 分配给 STR_COUNTRY 变量,等等。而后,对接下来的两行/迭代执行一样的操做,但使用了在那些行上指定的值。当脚本运行的时候,所指定的变量加载并包含它们的值,直到它们被覆盖或脚本结束。为了不无心中覆盖了变量,请当心地命名变量。此外,当您调试 JMeter 脚本时,知道变量的起源在哪里很是重要,由于脚本自己没有定义该位置。在 CSV 文件中使用一致的变量名称命名惯例颇有帮助。

图 4 显示了如何在 CSV Data Set Config 控制面板中指定 CSV 文件:

图 4. 在 JMeter 中指定和读取一个 CSV 文件

JMeter CSV Data Set Config 控制面板的屏幕截图,该面板用于指定和读取某个 CSV 数据文件

在图 4 中,Filename 字段被设置为将被读取的 CSV 文件的相对路径。“Allow quoted data?” 值被设置为 true,由于 CSV 文件中的数据值用引号括了起来。“Recycle on EOF?” 选项被设置为 false,“Stop thread on EOF?” 选项被设置为 true,这将致使线程在到达文件结束(EOF)时中止。

使用 While Controllers 实现循环

在将测试数据分离成单独的 CSV Data Set Config 文件后,能够更容易地使用数据集在一组类似但独立的操做中进行迭代。JMeter 提供了 While Controller 等循环构造函数来帮助实现迭代。经过在循环构造函数中组织测试操做,您能够在一个 JMeter 测试计划中执行所需的所有数据驱动的测试。

这种方法对于云测试颇有用,由于它解决了测试从多个访问角色或不一样数据集(正、负、边界值,等等)访问 API 的需求。利用循环,能够将一个 API 测试目标的全部测试排列都放在一个测试计划中,这使得编写测试用例的速度至少快了 20 倍。

图 5 显示了如何使用 While Controller 控制面板来告诉 JMeter 循环遍历全部 CSV 文件数据:

图 5. 循环遍历 CSV 文件中的全部数据

JMeter While Controller 控制面板的屏幕截图,该面板告诉 JMeter 循环遍历 CSV 文件中的全部数据

在图 5 中,Condition(函数或变量)字段被设置为 jexl() 函数。此函数比较了来自 CSV 数据文件的变量与 EOF,当 CSV 文件中没有其余数据行时,它会告诉 JMeter 退出循环。条件能够是最终计算结果为 false 的任何变量或函数。

使用 BeanShell 编写脚本

经过使用 BeanShell 脚本语言,您能够在 JMeter 脚本中进行 Java 编程。例如,在脚本必须操纵用 JMeter 的 Regular Expression Extractor 捕获的变量的状况下,BeanShell 脚本颇有用。BeanShell 脚本执行传递给它的程序,并在运行时返回结果。

在某些云应用程序中,使用了从 API 命令返回的响应数据(多是 JSON 格式的)做为对另外一个 API 命令的请求数据,其中进行了一些修改。使用未知的动态数据可能很是棘手和困难,除非您能够在脚本中使用编程。利用 BeanShell 脚本,经过使用 JSONObject 类库,您能够在运行时操纵 JSON 有效负载或读取 JSON 有效负载的属性值。为了在 JMeter 脚本中使用 JSONObject,经过将 JAR 复制到 JMETER_HOME/lib 文件夹,能够在 JMeter 的类路径中包含 java json.jar。

您能够针对不一样目的,经过多种方式定义和使用 BeanShell 脚本。利用 BeanShell PreProcessor 或 PostProcessor,能够在采样器执行以前或以后应用 JMeter BeanShell Sampler 中的一段代码。利用 BeanShell Assertion,能够进行条件测试,好比 JMeter 变量是否保存了一个预期值。

定义并使用 BeanShell 脚本的通常步骤是:

  1. 在 JMeter 中,建立一个 BeanShell Listener、一个 BeanShell PreProcessor、一个 BeanShell PostProcessor,或 BeanShell Sampler。
  2. 在 BeanShell 脚本中使用 vars.get("variable") 得到变量。
  3. 使用 Java 编程语言来处理 BeanShell 脚本。
  4. 在 BeanShell 脚本中,使用 vars.put("variable") 将处理后的变量放回指定的 JMeter 变量(这能够是一个现有变量或一个新变量)。

清单 6 中的样例 BeanShell 脚本修改了嵌套在 清单 3 中的 JSON 的第三层的 GivenName 和 WorkPhone 值:

清单 6. 使用 BeanShell 脚本修改两个 JSON 值

custPayload= vars.get("testResp");
org.json.JSONObject custJSON= new org.json.JSONObject(custPayload);

if (custJSON.has("Customer") && custJSON.get("Customer")!= null) {
   org.json.JSONObject contactJSON = custJSON.getJSONObject("Customer").getJSONObject(
   "Organization").getJSONObject("Contact");
   contactJSON.put("GivenName", "Shalini");
   contactJSON.put("MobilePhone", "9923406159");
}
vars.put("updatedCustPayload", custJSON.toString());

如今,请求能够在 API UPDATE 命令中使用 ${updatedCustPayload} 变量。

能够经过其余许多方式使用 BeanShell 脚原本操纵 JMeter 变量或 JSON 数据 — 好比执行算术运算、提取变量的值,或以一个特定变量的值替换另外一个变量的值。整体而言,BeanShell 可用于执行 JMeter 不直接支持的任务。

使用 Module Controller 模块化可重用的片断

一 个复杂的测试计划中包括许多变量和函数,这很常见。一般状况下,这些片断在其余测试计划中也被使用超过一次或两次。在这种状况下,能够将这些片断拆分为可 以在其余地方重用的若干个子模块,以便减小维护工做量。而后,若是一个可重用的功能在将来须要进行修改,您只须要在某个地方修改它。

JMeter Module Controller 是一种机制,能够在运行时在目前的测试计划中替换测试计划片断。片断能够位于任何线程组或在 WorkBench 上。Module Controller 使用的任何片断都必须具备唯一的名称,由于该名称被用于在从新加载一个测试计划时找到目标控制器。

图 6 的示例显示了放置 Module Controller 的位置,以及在脚本中调用的模块:

图 6. Module Controller 的放置和它指向的模块

JMeter 测试计划的屏幕截图,在该计划中,Module Controller 是在 Customer Service 模块的 Login 和 Logout 例程之间建立的,而且控制器所指向的 Register Customer 模块是在 WorkBench 中建立的

在图 6 所示的测试计划中,Register Customer 被定义为一个单独的模块,被放置在 WorkBench 部分中。Module Controller (Module Controller - Register Customer) 被放置在 Login User 例程的后面和 Logout 的前面,指向 Register Customer 模块。在运行脚本时,在 Module Controller 的所在位置上,Module Controller 替代了测试计划中的 Register Customer 模块。

图 7 显示了如何在脚本中定义一个 Module Controller:

图 7. Module Controller 指向在 WorkBench 中定义的简单控制器

指向 WorkBench 中定义的简单控制器的 JMeter Module Controller 的屏幕截图

在图 7 中,从 Module To Run 字段的下拉列表选中 Register Customer 模块,该列表列出了全部可用模块。

当可重用的组件在同一个脚本(JMX 文件)中被重用时,可使用 Module Controller。若是在其余脚本中也将使用可重用的片断,那么能够将片断移到一个单独的 JMX 文件中,并使用 Include Controller 调用它,在下一节中将会详细叙述该操做。

使用 Include Controller 包括可重用的 JMeter 文件

JMeter 的 Include Controller 提供了一个占位符,其中一个 JMX 文件(父 脚本)能够调用另外一个 JMeter 脚本(子 脚本)。经过将脚本拆分为较小的脚本或模块/例程,并使用这些子例程构创建一个测试套件,能够在脚本中实现模块化,以加强可理解性和可重用性。使用 Include Controller 分离可重用的代码片断或先决条件(如 Login User 和 Register User),帮助更好地管理和维护脚本。

要使用 Include Controller,首先须要建立一个子 JMX 文件,其中包含一个可重用的例程(如 Login Admin User)。图 8 显示了一个示例子脚本,经过 Include Controller 能够将它包含在父脚本中:

图 8. 子 JMX 文件 (LoginUser.jmx)

子脚本 (LoginUser.jmx) 的屏幕截图

图 8 中的子脚本定义了一个测试计划,其中包含一个采样程序和一个 Login User 的 HTTP 请求。在 HTTP 请求中,协议、服务器名称和其余设置所使用的变量是在父脚本中定义的。

下一步是在父脚本中想要调用子脚本的地方添加一个 Include Controller,并将 Include Controller 指向子 JMX 文件的路径。图 9 显示了一个在父脚本中定义的 Include Controller:

图 9. 在父 JMX 文件中添加一个 Include Controller

父脚本的 Include Controller 的屏幕截图

在图 9 所示的 Include Controller 控制面板中,Filename 字段存储了子 JMX 文件(在本例中是 Login_User.jmx)的相对路径。

子 JMX 文件能够访问在 Include Controller 中能够访问的父 JMX 文件中定义的任何变量,而且父 JMX 文件可使用在子 JMX 文件中定义的变量。

使用正则表达式

当 JSON 是 REST 操做的请求负载时,响应要么是 JSON 格式的,要么是字符串表示形式。在完成操做后,必须提取响应字符串、错误代码和错误消息字符串,以验证特性是否如预期般运做。您可使用 JMeter 的正则表达式特性来提取变量中的响应数据。

图 10 显示了如何在 JMeter 的 Regular Expression Extractor 控制面板中建立一个简单的正则表达式提取器:

图 10. 简单的正则表达式提取器

JMeter 中的简单的正则表达式提取器的屏幕截图

在图 10 中,Reference Name (在本例中是 User)存储使用正则表达式语法提取的值。在 Regular Expression 字段中,您为针对响应运行的正则表达式提供了语法(在 图 11 中,该语法是 \"LoginName\":\"(.*?)\"),以提取特定数据。JSON 响应数据的经常使用正则表达式语法示例包括:

  • \s*(.+)\s* 用于提取整个响应字符串
  • \"LoginName\":\"(.*?)\" 用于提取 "LoginName":"abc@testmail.com"
  • \"CustomerId\":(\d+) 用于提取 "CustomerId":2000006

在 图 10 的 Template 字段中,$1$ 表示参考变量的分组。Default Value 字段用于在正则表达式不匹配的状况下为调试提供默认值。根据实践,只有在脚本阶段添加和测试正则表达式模式的时候才声明默认值。

扩展功能 JMeter 脚本以执行性能测试

理想状况下,任何应用程序的性能测试都包括两个场景:用户数量尖峰和系统负载的增长。若是现有的功能测试场景涵盖了基本的 REST 函数,那么很容易扩展和更新它,从而测试托管在云基础架构上的 REST 服务的性能。您能够修改应该被发送到每一个服务器的请求的数量,对应用程序进行加载测试。您能够经过配置使用适当循环迭代的上升期 来控制请求的数量。

例如,假设您有一个测试计划,基于如下算法执行和验证一组简单的 REST 原则:

  1. 执行一个 HTTP POST 方法,以建立一个客户对象。
  2. 执行一个 HTTP GET 方法,以验证客户对象的建立。
  3. 执行一个 HTTP PUT 方法,以验证客户对象的修改。
  4. 执行一个 HTTP DELETE 方法,以验证客户对象已被删除。

您能够将简单的功能测试计划(最初为 RESTful API 功能测试场景而设计)调整为一个以云环境中部署的服务器为目标的性能测试脚本。

  1. 导航到测试计划的 Thread Group 控制面板,如图 11 所示:

    图 11. 图 11. 性能仿真设置示例

    JMeter Thread Group 控制面板的屏幕截图,显示了性能仿真设置
  2. 在 Number of Threads (users) 字段中输入 ${Thread}。Thread 变量的值(将在步骤 5 中配置它)设置了可用线程的数量,以反映有多少虚拟用户在访问服务器。
  3. 在 Ramp-Up Period (in seconds) 字段中输入 ${RampUp}。RampUp 变量的值(将在步骤 5 中配置它)肯定了分发请求的速度(这基于在步骤 1 中定义的线程数量)。例如,若是有 10 个线程,加速上升时间为 100 秒,那么每一个线程在前一个线程启动后 10 秒开始,有 100 秒的总时间可让测试加快速度。
  4. 在 Loop Count 字段中输入 ${Loop}。Loop 变量的值(将在步骤 5 中配置它)肯定了测试计划执行的次数。
  5. 导航到 User Defined Variables 控制面板,并将 Thread、RampUp 和 Loop 定义为全局变量,如图 12 所示。为每一个要模拟的负载分配适当的变量值。

    图 12. 性能测试模拟变量

    User Defined Variables 控制面板的屏幕截图,显示了样例性能测试仿真变量

    在图 12 中,Loop 值被设置为 5,RampUp 值被设置为 50,Loop 值被设置为 2。

图 13 显示了基于图 12 中已配置的变量值,对在云应用程序中部署的其中一个节点服务器执行 JMeter 的结果:

图 13. 性能测试结果

屏幕截图显示了对已在云应用程序中部署的某个节点服务器运行 JMeter 测试的结果,基于图 12 中定义的配置变量

图 13 显示了发送到服务器的并发请求的沉重负载,以模拟性能测试条件。

扩展功能 JMeter 脚本,以执行可靠性测试

可靠性测试 是经过在多组特定条件下连续运行一组脚本,确保总体系统稳定性的一种方式。可靠性测试的结果应该与压力测试、功能测试和网络特性测试的结果一块儿查看。

与性能测试同样,您能够将执行和验证一组简单的 REST 原则的测试计划转换为一组合适的可靠性测试脚本,以肯定云实例上运行的任何产品或特性的稳定性。

可靠性测试的一个重要方面是,肯定在连续多日运行一个脚本的过程当中是否发生故障。选中 Thread Group 控制面板的 Forever 复选框,如图 14 所示,让线程能够一直运行,直到测试失败或脚本被强行中止:

图 14. JMeter 脚本的可靠性设置

JMeter Thread Group 控制面板的屏幕截图,包含已为可靠性测试选中的 Forever 复选框

在配置了可靠性测试设置后,运行测试几天,经过 JMeter 结果图或经过 JMeter 提供的推断选项连续监测结果。

结束语

本文向您介绍了使用 JMeter 来有效地测试基于云的应用程序的方法。文章并无进行详尽的讨论,咱们鼓励您尝试使用其余技术来改进 JMeter 中的自动化任务实现。JMeter Wiki是继续您的探索的一个好地方。

相关文章
相关标签/搜索