Redis 协议
概述
Redis 协议支持为 Ryze 测试框架提供了与 Redis 数据库进行交互的能力。支持字符串、哈希、列表、集合等多种数据类型操作,以及缓存测试、分布式锁测试等常见 Redis 应用场景。
依赖引入
Redis 协议支持内置在核心模块中,无需额外依赖:
xml
<dependency>
<groupId>io.github.xiaomisum</groupId>
<artifactId>ryze</artifactId>
<version>6.0.1</version>
</dependency>
Redis 配置元件
Redis 数据源:使用该组件配置 Redis 数据源,用于 Redis 处理器\取样器引用。
YAML 配置方式
yaml
# Redis 数据源配置
testclass: redis # 配置元件类型
ref_name: redis_source # 数据源名称
config: # 可简化填写,无需config关键字,直接将配置内容至于首层
url: 'redis://127.0.0.1:6379/0' # Redis连接URL
timeout: 5000 # 连接超时时间,毫秒
max_total: 10 # 连接池最大连接数
max_idle: 5 # 连接池最大空闲连接数
min_idle: 1 # 连接池最小空闲连接数
JSON 配置方式
json
{
"testclass": "redis",
"ref_name": "redis_source",
"config": {
"url": "redis://127.0.0.1:6379/0",
"timeout": 5000,
"max_total": 10,
"max_idle": 5,
"min_idle": 1
}
}
Redis 处理器
前置处理器
前置处理器在主要测试之前执行,常用于准备测试数据或清理缓存。
yaml
testclass: redis # redis 前置处理器类型
config: # 处理器配置
datasource: redis_source # 数据源,必须先定义数据源
command: SETEX # Redis命令
args: # 命令参数
- test:user:1
- 3600
- '{"name":"测试用户","age":25}'
后置处理器
后置处理器在主要测试之后执行,常用于清理测试数据。
yaml
testclass: redis # redis 后置处理器类型
config: # 处理器配置
datasource: redis_source # 数据源,必须先定义数据源
command: DEL # Redis命令
args: # 命令参数
- test:user:1
- test:list
Redis 取样器
YAML 配置方式
yaml
title: 标准Redis取样器
testclass: redis # 取样器类型
config: # 取样器配置
datasource: redis_source # 数据源,必须先定义数据源
command: GET # Redis命令
args: # 命令参数
- test:user:1
JSON 配置方式
json
{
"title": "Redis字符串操作",
"testclass": "redis",
"config": {
"datasource": "redis_source",
"command": "HGETALL",
"args": [
"user:profile:123"
]
}
}
常见问题
- 连接超时问题:检查 Redis 服务是否正常运行,网络连接是否畅通
- 认证失败:确保 URL 中包含正确的用户名和密码
- 数据库选择:URL 中的数字表示数据库编号(0-15)
- 内存不足:检查 Redis 内存使用情况,适当调整 maxmemory 配置
配置优先级
配置项的优先级为:取样器配置 > Redis 默认配置
Java API 示例
基础 Redis 操作
java
import static io.github.xiaomisum.ryze.MagicBox.*;
public class RedisApiExample {
public void setupRedisDataSource() {
// 配置 Redis 数据源
redisDatasource("redisDefault", datasource -> datasource
.url("redis://localhost:6379/0")
.timeout(5000)
.maxTotal(10)
.maxIdle(5)
.minIdle(1)
);
}
public void testStringOperations() {
// 字符串操作
Result setResult = redis("设置用户缓存", builder -> builder
.datasource("redisDefault")
.command("SETEX")
.args("user:123", "3600", "张三")
);
Result getResult = redis("获取用户缓存", builder -> builder
.datasource("redisDefault")
.command("GET")
.args("user:123")
);
assertThat(getResult.getResponseBody()).isEqualTo("张三");
}
public void testHashOperations() {
// 哈希操作
redis("设置用户信息", builder -> builder
.datasource("redisDefault")
.command("HMSET")
.args("user:info:123",
"name", "李四",
"age", "30",
"city", "北京")
);
Result result = redis("获取用户信息", builder -> builder
.datasource("redisDefault")
.command("HGETALL")
.args("user:info:123")
);
// 验证结果
assertThat(result.extract("$.name")).isEqualTo("李四");
assertThat(result.extract("$.age")).isEqualTo("30");
}
}
完整 Redis 测试套件
java
import static io.github.xiaomisum.ryze.MagicBox.*;
public class RedisTestSuite {
public void redisCacheTestSuite() {
suite("Redis缓存测试套件", builder -> {
// 配置 Redis 默认设置
builder.configure(configure -> configure
.redis(redis -> redis
.ref("redisDefault")
.url("redis://localhost:6379/0")
.timeout(5000)
.maxTotal(10)
.maxIdle(5)
.minIdle(1)
)
);
builder.children(children -> {
// 前置处理:清理测试数据
children.redisPreprocessor("清理测试数据", preprocessor -> preprocessor
.datasource("redisDefault")
.command("FLUSHDB")
);
// 测试1:字符串缓存
children.redis("设置用户缓存", redis -> redis
.datasource("redisDefault")
.command("SETEX")
.args("test:user:1", "3600", "{\"name\":\"测试用户\",\"age\":25}")
.assertion(assertion -> assertion
.responseBody("OK")
)
);
// 测试2:获取缓存
children.redis("获取用户缓存", redis -> redis
.datasource("redisDefault")
.command("GET")
.args("test:user:1")
.assertion(assertion -> assertion
.json("$.name", "测试用户", "==")
.json("$.age", 25, "==")
)
);
// 测试3:列表操作
children.redis("添加列表元素", redis -> redis
.datasource("redisDefault")
.command("LPUSH")
.args("test:list", "item1", "item2", "item3")
.assertion(assertion -> assertion
.responseBody("3")
)
);
// 后置处理:清理数据
children.redisPostprocessor("清理测试数据", postprocessor -> postprocessor
.datasource("redisDefault")
.command("DEL")
.args("test:user:1", "test:list")
);
});
});
}
}
Groovy API 示例
基础 Redis 操作
groovy
import static io.github.xiaomisum.ryze.MagicBox.*
// 配置 Redis 数据源
def setupRedis() {
redisDatasource("redisDefault") { datasource ->
datasource.url("redis://localhost:6379/0")
.timeout(5000)
.maxTotal(10)
.maxIdle(5)
.minIdle(1)
}
}
// 基本字符串操作
def stringOperations() {
// 设置值
redis("设置用户名") { builder ->
builder.datasource("redisDefault")
.command("SET")
.args("user:123:name", "张三")
}
// 获取值
def result = redis("获取用户名") { builder ->
builder.datasource("redisDefault")
.command("GET")
.args("user:123:name")
}
assert result.responseBody == "张三"
return result.responseBody
}
// 哈希操作
def hashOperations() {
// 设置哈希字段
redis("设置用户信息") { builder ->
builder.datasource("redisDefault")
.command("HMSET")
.args("user:info:123",
"name", "李四",
"age", "30",
"city", "北京",
"department", "技术部")
}
// 获取所有哈希字段
def result = redis("获取用户信息") { builder ->
builder.datasource("redisDefault")
.command("HGETALL")
.args("user:info:123")
}
// 返回结果为 Map 形式
return result.responseBody
}
// 列表操作
def listOperations() {
def listKey = "user:notifications:123"
// 添加通知
["欢迎加入", "系统更新", "新消息提醒"].each { notification ->
redis("添加通知: ${notification}") { builder ->
builder.datasource("redisDefault")
.command("LPUSH")
.args(listKey, notification)
}
}
// 获取所有通知
def result = redis("获取通知列表") { builder ->
builder.datasource("redisDefault")
.command("LRANGE")
.args(listKey, "0", "-1")
}
return result.responseBody
}
完整 Redis 测试脚本
groovy
import static io.github.xiaomisum.ryze.MagicBox.*
// Redis 缓存完整测试流程
suite("Redis缓存功能测试") { builder ->
// 配置 Redis 数据源
builder.configure { configure ->
configure.redis { redis ->
redis.ref("redisDefault")
.url("redis://localhost:6379/0")
.timeout(5000)
.maxTotal(10)
.maxIdle(5)
.minIdle(1)
}
}
builder.children { children ->
// 1. 数据准备:清理旧数据
children.redisPreprocessor("清理测试数据") { preprocessor ->
preprocessor.datasource("redisDefault")
.command("FLUSHDB")
}
// 2. 基本缓存操作
children.redis("设置用户基本信息") { redis ->
redis.datasource("redisDefault")
.command("SETEX")
.args("cache:user:001", "3600", """
{
"id": "001",
"name": "Groovy测试用户",
"email": "groovy@test.com",
"role": "developer",
"lastLogin": "2024-01-01T10:00:00Z"
}
""")
.assertion { assertion ->
assertion.responseBody("OK")
}
}
// 3. 验证缓存获取
children.redis("获取用户信息") { redis ->
redis.datasource("redisDefault")
.command("GET")
.args("cache:user:001")
.assertion { assertion ->
assertion.json("$.id", "001", "==")
.json("$.name", "Groovy测试用户", "==")
.json("$.role", "developer", "==")
.json("$.email", "groovy@test.com", "==")
}
}
// 4. 设置哈希类型数据
children.redis("设置用户配置") { redis ->
redis.datasource("redisDefault")
.command("HMSET")
.args("config:user:001",
"theme", "dark",
"language", "zh-CN",
"timezone", "Asia/Shanghai",
"notifications", "true")
.assertion { assertion ->
assertion.responseBody("OK")
}
}
// 5. 获取哈希数据
children.redis("获取用户配置") { redis ->
redis.datasource("redisDefault")
.command("HGETALL")
.args("config:user:001")
.assertion { assertion ->
assertion.json("$.theme", "dark", "==")
.json("$.language", "zh-CN", "==")
.json("$.timezone", "Asia/Shanghai", "==")
.json("$.notifications", "true", "==")
}
}
// 6. 列表操作:添加最近访问记录
children.redis("添加访问记录") { redis ->
redis.datasource("redisDefault")
.command("LPUSH")
.args("recent:user:001", "/dashboard", "/profile", "/settings")
.assertion { assertion ->
assertion.responseBody("3")
}
}
// 7. 获取最近访问记录
children.redis("获取访问记录") { redis ->
redis.datasource("redisDefault")
.command("LRANGE")
.args("recent:user:001", "0", "4")
.assertion { assertion ->
assertion.json("$.size()", 3, "==")
.json("$[0]", "/settings", "==")
.json("$[1]", "/profile", "==")
.json("$[2]", "/dashboard", "==")
}
}
// 8. 集合操作:添加权限
children.redis("添加用户权限") { redis ->
redis.datasource("redisDefault")
.command("SADD")
.args("permissions:user:001", "read", "write", "delete", "admin")
.assertion { assertion ->
assertion.responseBody("4")
}
}
// 9. 检查权限
children.redis("检查管理员权限") { redis ->
redis.datasource("redisDefault")
.command("SISMEMBER")
.args("permissions:user:001", "admin")
.assertion { assertion ->
assertion.responseBody("1")
}
}
// 10. 获取所有权限
children.redis("获取所有权限") { redis ->
redis.datasource("redisDefault")
.command("SMEMBERS")
.args("permissions:user:001")
.assertion { assertion ->
assertion.json("$.size()", 4, "==")
}
}
// 11. 清理:删除所有测试数据
children.redisPostprocessor("清理所有测试数据") { postprocessor ->
postprocessor.datasource("redisDefault")
.command("DEL")
.args("cache:user:001", "config:user:001",
"recent:user:001", "permissions:user:001")
}
}
}