性能文章>【译】如何使用 JUnit/Maven 进行简单而准确的性能测试>

【译】如何使用 JUnit/Maven 进行简单而准确的性能测试转载

2年前
361958

本文将演示在JUnit、Zerocode和 IDE(IntelliJ、Eclipse 等) 的帮助下,我们如何轻松地进行性能测试。

内容将涵盖以下几个方面。

  • 常见测试问题和解决方案

  • JUnit + Zerocode-TDD开源框架

  • 使用示例

  • 报告和故障测试日志

您可以  在 GitHub中找到演示性能测试项目。

 

1. 常见测试问题与解决方案

我们可以像使用JUnit进行单元测试一样轻松地进行性能测试。

有时,我们会在开发冲刺结束时保留性能测试记录,即更接近生产发布日期。然后,要求开发人员或性能测试人员(有时是专门的团队)从市场中选择一个独立的工具,并制作一些关于性能测试的精美报告

这意味着它是独立于常规构建完成的,并且产品或服务 API 的重要方面被遗漏或未正确完成。这无法为改进或修复产品中发现的潜在问题提供任何空间。

如何解决这个问题呢?就是CI 构建管道中进行这方面的测试,如果不是在每次提交/合并时定期进行,那么每晚构建应该就足够了。

2. 模拟或存根边界 API

我们模拟或存根位于被测应用程序外部的边界 API非常重要。否则,我们将在其他应用程序上产生不必要的负载,并生成错误的分析报告。

下面的剪辑显示,你可以多么轻松地通过 WireMock 进行外部服务虚拟化,而无需编写 Java 代码,即只需为模拟 API 放置JSON 有效负载

我们可以 在Github中找到这个api-mock-maker 。

图片标题

3. 我们如何将性能测试与 CI 构建集成?

在传统方法中,我们花了太多时间来理解一个工具并让该工具工作,因为有些不是 IDE友好的,甚至不是基于Maven/JUnit的。

有时,将我们的性能测试工具指向技术堆栈中的任何位置并不容易,例如,通过公司代理指向REST 端点、数据库服务器、SOAP 端点或 Kafka 主题或 SSL 主机。

这使我们很难隔离问题,不确定我们的应用程序 API 是否表现不佳,还是只有下游系统表现不佳

让我们解释一下它的含义:

例如,我们刚刚测试了 GET API 的性能, "/api/v1/loans/LD1001" 使用独立工具指向 URL,发现响应 delay 非常高。然后我们(开发团队)倾向于将其归咎于数据库,理由是 OracleDB服务器在处理并行负载时非常慢。

4. 你如何证明你的 API 并不慢?

现在,我们希望我们有一种机制或工具,通过将我们的性能测试工具直接指向 数据库、Kafka主题等 ,将这个问题与我们的应用程序隔离开来。

因为(作为开发人员)我们知道哪些 SQL 查询被触发到数据库以获取结果。

或者我们可以绕过应用程序API 处理层直接从中获取数据的主题/分区名称。

这可以 有意义地证明我们的观点并产生证据。

重用现有 JUnit 的负载/应力生成测试

理想情况下,我们需要一个自定义的 JUnit 负载运行器 ,重用我们现有的  JUnit tests (e2e 集成测试、功能测试或组件测试,因为它们中的大多数都在幕后使用 JUnit)来为目标应用程序生成负载或压力。

幸运的是,我们有这个现成的跑步者可用:

负载运行器如下所示:

应该在哪里 load_config.properties 保存以下属性:

 

在这里,我们有80 个用户要在80 秒内加速 (每个用户在一秒的间隔内触发测试),这要运行两次(循环 = 2),总共有160 个并行用户 触发 请求,每个大约在一个-第二个差距。

@TestMapping表示

上面的“ testXyz” 方法 AnyTest 具有所需的测试“断言”

一旦负载运行完成,我们应该能够得出如下统计数据:

触发的测试总数

160

通过的测试总数

140

失败的测试总数

20

请求之间的平均延迟(以秒为单位)

1

平均响应时间延迟(秒)

5

理想情况下,可以按需绘制更多统计信息,因为 LoadRunner 会生成包含以下(或更多)数据类型的 CSV/电子表格:

测试类名

测试方法

唯一测试 ID

请求时间戳

响应延迟

响应时间戳

结果

你现有的测试

一个测试

测试ID-001

2018-05-09T21:31:38.695

165

2018-05-09T21:31:38.860

通过

你现有的测试

一个测试

测试ID-002

2018-05-09T21:31:39.695

169

2018-05-09T21:31:39.864

失败的

