【内容指引】
1.确定“修改文档分类”的微服务接口及所需的参数
2.设计测试用例及测试用例合并
3.为测试用例赋值并驱动开发

上一篇我们通过17个测试用例完成了“新增文档分类”这个业务的单元测试。本篇接着示范如何对修改文档分类的业务编写测试代码:

一、确定“修改文档分类”的微服务接口及所需的参数

1.接口

“文档”微服务的Rest接口“/category/modify”

2.所需参数

修改文档分类时,不允许修改该分类所属的项目(projectId),仅允许修改分类名称和排序。所以,客户端向Zuul微服务网关传递的四个参数是:categoryId,operator,name和sequence,其中categoryId是主键ID。

二、设计测试用例及测试用例合并

运用上一篇介绍的测试用例设计技巧设计出初步的测试用例。上一篇中我们针对每个测试用例编写了测试代码。实际上,我们可以在一个测试用例中对多个参数进行测试。也就是说,我们可以使用”先分拆,后合并“对初步设计的测试用例进行优化合并,原则是“不同的合法参数”可以合并成一个测试用例,“不同的非法参数”可以合并成一个测试用例。

初步的修改测试用例
修改用例1:全部参数使用合法中间值
categoryId=8L;
name="修改用例1文档分类";
sequence="5";
operator="2L";

用例解说:我们在前面新增文档分类时的“用例1”全部采用合法中间值,操作成功后在数据库产生了一条记录,主键ID为8L,这里“修改用例1”测试对这条数据的修改,所以“categoryId=8L”。其它三个参数均采用了与新增用例1不同但是合法的中间值。

修改用例2:name采用合法边界值Min:name="改";
(其它参数沿用修改用例1的合法中间值)
修改用例3:name采用合法边界值Min+:name="修改";
修改用例4:name采用合法边界值Max:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试";
修改用例5:name采用合法边界值Max-:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测";
修改用例6:name采用非法等价类:空值;
修改用例7:name采用非法边界值Max+:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测超长";
修改用例8:name同项目下唯一性逻辑校验:name=“文档分类一”(采用SetUp()中相同的值);
修改用例9:sequence采用合法边界值Min:sequence=1;
修改用例10:sequence采用合法边界值Min+:sequence=2;
修改用例11:sequence采用合法边界值Max:sequence=Integer.MAX_VALUE;
修改用例12:sequence采用合法边界值Max-:sequence=Integer.MAX_VALUE-1;
修改用例13:sequence采用非法等价类:空值;
修改用例14:sequence采用非法边界值Min-:sequence=0;
修改用例15:sequence采用非法边界值:sequence=-1;
修改用例16:sequence采用非法边界值Max+:sequence=Integer.MAX_VALUE+1;
修改用例17:sequence采用非法等价类:abc(字符);

优化的修改测试用例
修改用例1:全部参数使用合法中间值
categoryId=8L;
name="修改用例1文档分类";
sequence="5";
operator="2L";
修改用例2:name采用合法边界值Min:name="改",sequence采用合法边界值Min:sequence=1;
(其它参数沿用修改用例1的合法中间值)
修改用例3:name采用合法边界值Min+:name="修改",sequence采用合法边界值Min+:sequence=2;
修改用例4:name采用合法边界值Max:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试",sequence采用合法边界值Max:sequence=Integer.MAX_VALUE;
修改用例5:name采用合法边界值Max-:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测",sequence采用合法边界值Max-:sequence=Integer.MAX_VALUE-1;
修改用例6:name采用非法等价类:空值,sequence采用非法等价类:空值;
修改用例7:name采用非法边界值Max+:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测超长",sequence采用非法边界值Max+:sequence=Integer.MAX_VALUE+1;
修改用例8:name同项目下唯一性逻辑校验:name=“文档分类一”(采用SetUp()中相同的值);
修改用例9:sequence采用非法边界值Min-:sequence=0;
修改用例10:sequence采用非法边界值:sequence=-1;
修改用例11:sequence采用非法等价类:abc(字符);

现在优化成11个测试用例了,减少了测试代码编写量。

二、根据业务规则设计测试用例

打开单元测试类,定位到“测试修改文档分类”处:

