Redis API——List功能实践与性能测试【Go版】

前文提到Go语言Redis API基本功能实践,以及后续的学习实践计划,由于总总原因耽搁了许久。终究是计划赶不上变化,学完Go语言操作Redis的常用功能之后,我打算把API实践、封装、简单性能测试场景放在一起写。

今天分享一下Redis list常用操作API的实践和性能测试,API的封装会放在文末。

常用API实践

LPush、LPush、LPush、LPush

关于API的功能,看名字就能够明白八九不离十。两组变量:左和右,推送和获取。

下面是我写了一个测试用例,均测试通过。

func TestPushPop(t *testing.T) {
	var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
	var key = "fun"
	var value = "abc"
	pool.LPush(key, value)
	pop := pool.LPop(key)
	assert.Equal(t, pop, value)
}

func TestPushPop2(t *testing.T) {
	var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
	var key = "fun"
	var value = "abc"
	pool.RPush(key, value)
	pop := pool.RPop(key)
	assert.Equal(t, pop, value)
}

XLen

这是一个获取list长度的API。测试用例如下:

func TestLen(t *testing.T) {
	var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
	var key = "fun"
	var value = "FunTester"
	len1 := pool.LLen(key)
	pool.LPush(key, value)
	len2 := pool.LLen(key)
	pool.LPop(key)
	len3 := pool.LLen(key)
	assert.Equal(t, len1, len3)
	assert.Equal(t, len1, len2-1)
}

LRange

获取某个范围的list数据,获取不会删除原始数据。用例如下:


func TestLRange(t *testing.T) {
	var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
	var key = "fun"
	var value = "FunTester"
	pool.Del(key)
	for i := 0; i < 10; i++ {
		pool.RPush(key, value+strconv.Itoa(i))
	}
	lRange := pool.LRange(key, 1, 3)
	for _, s := range lRange {
		log.Println(s)
	}
}

日志输出如下:

=== RUN   TestLRange
2022/08/13 17:13:31 Redis 连接成功
2022/08/13 17:13:31 确认连接成功!
2022/08/13 17:13:31 FunTester1
2022/08/13 17:13:31 FunTester2
2022/08/13 17:13:31 FunTester3
--- PASS: TestLRange (0.00s)

后来还有一些不常用的API(对于我来讲)这里就不过多展示了,下面进入性能测试环节。

性能测试

这里我只设计了一个性能测试用例,添加和删除。这次使用的时间作为限制条件的压测模型。

func TestPushPopPerf(t *testing.T) {
	var pool = redis.NewRdisPool("127.0.0.1:6379", base.Empty, 1)
	var key = "fun"
	var value = "FunTester"
	execute.ExecuteRoutineTime(func() {
		pool.LPush(key, value)
		pool.RPop(key)
	}, 20, 2)
}

控制台输出:

=== RUN   TestPushPopPerf
2022/08/13 17:22:40 Redis 连接成功
2022/08/13 17:22:40 确认连接成功!
2022/08/13 17:23:00 总耗时: 20.001000
2022/08/13 17:23:00 请求总数: 532029
2022/08/13 17:23:00 QPS: 26600.119994
--- PASS: TestPushPopPerf (20.00s)
PASS

API封装

下面是我针对Redis API的封装源码,大家有兴趣的可以阅读原文去我的仓库。

package redis

import (
	"funtester/base"
	"log"
)

// LPush
//  @Description: 从列表左边插入数据
//  @receiver r
//  @param key
//  @param value
//  @return int64
//
func (r RedisBase) LPush(key string, value interface{}) int64 {
	result, err := r.pool.LPush(key, value).Result()
	if err != nil {
		log.Printf("LPush:%s value: %s 失败\n", key, value)
		log.Println(err)
		return base.TestError
	}
	return result
}

// RPush
//  @Description:从列表右边插入数据
//  @receiver r
//  @param key
//  @param value
//  @return int64
//
func (r RedisBase) RPush(key string, value interface{}) int64 {
	result, err := r.pool.RPush(key, value).Result()
	if err != nil {
		log.Printf("RPush:%s value: %s 失败\n", key, value)
		log.Println(err)
		return base.TestError
	}
	return result
}