当然,这些是基础知识,你应该能够使用任何给定的工具进行所有这些测试。 

5.同时为每个用户触发不同类型的请求

  • 如果我们想逐渐增加或减少被测应用程序的负载怎么办?

  • 如果我们的一位用户想要启动 POST,然后 GET 怎么办?

  •  如果另一个用户每次触发请求时都在动态更改有效负载怎么办?

  • 如果另一个用户继续触发 POST,然后是 GET,然后是 PUT,然后是 GET 以验证所有 CRUD 操作是否正常?依此类推,这里的每个场景都在断言 它们相应的测试结果。

现在我们肯定需要一种机制来重用你现有的测试,因为我们可能已经有测试用例在您的常规 e2e 测试中执行这些操作(顺序和独立,但不是并行)。

你可能需要像下面这样的 JUnit 运行器,它可以创建类似生产的负载,并行用户触发不同类型的请求并为每个调用断言它们。转到演示存储库以查看此操作。

6. Junit + Zerocode TDD 开源测试库 

 

基本上,你结合这两个库JUnit 和 Zerocode来生成负载/压力:

  1. JUnit  (非常流行,开源,在 Java 社区中常用)

  2. Zerocode  (由于 BDD/TDD 自动化的简单断言而新并越来越受欢迎)

最近,我们的团队在 JUnit 中使用了开源 Maven 库 Zerocode(参见 GitHub 上的 README),这使得性能测试变得轻而易举。

我们可以创造性地思考许多场景,并很快准备好进行负载测试。当然,我们不断将这些测试添加到负载回归包中,同时为CI 构建做好准备。

优点是我们也能够重用JMeter中的测试子集来生成业务(非开发人员)使用的负载。业务用户需要基于 UI 的工具来选择特定的业务场景并运行。

7. 示例用法

浏览示例性能测试 repo 性能测试项目 

我们可以在这里找到工作示例。

8. 报告和阅读失败的测试日志

当你在 CSV 文件中生成测试运行统计信息时,你可以使用框架生成的数据集绘制图表或图形。

该框架生成两种报告(请参阅此处的示例负载测试报告):

1) CSV 报告(在 target 文件夹中)

2)交互式模糊搜索和过滤HTML报告 (在 target 文件夹中)

你可以通过许多参数跟踪失败的测试,但最容易的是通过其uniquestep-correlation-id

最重要的是,有时测试会失败,我们需要知道特定请求实例失败的原因。在 CSV 报告(以及 HTML)中,你将找到一列 correlationId ,其中包含与每次运行的测试步骤相对应的唯一 ID。只需选择此 ID 并在 target/zerocode_rest_bdd_logs.log 文件中搜索 - 您将获得匹配的全部详细信息 TEST-STEP-CORRELATION-ID, 如下所示:

2022-10-23 21:55:39,865 [main] INFO org.jsmart.zerocode.core.runner.ZeroCodeMultiStepsScenarioRunnerImpl - 
--------- TEST-STEP-CORRELATION-ID: b3ce510c-cafb-4fc5-81dd-17901c7e2393 ---------
*requestTimeStamp:2018-06-23T21:55:39.071
step:get_user_details
url:https://api.github.com:443/users/octocat
method:GET
request:
{ } 
--------- TEST-STEP-CORRELATION-ID: b3ce510c-cafb-4fc5-81dd-17901c7e2393 ---------
Response:
{
  "status" : 200,
  "headers" : {
    "Server" : [ [ "GitHub.com" ] ],
    "Status" : [ [ "200 OK" ] ]
  },
  "body" : {
    "login" : "octocat",
    "id" : 583231,
    "updated_at" : "2018-05-23T04:11:18Z"
  }
}
*responseTimeStamp:2018-06-23T21:55:39.749 
*Response delay:678.0 milli-secs 
---------> Assertion: <----------
{
  "status" : 200,
  "body" : {
    "login" : "octocat-REALLY",
    "id" : 583231,
"type" : "User"
  }
} 
-done-


java.lang.RuntimeException: Assertion failed for :- 

[GIVEN-the GitHub REST end point, WHEN-I invoke GET, THEN-I will receive the 200 status with body] 
|
|
+---Step --> [get_user_details] 

Failures:
--------- 
Assertion path '$.body.login' with actual value 'octocat' did not match the expected value 'octocat-REALLY'
 

吞吐量结果可以绘制如下:

图片标题

当然,你也可以使用 Excel 或任何其他方便的工具绘制折线图、饼图和 3D 图表。

原文作者:Nirmal Chandra

点赞收藏
一只菌

简简单单,认真生活。

请先登录,查看5条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步
8
5