网易首页 > 网易号 > 正文 申请入驻

DevOps后台自动化测试平台讲解,支持Go、Python、C++等

0
分享至

作者:faithchen,腾讯PCG测试开发工程师

  • 一、背景及概要
  • 二、用例编写
  • 三、用例执行
  • 四、结果分析
  • 五、总结
  • 六、其他
一、背景及概要1.1 背景

随着业内对研发效能的重视,DevOps理念愈发地渗入到日常软件研发流程中,我们希望通过自动化测试等手段,能够更加快捷、频繁和可靠地构建、测试、发布软件。

在这个背景下,PCG后台自动化测试平台(同源)为后台单元测试落地到devops流程提供了一站式解决方案。从单测用例编写、用例执行到结果分析,平台都有一套已经在实践中的方案,致力于提升单测编写效率以及提供CI/CD流程高效接入单测能力,保证产品质量,提升研发效能。

本文主要以Go语言为例进行说明,对于Python、C++等语言也有相应的支持。

1.2 后台单测概要

后台测试主要有单元测试接口测试集成测试压力测试。无论哪一种测试,最终目的都只有一个,就是提升代码质量,持续交付。PCG后台自动化测试平台提供了整套符合DevOps规范的单元测试、接口测试、集成测试和压测自动化方案:同源同库、go test可直接运行、MR质量红线等。本文主要介绍***后台单元测试***相关的工具和概念。

说到测试用例(包括单元测试),无外乎三个步骤:用例编写->用例执行->结果分析,接下来对这三个步骤展开说明。

二、用例编写

当需要着手去写用例时,首先要明确一些单元测试的概念。众所周知,单元测试(Unit Testing)本身就是针对软件设计最小可测单位即程序模块的测试,在后台测试中,这个最小模块一般是一个函数方法。

最理想的情况是要测试的单元,不需要模拟对象(mock),也不需要依赖数据库、Redis等组件便可以编写用例去保证代码的功能与质量。举个最简单的例子:

// Add 对两个int类型进行相加func Add(a, b int) int { return a + b}// TestAdd 用于Add函数逻辑是否正确func TestAdd(t *testing.T) { assert.Equal(t, 3, Add(1, 2))//断言}

当然了,必要情况可以多设计一些边界值和异常值来保证功能的完整,这里只是举个最简单的例子。

然而我们很快就会发现,并不是所有情况都那么理想,比如说我突然想看这个函数处理异常时功能是否符合预期,但是这个异常情况通过正常运行并不能或难以复现,或者需要更测试某个条件/逻辑分支,那么这个时候就需要用到mock工具了。

2.1 用例编写之Mock

Mock能帮助解决一部分的单元测试编写问题,那么是哪一部分呢?这部分我们给个名字的话,可以暂时称为无外部依赖单测用例。先上个图:

从图中可以看到,需要测试的函数方法,只依赖被测代码,不需要其他数据库等,并且在同进程内测试,当然了对外部依赖就更加禁止了。

对于这部分代码的单测,除了可以直接测试的代码外,其他不能直接测试的代码那就需要使用Mock方法。

基于公司目前内部没有一款自己维护的适合公司业务迭代的后台mock框架,众多项目采用外界开源的gomonkey框架进行函数的mock,因其存在一些的稳定性的bug,不支持异包私有函数mock,同包私有方法mock等等问题,在PCG后台自动化测试中,提供了goom mock工具,其提供了针对Go语言的mock能力。

其主要功能特性有:

  1. 私有(未导出)函数(或方法)的mock, 普通函数的mock
  2. mock过程中回调原函数(线程安全, 支持并发单测),已升级为trampoline模式
  3. 异常注入,对函数调用支持异常注入,延迟模拟等稳定性测试
  4. 支持interface mock (面向接口编程和测试,验证中)

假设我们有以下待单测函数:

func foo(i int) int { return i}

对上面foo函数进行mock的示例代码如下:

func TestGoomMock(t *testing.T) { // 创建当前包的mocker mock := mocker.Create() // 完成这个单测以后重置mock defer mock.Reset() // mock函数foo并设定返回值为1 mock.Func(foo).Return(1) // 断言 assert.Equal(t, foo(100), 1)}

如上面代码所示,我们很简单地就对一个函数进行了mock,并对其进行了断言,完成了一个最简单的单元测试 : ) 除了上面设置返回值的方法外,我们也可以通过设置代理函数的方法来mock:

func TestGoomMock(t *testing.T) { mock := mocker.Create() defer mock.Reset() // mock函数foo并设置其代理函数 mock.Func(foo).Apply(func(i int) int { return i * 2 }) assert.Equal(t, foo(100), 200)}

值得提醒的是,在写代码单测过程中,尽量遵循“ 非必须不使用mock ”的原则,以便更好地提高代码覆盖率。

2.2 用例编写之组件依赖

在后台单元测试中,还会遇到一种情况,单纯使用mock难以满足编写用例需求,比如部分代码需要与数据库、Redis、Kafka等组件进行交互,难以编写单元测试用例。这种情况我们将原本需要远程依赖的组件,通过本地提供相关组件的方式,使原本需要通过接口或集成测试实现的用例可以通过单元测试实现,如下图:

这类单元测试用例注重服务内部模块间的集成验证,除依赖被测代码以外,还可以依赖本地资源。(“本地”即访问网络为localhost,依赖的本地资源包括本地数据库、本地文件系统、同进程mock或者本地测试替身等)。在PCG自动化分层定义中,将这类测试用例称为A1单元测试用例,前文提到的不需要依赖本地资源的称为A0单元测试用例。 对于上述这类单测,提供了以下方案,解决开发阶段需要在 蓝盾流水线本地 两种模式下编写和运行含本地依赖测试用例的难题,简化开发蓝盾流水线配置和本地配置成本,覆盖司外mysql、redis、kalfka、es和司内dcached的数据库相关组件。

2.2.1 实现方案

假设有以下mysql的业务逻辑,需要与mysql进行交互:

// InsertNameAndAge 在数据中插入name和agefunc InsertNameAndAge(db *sql.DB, name string, age string) { sqlStr := "insert into user(name, age) values (?,?)" ret, err := db.Exec(sqlStr, name, age) if err != nil { return }}

对于上述代码的单测,目前的方案是通过docker-compose工具,使用 docker-compose.yml 定义单测需要的组件服务,例如下图的yml文件配置了一个mysql组件服务:

version: "3"services: mysql: image: mysql:5.6 container_name: ngtest-mysql ports: - 4306:3306 environment: - MYSQL_DATABASE=test - MYSQL_ROOT_PASSWORD=abcde

接下来通过代码完成以下流程:

  1. 在运行单测前使用docker-compose命令在后台启动组件 docker-compose -f docker-compose.yml up -d
  2. 执行单测用例
  3. 最后销毁本地组件 docker-compose -f docker-compose.yml down

具体代码:

// TestMain 运行单测环境设置func TestMain(m *testing.M) { InitDockerYml() //在用例执行前通过docker-compose命令在后台启动组件 m.Run() //运行用例 TearDownDocker()//运行用例后销毁组件 os.Exit(0)}// TestInsertNameAndAge 测试InsertNameAndAge功能是否正常func TestInsertNameAndAge(t *testing.T){ //通过本地yml文件获取mysql配置,并且获取默认DB db, err := service.GetMySQLDB(s.MySQLConfig, "") assert.Nil(t, err) InsertNameAndAge(db, "Tom", 11) var name string var age uint8 //获取最后插入数据的自增ID id, err := result.LastInsertId() err = db.QueryRow("select name,age from test where id = ?", id).Scan(&name, &age) //断言 assert.Nil(t, err) assert.EqualValues(t, "Tom", name) assert.EqualValues(t, 11, age)}

这部分功能还在持续迭代和完善中,后续会提供更详细文档。

2.3 用例编写共识及规范2.3.1 用例编写共识

这里简要介绍一些有较多测试经验的工程师总结的一些测试编写共识,有助于写出更高质量的测试代码。下面简要列出几点:

  • 非必要不使用mock:这一点在上面已经简单的提到了,过多的mock会降低单测的有效性,所以应该减少mock,非必要时不使用mock,来起到单测应该发挥的作用。
  • 在单测中不允许使用Sleep:可能有部分人员在编写测试用例的时候,对一些有异步逻辑的方法测试时,会使用sleep方法来保证用例可以通过,但是这与单元测试的“小而快”的理念相悖,容易带来大量的单测运行耗时,减慢我们mr等操作的进度。
  • 避免脆弱的测试:编写测试用例是为了保证代码质量,并且希望一旦出现失败是代码变动导致了bug才使用例失败。但是如果由于一些偶现的环境因素或者其他原因导致用例失败,让我们需要投入人力去排查,那么这样的测试用例是应该被整改或者删除的,因为它给了我们错误的信息,并且花费了我们不必要的时间。
  • 提高用例可操作性:即如果用例失败,我们能够快速定位错误的位置。
三、用例执行3.1 本地执行后台单测用例

大家知道Go语言是自带一套单元测试和性能测试系统。当写完本地的后台单元测试之后,可以通过以下命令运行,并获取结果:

go test -v `go list ./...|grep -v apitest|grep -v api_test` -gcflags=all=-l -covermode count -coverpkg ./... -coverprofile cover.out

其中grep -v apitest|grep -v api_test是将命名表示为接口api测试的测试用例剔除,gcflags=all=-l表示禁止内联,防止我们一些mock的函数不生效,并且生成cover.out文件。

控制台输出的信息如下:

2021-05-17 14:32:09.568 INFO automaxprocs@v1.3.0/automaxprocs.go:32 maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined=== RUN TestSayHello--- PASS: TestSayHello (0.00s)=== RUN TestSayHi--- PASS: TestSayHi (0.00s)PASScoverage: 10.1% of statements in ./...ok trpc.app.Greeter/greeter 0.010s coverage: 10.1% of statements in ./...? trpc.app.Greeter/pb [no test files]

里面可以看到每个用例的成功与失败,还有覆盖率。 cover.out文件的输出如下:

mode: counttrpc.app.Greeter/pb/helloworld.pb.go:31.40,31.63 1 0trpc.app.Greeter/pb/helloworld.pb.go:32.40,32.77 1 0trpc.app.Greeter/pb/helloworld.pb.go:33.41,33.42 0 0trpc.app.Greeter/pb/helloworld.pb.go:34.51,36.2 1 1trpc.app.Greeter/pb/helloworld.pb.go:38.54,40.2 1 0trpc.app.Greeter/pb/helloworld.pb.go:41.82,43.2 1 03.2 CI/CD执行后台单测用例

编写单测的最终目的还是能够在CI/CD之间发挥作用,提升代码的质量。

蓝盾流水线添加后台单测插件

如下图所示,添加了同源自动化测试插件后,设置代码路径code_path,和分支code_tag后,如下图勾选单元测试便可以执行对应的单元测试(当然,如果有需要也可以加上接口测试)。

执行完之后,在插件日志中,也可以看到自动化报告:

腾讯应用宝、微视、看点、腾讯视频等PCG大部分业务都在使用。

四、结果分析4.1 结果报告

在上述执行完单测后,我们便可以得到测试结果。在同源自动化测试插件的日志中我们可以看到相应结果的链接:

自动化报告信息如下:

这个报告能够很直观的告诉我们本地单测的执行情况,这个在单测数目比较多的时候回更加直观与高效,帮助我们查看用例的执行情况,当某个用例出错时,也会相应地列出出错原因等,便于定位,例如:

覆盖率报告信息如下:

4.2 质量红线

在获取了单测结果报告后,在代码commit、mr等关键环节中,我们还可以进一步设置质量红线,我们提供了同源后台质量红线插件,大家可以在上面配置代码覆盖率用例通过率等红线,保证我们进行代码mr等关键环节的代码质量。

五、总结

单测的编写及使用流程如下:

CI/CD的接入流程如下:

六、其他

其他语言如Python、C++的后台单元测试,平台也有相应多的支持。 有任意疑问或者建议随时欢迎联系讨论。

福利时间

抽5位朋友送出《小程序开发原理与实战》,腾讯一线专家带你学习小程序开发,干货满满!戳这里: 福利 参与!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
谈好了!埃及和中国签约了!

谈好了!埃及和中国签约了!

故事终将光明磊落
2026-09-03 10:31:03
韩国主办方拒换涉台标牌,中方零容忍果断撤展,就算道歉也不管用

韩国主办方拒换涉台标牌,中方零容忍果断撤展,就算道歉也不管用

面包夹知识
2026-09-03 18:19:36
王志文:不要和任何人走得太近,因为你不知道什么时候会反目成仇|保持距离,才是最好的保护

王志文:不要和任何人走得太近,因为你不知道什么时候会反目成仇|保持距离,才是最好的保护

杏花烟雨江南的碧园
2026-07-28 15:15:03
官宣加盟!你好,威少!50亿美元全球巡回联赛

官宣加盟!你好,威少!50亿美元全球巡回联赛

篮球实战宝典
2026-09-03 19:08:10
黄喜灿在伯明翰一家韩餐馆用餐后,为餐厅所有食客买了单

黄喜灿在伯明翰一家韩餐馆用餐后,为餐厅所有食客买了单

懂球帝
2026-09-03 15:42:18
赴韩领毕业证遇害中国留学生家属已委托律师团队,全力争取将凶手引渡回国审判,家属最新回应

赴韩领毕业证遇害中国留学生家属已委托律师团队,全力争取将凶手引渡回国审判,家属最新回应

极目新闻
2026-09-02 16:56:27
搓澡10年的大姐说句掏心话:女人脱了衣服才发现这5个真相

搓澡10年的大姐说句掏心话:女人脱了衣服才发现这5个真相

朗威谈星座
2026-09-04 08:06:39
郭富城太太时装展脚抖快摔倒,嫁港 9 年还要翻译,现场反应引热议

郭富城太太时装展脚抖快摔倒,嫁港 9 年还要翻译,现场反应引热议

寒士之言本尊
2026-09-03 18:47:12
利物浦头号卧底!名宿痛批新版努涅斯!4000 万引援坑惨全队

利物浦头号卧底!名宿痛批新版努涅斯!4000 万引援坑惨全队

澜归序
2026-09-04 09:36:25
36岁待业演员在河北一景区扮演“玄奘”走红;当事人回应:之前是影视演员,目前主要是游走互动和游客聊天

36岁待业演员在河北一景区扮演“玄奘”走红;当事人回应:之前是影视演员,目前主要是游走互动和游客聊天

封面新闻
2026-09-03 22:49:04
GPT-6 Astra上线,AGI时代真到来了吗?

GPT-6 Astra上线,AGI时代真到来了吗?

字母榜
2026-09-04 08:11:18
《醒来》大结局:顶级特工李士群,76号大魔头,最终38岁栽在了牛肉饼上

《醒来》大结局:顶级特工李士群,76号大魔头,最终38岁栽在了牛肉饼上

肆季娱乐
2026-09-02 21:02:27
中国该怎么救俄罗斯?比俄罗斯失败更可怕的是,是中国被俄拖下水

中国该怎么救俄罗斯?比俄罗斯失败更可怕的是,是中国被俄拖下水

风流女汉
2026-09-04 07:42:31
马蓉直播哭穷,5000万快花光!金发造型寻找下一个“王宝强”?

马蓉直播哭穷,5000万快花光!金发造型寻找下一个“王宝强”?

八卦疯叔
2026-09-03 10:00:06
彻查!信号强烈!中央升级反腐“天网”!

彻查!信号强烈!中央升级反腐“天网”!

职场资深秘书
2026-09-03 13:02:35
强盗本性爆发,美欧合力逼人民币升值,要让14亿中国人给美债买单

强盗本性爆发,美欧合力逼人民币升值,要让14亿中国人给美债买单

时尚的弄潮
2026-09-03 11:32:47
让大众中国告诉常州星宇: 再复制富士康式的悲剧,后果会如何

让大众中国告诉常州星宇: 再复制富士康式的悲剧,后果会如何

冷观互联网
2026-09-01 16:23:40
吹捧印度人天生优越、国人素质低下的东北刘丹彻底翻车,沦为笑柄

吹捧印度人天生优越、国人素质低下的东北刘丹彻底翻车,沦为笑柄

呼呼历史论
2026-09-04 08:07:10
一辆不值钱的“奔驰E300L”,让学生家长被嘲笑:现实点吧,别心比天高

一辆不值钱的“奔驰E300L”,让学生家长被嘲笑:现实点吧,别心比天高

熙熙说教
2026-08-31 14:59:44
阿卡逆转阿昺横扫,中西一哥二番战来啦!萨巴送油条巴多萨战高芙

阿卡逆转阿昺横扫,中西一哥二番战来啦!萨巴送油条巴多萨战高芙

网球之家
2026-09-03 12:51:53
2026-09-04 11:19:00
腾讯技术工程
腾讯技术工程
不止于技术
1447文章数 601关注度
往期回顾 全部

科技要闻

OpenAI深夜王炸!GPT-6 Astra来了

头条要闻

尼泊尔泥石流致1290死 民众拍下山洪吞没山谷建筑过程

头条要闻

尼泊尔泥石流致1290死 民众拍下山洪吞没山谷建筑过程

体育要闻

梅西:巴萨10号与阿根廷10号

娱乐要闻

王宝强冯清八年未领证!真相令人泪目

财经要闻

电池税开征,纯电车利润快归零了

汽车要闻

30.99-39.99万 价格够狠、配置够满、豪华够硬 奇瑞捷豹路虎神行者8上市即爆单

态度原创

房产
本地
时尚
游戏
公开课

房产要闻

投资50亿!三亚又一重大配套,方案曝光!

本地新闻

昆明的雨,解锁汪曾祺的浪漫雨季

这么多年,美容觉白睡了?

科乐美新作《绯红狂想曲》公布,魔法少女卷入纽约黑帮阴谋

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版