前文提到,在UI自动化之外,我们着力探索了如何实施单元测试(unit test
相对于UI自动化,单元测试方面的实践还是不够充分的,因此,这里也只是小结一下我们的经验
 概述
首先明确一下,此处单元测试概念与经典意义有所不同,泛指所有:
由开发工程师编写的,可以在开发本地一键运行的,运行时间在分钟级别的测试用例,用例执行会依赖不多的,但往往也是稳定可靠的外部环境
测试框架一般使用TestNg而不是JUnit,主要原因在于TestNg的 DataProvider 功能很给力,非常适合用例须要覆盖多分支的场景
 用例组织原则:
一个测试类对应一个功能类: funcOneTest.java 对应于 funcOne.java
若干个测试方法对应一个功能方法:test_funcOne_smoke() & test_funcOne_normal() & test_funcOne_error() 对应于 funcOne()
用例分类约定
还是以 超市购物 为背景,写几个Demo用例
 Δ冒烟型用例 – 甲
@Test(description = "getNewestItems_冒烟_获取最新商品并检查若干关键属性")
public void test_getNewestItems_smoke() {
List<ItemVo> itemList = itemBean.getNewestItems(1);
Assert.assertTrue(itemList.size() == 16,        "size应该是16");
for (ItemVo vo : itemList) {
Assert.assertTrue(vo.getName() != null,     "name不能为空");
Assert.assertTrue(vo.getPrice() != null,    "price不能为空");
}
}
说明:
顾名思义,就是在用例中简单调用一下被测方法(method),主要是为了跑通流程,拒绝Block级别问题
实践中,推荐 伴随着功能开发,随时编写冒烟用例,功能代码与冒烟用例一起提交代码库
对于一些复杂的功能,功能开发的过程也是一个持续重构的过程,编码前期完成的冒烟用例,可以有效起到安全网作用
Δ冒烟型用例 – 乙
@Test(description = "enter_and_leave_market_冒烟_进入与离开超市")
public void test_enter_and_leave_market_smoke() {
Custom tom = new Custom("Tom");
tom.enterMarket();
Assert.assertTrue(Custom.isAtMarket(tom),   "tom应该在超市内");
tom.leaveMarket();
Assert.assertFalse(Custom.isAtMarket(tom),  "tom应该不在超市");
}
说明:
这个用例把进入超市及离开超市这两个(强相关的)接口串起来了,目的在于走通流程
  实践中,建议 将新模块(函数)与其强相关的模块(函数)尽早进行简单的集成测试以提前发现一些问题

Δ正常流程用例
@Test(description = "addToCart_正常流程_往购物车内添加各种类型数目的商品", dataProvider = "test_addToCart_normal_data")
@Rollback
public void test_addToCart_normal(String caseNote, long itemId, int count) {
Custom tom = new Custom("Tom");
this.setCustom(tom);
cartBean.addToCart(itemId, count);
Item item = tom.getCart.getItems.get(0);    // 获取购物车中的第一项商品
Assert.assertEquals(item.getId,      itemId,  "itemId is wrong");
Assert.assertEquals(item.getCount,   count,   "count is wrong");
}
@DataProvider
public Object[][] test_addToCart_normal_data() {
return new Object[][] {
// caseNote,                    itemId,     count
{"Milk  - just a dozen",        39001L,     12,  },
{"Bread - huge number",         116001L,    999},
{"Bean  - less then 10",        1018100L,   2},
};
}
说明:
这个示例代码演示了如何测试addToCart()的功能,假定这个方法内部有十分复杂的业务逻辑,我们须要覆盖各种场景
可以看到,正常流程用例与冒烟用例其实差不多,不同的是,正常流程用例会覆盖更多分支,冒烟用例则一般是走通流程就行
这个用例使用了@Rollback标签,用例执行后会回滚数据,而不会真正往数据库内插入数据;这个功能十分有用,可以大大减少数据准备与清理的工作;至于@Rollback背后的实现原理,此处暂时按下不表
测试参数使用TestNg的@DataProvider组织起来,每一行都是一组测试数据,覆盖一种测试分支
测试参数的第一列建议设置为caseNote,简单阐述用例的意图,可以有效提升用例可读性
Δ异常流程用例
@Test(description = "addToCart_异常流程_往购物车内添加参数非法的商品", dataProvider = "test_addToCart_error_data")
@Rollback
public void test_addToCart_error(String caseNote, long itemId, int count, int expectedErrorCode) {
Custom tom = new Custom("Tom");
this.setCustom(tom);
try {
cartBean.addToCart(itemId, count);
Assert.fail();
} catch (Exception e) {
Assert.assertEquals(e.getErrorCode, expectedErrorCode);
}
}
@DataProvider
public Object[][] test_addToCart_error_data() {
return new Object[][] {
// caseNote,                        itemId,     count,  expectedErrorCode
{"iPad       - 0 count",            39001L,     0,      Cart.ZERO_COUNT},
{"MacBookPro - more then stock",    116001L,    1024,   Cart.MORE_THAN_STOCK},
{"no such item",                    0L,         1L,     Cart.NO_SUCH_ITEM}
};
}
说明:
  如果不同的异常输入会有相应的 errorCode 的话, 可以把errorCode当成测试数据的一项参数传进去

Δ特殊场景 & 复杂流程
个别特殊场景,不方便使用@DataProvider合并的复杂流程,可以单独创建一个用例进行测试,函数命名的时候注明一下,例如:
test_addToCart_error_withoutEnoughMoney() – 钞票不够
test_addToCart_normal_mergeMultiCarts() – 合并多个购物车
Δ前事不忘,后事之师
出过Bug的地方(及其周边)补充单元测试覆盖,由单元测试帮你记住前事 – test_funcOne_issue12345_bugfix()
  用例编写流程
  用例编写顺序:
开发新功能时,同步编写冒烟测试,用于自测及调试,功能代码与冒烟用例一起提交 – test_funcOne_smoke()
稍晚,补充更多分支覆盖的正常流程用例,相当于进行又一轮自测 – test_funcOne_normal()
最后,补充异常流程和特殊(复杂)场景用例 – test_funcOne_error() & test_funcOne_specialScenario()
之所以这样安排,一个很重要的原因是希望 保持主干及正常流程的畅通,确保开发及测试不会Block
  此外:
尽量把单个开发任务切分成多个小功能点,频繁提交,稳扎稳打,配合Jenkins & Sonar,多跑单元测试和静态代码检查,问题早发现早处理
前事不忘,后事之师,出过Bug的地方补充单元测试
  补遗
单元测试与静态代码检查(static analysis, SA)是一对好基友,两者可以统一显示在Sonar上面,在实践中往往一起考察
关于Sonar,实乃居家必备,代码度量之利器,以后会另外讲述,这里先贴个图:
最新内容请见作者的GitHub页:http://qaseven.github.io/

持续集成实践小结[2] —单元测试相关推荐

  1. 基于Jenkins的开发测试全流程持续集成实践

    今年上半年一直在公司实践CI,本文将上半年来的一些实践总结一下,可能不太完善或优美,但的确初步解决了我目前所在项目组的一些痛点.当然这仅是一家之言也不够完整,后续下半年还会深入实践和引入Kuberne ...

  2. 基于Jenkins Pipeline的ASP.NET Core持续集成实践

    最近在公司实践持续集成,使用到了Jenkins的Pipeline来提高团队基于ASP.NET Core API服务的集成与部署,因此这里总结一下. 一.关于持续集成与Jenkins Pipeline ...

  3. [独孤九剑]持续集成实践(三)- Jenkins安装与配置(Jenkins+MSBuild+GitHub)

    本系列文章包含: [独孤九剑]持续集成实践(一)- 引子 [独孤九剑]持续集成实践(二)– MSBuild语法入门 [独孤九剑]持续集成实践(三)- Jenkins安装与配置(Jenkins+MSBu ...

  4. [独孤九剑]持续集成实践(二)– MSBuild语法入门

    本系列文章包含: [独孤九剑]持续集成实践(一)- 引子 [独孤九剑]持续集成实践(二)– MSBuild语法入门 [独孤九剑]持续集成实践(三)- Jenkins安装与配置(Jenkins+MSBu ...

  5. Jenkins与Docker的持续集成实践

    本文讲的是Jenkins与Docker的持续集成实践[编者的话]持续集成(CI/CD)是一种软件开发实践.用于帮助团队成员频繁.快速的集成,测试他们的工作成果,以尽快发现集成错误. 更频繁.更早的集成 ...

  6. Android 持续集成实践(三)——编写 .gitlab-ci.yml 实现自动化

    文章目录 前言 系列文章 Android 持续集成实践(三)--编写 .gitlab-ci.yml 实现自动化 要实现的效果 定义 gitlab-ci 工作场景阶段 定义 build 任务 定义 re ...

  7. Android 持续集成实践(二)——配置 Docker + gitlab-runner 实现线上自动编译

    文章目录 前言 系列文章 Android 持续集成实践(二)--配置 Docker + gitlab-runner 实现线上自动编译 安装 Docker 安装 gitlab-runner 安装 注册 ...

  8. Android 持续集成实践(四)——配置 WebHook 通知编译结果

    文章目录 前言 系列文章 Android 持续集成实践(四)--配置 WebHook 通知编译结果 团队沟通工具 创建团队 创建讨论组 添加 BearyChat 机器人 配置 WebHook gitl ...

  9. 软件自动化测试培训内容,软件自动化测试与持续集成实践培训方案

    一.背景概述 为响应工业和信息化部信息化高端人才培养的号召,中国信息化培训中心特推出了软件自动化测试与持续集成实践培训班,希望通过专业的培训与业界真实案例来全面提高学员软件自动化测试水平,从而更好地服 ...

最新文章

  1. linux在多核处理器上的负载均衡原理
  2. 【进阶4-1期】详细解析赋值、浅拷贝和深拷贝的区别
  3. 解决在C#(.net)按字节数截取字符串最后出现乱码的问题
  4. 【干货】iOS9的新特性UI Tests
  5. C#7.0之ref locals and returns (局部变量和引用返回,之前欠大家的,现在补上)
  6. 【BZOJ - 2574】[Poi1999] Store-Keeper(点双连通分量,求割点,记忆化bfs)
  7. html+注释格式化,使用xml注释来生成格式化的html输出
  8. 2020智慧零售行业研究报告
  9. 《ArcGIS Runtime SDK for Android开发笔记》
  10. Spring cloud Gateway(二) 一个Http请求的流程解析
  11. “华为杯”第十八届中国研究生数学建模竞赛历程及感悟
  12. 激荡三十年——互联网的崛起
  13. 介绍一下xgb_xgboost实战,一篇就好
  14. 3. Kubernetes资源-概述
  15. 这才叫装机必备,这3款高质量电脑软件,内存满了也绝不卸载
  16. 2021年安全生产模拟考试(建筑特种作业操作证-建筑焊工模拟考试题库)安考星
  17. 将监控摄像头的监控视频转发到互联网,实现远程视频监控
  18. 图像处理工具-Stirmark使用方法
  19. 相信历史会记住普通人
  20. 驾驶证上的照片有具体要求吗?这几点需要注意

热门文章

  1. 四轴飞行器1.4 姿态解算和Matlab实时姿态显示
  2. bool 变量想为什么一般初始化为FALSE 比较好?
  3. 洞悉物联网发展1000问之从精益管理到互联工业带来的启示是什么?
  4. (原創) 如何讓P7010外接螢幕支援1440x900(WXGA+)? (NB) (P7010)
  5. 微信小程序项目文件配置介绍
  6. SP2-0110: Cannot create save file afiedt.buf
  7. C++多小球非对心弹性碰撞(HGE引擎)
  8. 给VMWare虚拟机做快照--保存你的劳动成果
  9. python 钩子函数的使用
  10. flex与java实现增删改查