当前位置: 首页 > 质量专栏 > 软件测试工具Gatling Feeders软件数据驱动测试:CSV、JSON、JDBC与Redis数据源集成
软件测试工具Gatling Feeders软件数据驱动测试:CSV、JSON、JDBC与Redis数据源集成
2025-11-25 作者cwb 浏览次数58

Gatling中Feeders的使用,这些Feeders用于在性能测试中提供数据驱动能力。我们将覆盖CSV、JSON、JDBC和Redis数据源,并提供详细的代码示例和解释。


1. Feeders概述

Feeders在Gatling中用于为虚拟用户提供测试数据。它们是一种数据源,可以在模拟运行过程中为每个用户提供不同的数据。Feeder本质上是一个迭代器,它返回键值对,这些键值对可以注入到Session中。


2. CSV Feeder

CSV Feeder从CSV文件中读取数据。每行是一个记录,每个记录是一个Map,键是CSV的列名。

基本用法

假设我们有一个名为users.csv的文件,内容如下:


csv

id,username,password

1,user1,pass1

2,user2,pass2

3,user3,pass3


在Gatling中,我们可以这样使用:


scala

val csvFeeder = csv("users.csv").circular


val scn = scenario("CSV Feeder Test")

  .feed(csvFeeder)

  .exec(http("Get user by ID")

    .get("/user/${id}")

    .check(status.is(200)))


循环策略

circular: 循环使用数据,当到达文件末尾时,从第一行重新开始。

random: 随机选择一行。

shuffle: 打乱顺序然后循环。

queue: 按顺序使用,每个用户获取下一行,如果到达末尾则失败。


3. JSON Feeder

JSON Feeder从JSON文件中读取数据。JSON文件应该是一个数组,每个元素是一个对象。

基本用法

假设我们有一个名为users.json的文件,内容如下:


json

[

  {

    "id": 1,

    "username": "user1",

    "password": "pass1"

  },

  {

    "id": 2,

    "username": "user2",

    "password": "pass2"

  }

]


在Gatling中,我们可以这样使用:


scala

val jsonFeeder = jsonFile("users.json").circular


val scn = scenario("JSON Feeder Test")

  .feed(jsonFeeder)

  .exec(http("Get user by ID")

    .get("/user/${id}")

    .check(status.is(200)))


4. JDBC Feeder

JDBC Feeder从数据库中读取数据。需要配置数据库连接。

基本用法

首先,在build.sbt中添加数据库驱动依赖,例如MySQL:


scala

libraryDependencies += "mysql" % "mysql-connector-java" % "8.0.33"


然后,在Gatling中配置JDBC Feeder:


scala

val jdbcFeeder = jdbcFeeder(

  "jdbc:mysql://localhost:3306/test",

  "username",

  "password",

  "SELECT id, username, password FROM users"

)


val scn = scenario("JDBC Feeder Test")

  .feed(jdbcFeeder)

  .exec(http("Get user by ID")

    .get("/user/${id}")

    .check(status.is(200)))


5. Redis Feeder

Redis Feeder从Redis中读取数据。Gatling不直接支持Redis Feeder,但我们可以通过编写自定义Feeder来实现。

自定义Redis Feeder

首先,添加Redis客户端依赖,例如lettuce-core:


scala

libraryDependencies += "io.lettuce" % "lettuce-core" % "6.2.4.RELEASE"


然后,我们可以创建一个自定义Feeder:


scala

import io.lettuce.core._

import io.lettuce.core.api.sync._

import scala.collection.JavaConverters._


def redisFeeder(redisUri: String, keyPattern: String): Feeder[String] = {

  val redisClient = RedisClient.create(redisUri)

  val connection = redisClient.connect()

  val commands = connection.sync()


  // 假设我们从Redis中获取一个列表,然后循环使用

  val keys = commands.keys(keyPattern).asScala.toList

  val iterator = keys.iterator


  feeder[String] { _ =>

    if (iterator.hasNext) {

      val key = iterator.next()

      // 这里我们假设存储的是String,根据实际情况调整

      val value = commands.get(key)

      Map("redisKey" -> key, "redisValue" -> value)

    } else {

      Map.empty

    }

  }.circular

}


// 使用自定义Redis Feeder

val redisFeeder = redisFeeder("redis://localhost:6379", "user:*")


val scn = scenario("Redis Feeder Test")

  .feed(redisFeeder)

  .exec(http("Get user by ID")

    .get("/user/${redisValue}")

    .check(status.is(200)))


注意:这只是一个示例,实际使用时需要根据Redis中数据的存储结构和需要的数据进行调整。


6. 自定义Feeder

如果内置的Feeder不满足需求,我们可以自定义Feeder。自定义Feeder是一个返回Iterator[Map[String, T]]的函数,其中T是任何类型。

示例:随机生成数据


scala

val randomEmailFeeder = Iterator.continually(

  Map("email" -> (s"user${java.util.UUID.randomUUID()}@example.com"))

)


val scn = scenario("Random Email Feeder Test")

  .feed(randomEmailFeeder)

  .exec(http("Register user")

    .post("/register")

    .formParam("email", "${email}")

    .check(status.is(200)))


7. 数据源策略与性能考虑

循环方式:保证每个虚拟用户都能获得唯一的数据,避免重复。

数据量:如果测试需要大量数据,确保数据源能够快速提供数据,避免成为瓶颈。

连接管理:对于JDBC和Redis等外部数据源,注意连接的管理和释放,避免资源泄露。


8. 综合示例

下面是一个综合使用多种Feeder的示例:


scala

import io.gatling.core.Predef._

import io.gatling.http.Predef._

import scala.concurrent.duration._


class FeederSimulation extends Simulation {


  val httpProtocol = http

    .baseUrl("http://localhost:8080")

    .acceptHeader("application/json")


  // CSV Feeder

  val csvFeeder = csv("users.csv").queue


  // JSON Feeder

  val jsonFeeder = jsonFile("users.json").random


  // JDBC Feeder

  val jdbcFeeder = jdbcFeeder(

    "jdbc:mysql://localhost:3306/test",

    "user",

    "password",

    "SELECT id, username FROM users WHERE status = 'active'"

  )


  // 自定义Redis Feeder(假设我们已经定义了上面的redisFeeder函数)

  val redisFeeder = redisFeeder("redis://localhost:6379", "user:*")


  val scn = scenario("Multiple Feeder Test")

    .feed(csvFeeder)

    .feed(jsonFeeder)

    .feed(jdbcFeeder)

    .feed(redisFeeder)

    .exec(http("Complex Request")

      .post("/complex")

      .formParam("csvId", "${id}")  // 来自CSV

      .formParam("jsonUsername", "${username}")  // 来自JSON

      .formParam("jdbcId", "${id}")  // 来自JDBC

      .formParam("redisKey", "${redisKey}")  // 来自Redis

      .check(status.is(200)))


  setUp(

    scn.inject(

      rampUsers(100) during (10 seconds)

    )

  ).protocols(httpProtocol)

}


注意:在实际测试中,不建议同时使用多个Feeder,除非有特殊需求。通常一个测试场景使用一种数据源即可。


9. 总结

Gatling的Feeders提供了灵活的数据驱动测试能力。我们可以根据测试需求选择合适的数据源和策略。对于不满足内置Feeder的情况,我们可以通过自定义Feeder来扩展。


文章标签: 测试工具 软件测试 测试平台 性能测试 测试框架 大数据测试 软件测试用例 并发压力测试
咨询软件测试