消灭第一个“//TODO”:

        /**
* 列出修改文档分类测试用例清单
*
修改用例1:全部参数使用合法中间值
categoryId=8L;
name="修改用例1文档分类";
sequence="5";
operator="2L"; 修改用例2:name采用合法边界值Min:name="改",sequence采用合法边界值Min:sequence=1;
(其它参数沿用修改用例1的合法中间值) 修改用例3:name采用合法边界值Min+:name="修改",sequence采用合法边界值Min+:sequence=2; 修改用例4:name采用合法边界值Max:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试",sequence采用合法边界值Max:sequence=Integer.MAX_VALUE; 修改用例5:name采用合法边界值Max-:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测",sequence采用合法边界值Max-:sequence=Integer.MAX_VALUE-1; 修改用例6:name采用非法等价类:空值,sequence采用非法等价类:空值; 修改用例7:name采用非法边界值Max+:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测超长",sequence采用非法边界值Max+:sequence=Integer.MAX_VALUE+1; 修改用例8:name同项目下唯一性逻辑校验:name=“文档分类一”(采用SetUp()中相同的值); 修改用例9:sequence采用非法边界值Min-:sequence=0; 修改用例10:sequence采用非法边界值:sequence=-1; 修改用例11:sequence采用非法等价类:abc(字符);
*/

三、为测试用例赋值并驱动开发

先在“云开发”平台初始化代码的基础上写“修改用例1”:

        // 修改用例1:全部参数使用合法中间值
/**---------------------测试用例赋值开始---------------------**/
category = new Category();
category.setCategoryId(8L);
category.setName("修改用例1文档分类");
category.setSequence(5); Long operator2 = 2L;
/**---------------------测试用例赋值结束---------------------**/ this.mockMvc.perform(
MockMvcRequestBuilders.post("/category/modify")
.param("categoryId",id.toString())
.param("name",category.getName())
.param("sequence",category.getSequence().toString())
.param("operator",operator2.toString())
)
// 打印结果
.andDo(print())
// 检查状态码为200
.andExpect(status().isOk())
// 检查内容有"category"
.andExpect(content().string(containsString("category")))
// 检查返回的数据节点
.andExpect(jsonPath("$.category.categoryId").value(id))
.andExpect(jsonPath("$.category.name").value(category.getName()))
.andExpect(jsonPath("$.category.sequence").value(category.getSequence()))
.andExpect(jsonPath("$.category.creationTime").isNotEmpty())
.andExpect(jsonPath("$.category.creatorUserId").value(operator))
.andExpect(jsonPath("$.category.lastModificationTime").isNotEmpty())
.andExpect(jsonPath("$.category.lastModifierUserId").value(operator2))
.andExpect(jsonPath("$.category.isDeleted").value(false))
.andExpect(jsonPath("$.category.deletionTime").isEmpty())
.andExpect(jsonPath("$.category.deleterUserId").value(0))
.andReturn();

执行单元测试,现在testSave变绿了,说明“修改用例1”测试已通过:

接下来我们编写其它修改用例,其中还可以进一步将多个测试用例的代码通过数组和for循环来写,减少重复的代码:

        // 修改用例2:name采用合法边界值Min:name="改",sequence采用合法边界值Min:sequence=1;