// LPop
//  @Description:  从列表左边删除第一个数据,并返回删除的数据
//  @receiver r
//  @param key
//  @param second
//  @return string
//
func (r RedisBase) LPop(key string) string {
	result, err := r.pool.LPop(key).Result()
	if err != nil {
		log.Printf("LPop:%s 失败\n", key)
		log.Println(err)
		return base.Empty
	}
	return result
}

// RPop
//  @Description:  从列表的右边删除第一个数据,并返回删除的数据
//  @receiver r
//  @param key
//  @param second
//  @return string
//
func (r RedisBase) RPop(key string) string {
	result, err := r.pool.RPop(key).Result()
	if err != nil {
		log.Printf("RPop:%s 失败\n", key)
		log.Println(err)
		return base.Empty
	}
	return result
}

// LLen
//  @Description: 返回列表的大小
//  @receiver r
//  @param key
//  @return int64
//
func (r RedisBase) LLen(key string) int64 {
	result, err := r.pool.LLen(key).Result()
	if err != nil {
		log.Printf("LLen :%s 失败\n", key)
		log.Println(err)
		return base.TestError
	}
	return result
}

// LRange
//  @Description:返回列表的一个范围内的数据,也可以返回全部数据
//  @receiver r
//  @param key
//  @param start
//  @param end
//  @return []string
//
func (r RedisBase) LRange(key string, start, end int64) []string {
	result, err := r.pool.LRange(key, start, end).Result()
	if err != nil {
		log.Printf("LRange :%s 失败\n", key)
		log.Println(err)
		return nil
	}
	return result
}

// LRem
//  @Description:删除列表中的数据
//从列表左边开始删除, 如果出现重复元素,仅删除1次,也就是删除第一个(key,1,"FunTester")
// 如果存在多个,则从列表左边开始删除2个100(key,2,"FunTester")
// 如果存在多个,则从列表右边开始删除2个100(key,-2,"FunTester")
// 删除所有(key,0,value)
//  @receiver r
//  @param key
//  @param count
//  @param value
//  @return int64
//
func (r RedisBase) LRem(key string, count int64, value interface{}) int64 {
	result, err := r.pool.LRem(key, count, value).Result()
	if err != nil {
		log.Printf("LRem :%s count: %d value: %s 失败\n", key, count, value)
		log.Println(err)
		return base.TestError
	}
	return result
}

// LIndex
//  @Description:根据索引坐标,查询列表中的数据
//  @receiver r
//  @param key
//  @param index 索引,从0开始算
//  @return string
//
func (r RedisBase) LIndex(key string, index int64) string {
	result, err := r.pool.LIndex(key, index).Result()
	if err != nil {
		log.Printf("LIndex :%s index: %d 失败\n", key, index)
		log.Println(err)
		return base.Empty
	}
	return result
}

// LInsertBefore
//  @Description:在指定位置插入数据
//  @receiver r
//  @param key
//  @param pivot
//  @param value
//  @return int64
//
func (r RedisBase) LInsertBefore(key string, pivot, value interface{}) int64 {
	result, err := r.pool.LInsertBefore(key, pivot, value).Result()
	if err != nil {
		log.Printf("LInsertBefore :%s pivot: %s value:%s 失败\n", key, pivot, value)
		log.Println(err)
		return base.TestError
	}
	return result
}

// LInsertAfter
//  @Description:在指定位置插入数据
//  @receiver r
//  @param key
//  @param pivot
//  @param value
//  @return int64
//
func (r RedisBase) LInsertAfter(key string, pivot, value interface{}) int64 {
	result, err := r.pool.LInsertAfter(key, pivot, value).Result()
	if err != nil {
		log.Printf("LInsertAfter :%s pivot: %s value:%s 失败\n", key, pivot, value)
		log.Println(err)
		return base.TestError
	}
	return result
}

FunTester原创专题集锦 - 接口功能测试专题 - 性能测试专题 - Groovy专题 - Java、Groovy、Go、Python - 单测&白盒 - FunTester社群风采 - 测试理论鸡汤 - FunTester视频专题 - 案例分享:方案、BUG、爬虫 - UI自动化专题 - 测试工具专题

阅读原文,跳转我的仓库地址