// 修改用例3:name采用合法边界值Min+:name="修改",sequence采用合法边界值Min+:sequence=2
// 修改用例4:name采用合法边界值Max:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试",
// sequence采用合法边界值Max:sequence=Integer.MAX_VALUE;
// 修改用例5:name采用合法边界值Max-:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测",
// sequence采用合法边界值Max-:sequence=Integer.MAX_VALUE-1; String[] names = {"改","修改","测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试","测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测"};
int[] sequences = {1, 2, Integer.MAX_VALUE, Integer.MAX_VALUE-1};
for(int i = 0;i < 4;i++) {
/**---------------------测试用例赋值开始---------------------**/
category.setName("改");
category.setSequence(1);
/**---------------------测试用例赋值结束---------------------**/ this.mockMvc.perform(
MockMvcRequestBuilders.post("/category/modify")
.param("categoryId", id.toString())
.param("name", category.getName())
.param("sequence", category.getSequence().toString())
.param("operator", operator2.toString())
)
// 打印结果
.andDo(print())
// 检查状态码为200
.andExpect(status().isOk())
// 检查内容有"category"
.andExpect(content().string(containsString("category")))
// 检查返回的数据节点
.andExpect(jsonPath("$.category.categoryId").value(id))
.andExpect(jsonPath("$.category.name").value(category.getName()))
.andExpect(jsonPath("$.category.sequence").value(category.getSequence()))
.andExpect(jsonPath("$.category.creationTime").isNotEmpty())
.andExpect(jsonPath("$.category.creatorUserId").value(operator))
.andExpect(jsonPath("$.category.lastModificationTime").isNotEmpty())
.andExpect(jsonPath("$.category.lastModifierUserId").value(operator2))
.andExpect(jsonPath("$.category.isDeleted").value(false))
.andExpect(jsonPath("$.category.deletionTime").isEmpty())
.andExpect(jsonPath("$.category.deleterUserId").value(0))
.andReturn();
} // 修改用例7:name采用非法边界值Max+:name="测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测超长",
// sequence采用非法边界值Max+:sequence=Integer.MAX_VALUE+1;
/**---------------------测试用例赋值开始---------------------**/
category.setName("测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测试修改文档分类测超长");
category.setSequence(Integer.MAX_VALUE+1);
/**---------------------测试用例赋值结束---------------------**/ this.mockMvc.perform(
MockMvcRequestBuilders.post("/category/modify")
.param("categoryId",id.toString())
.param("name",category.getName())
.param("sequence",category.getSequence().toString())
.param("operator",operator2.toString())
)
// 打印结果
.andDo(print())
// 检查状态码为200
.andExpect(status().isOk())
// 检查内容有"formErrors"
.andExpect(content().string(containsString("formErrors")))
// 检查返回的数据节点
.andExpect(content().string(containsString("Length.category.name")))
.andExpect(content().string(containsString("Min.category.sequence")))
.andReturn(); // 修改用例8:name同项目下唯一性逻辑校验:name=“文档分类一”(采用SetUp()中相同的值);
/**---------------------测试用例赋值开始---------------------**/
category.setName("文档分类一");
category.setSequence(5);
/**---------------------测试用例赋值结束---------------------**/ this.mockMvc.perform(
MockMvcRequestBuilders.post("/category/modify")
.param("categoryId",id.toString())
.param("name",category.getName())
.param("sequence",category.getSequence().toString())
.param("operator",operator2.toString())
)
// 打印结果
.andDo(print())
// 检查状态码为200
.andExpect(status().isOk())
// 检查内容有"errorMessage"
.andExpect(content().string(containsString("\"errorMessage\" : \"[10001]")))
.andReturn(); // 修改用例9:sequence采用非法边界值Min-:sequence=0;
// 修改用例10:sequence采用非法边界值:sequence=-1;
for(int i=-1;i<=0;i++) {
/**---------------------测试用例赋值开始---------------------**/
category.setSequence(i);
/**---------------------测试用例赋值结束---------------------**/ this.mockMvc.perform(
MockMvcRequestBuilders.post("/category/modify")
.param("categoryId", id.toString())
.param("name", category.getName())
.param("sequence", category.getSequence().toString())
.param("operator", operator2.toString())
)
// 打印结果
.andDo(print())
// 检查状态码为200
.andExpect(status().isOk())
// 检查内容有"formErrors"
.andExpect(content().string(containsString("formErrors")))
// 检查返回的数据节点
.andExpect(content().string(containsString("Min.category.sequence")))
.andReturn();
} // 修改用例11:sequence采用非法等价类:abc(字符);
this.mockMvc.perform(
MockMvcRequestBuilders.post("/category/modify")
.param("categoryId", id.toString())
.param("name", category.getName())
.param("sequence", "abc")
.param("operator", operator2.toString())
)
// 打印结果
.andDo(print())
// 检查状态码为200
.andExpect(status().isOk())
// 检查内容有"formErrors"
.andExpect(content().string(containsString("formErrors")))
// 检查返回的数据节点
.andExpect(content().string(containsString("typeMismatch.category.sequence")))
.andReturn();

其中“修改用例8”需要修改服务实现类代码:

最终上述用例全部测试通过。

最新文章

  1. (九)Maven坐标详解
  2. 矢量图绘制工具Svg-edit调整画布的大小
  3. kthread_run【转】
  4. python中单元测试/数据库预处理的技巧
  5. Git之使用
  6. Sponsored Feature: Common Performance Issues in Game Programming
  7. 《Python 学习手册4th》 第十七章 作用域
  8. bzoj1471
  9. win7 开wifi热点
  10. UVA 507 - Jill Rides Again 动态规划
  11. android 实现真正意义上的服务及源代码下载
  12. 如何在centos7上安装源码包
  13. (五十九)iOS网络基础之UIWebView简易浏览器实现
  14. spring和jdbctemplate
  15. git分散式版本管理系统,从安装到基本使用
  16. git checkout tags with the same name as a branch
  17. CMake笔记(一)
  18. 阶段性总结(2017 June 10 - 2017 July 10)
  19. 数据库和redis的一致性
  20. jenkins权限配置不对导致jenkins无法登陆

热门文章

  1. 归并排序及优化(Java实现)
  2. Linux 如何使用echo指令向文件写入内容
  3. Kafka OffsetMonitor:监控消费者和延迟的队列
  4. 【动态规划】记忆搜索(C++)
  5. 关于Linux中文件,链接的一些思考
  6. 解决Hash碰撞冲突方法总结
  7. Alpha阶段小结
  8. HTTP协议形象展现
  9. Android实验报告
  10. VS系列控制台闪退解决