测试驱动开发实践5————testSave之修改文档分类
【内容指引】
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”需要修改服务实现类代码:

最终上述用例全部测试通过。
测试驱动开发实践5————testSave之修改文档分类的更多相关文章
- 测试驱动开发实践4————testSave之新增文档分类
[内容指引] 1.确定"新增文档分类"的流程及所需的参数 2.根据业务规则设计测试用例 3.为测试用例赋值并驱动开发 一.确定"新增文档分类"的流程及所需的参数 ...
- 测试驱动开发实践3————testSave之新增用户
内容指引 1.确定新增用户的业务规则 2.根据业务规则设计测试用例 3.为测试用例赋值并驱动开发 一.确定新增用户的规则 1.注册用户允许通过"用户名+密码"."手机号+ ...
- 测试驱动开发实践3————从testList开始
[内容指引] 运行单元测试: 装配一条数据: 模拟更多数据测试列表: 测试无搜索列表: 测试标准查询: 测试高级查询. 一.运行单元测试 我们以文档分类(Category)这个领域类为例,示范如何通过 ...
- 测试驱动开发实践—从testList开始
[内容指引]运行单元测试:装配一条数据:模拟更多数据测试列表:测试无搜索列表:测试标准查询:测试高级查询. 一.运行单元测试 我们以文档分类(Category)这个领域类为例,示范如何通过编写测试用例 ...
- Mongodb:修改文档结构后出现错误:Element '***' does not match any field or property of class ***.
Mongodb:修改文档结构后出现错误:Element '***' does not match any field or property of class ***. Mongodb是一种面向文档的 ...
- 将Word文档发给别人时如何限制别人只能修改文档部分内容
将Word文档发给别人时如何限制别人只能修改文档部分内容 转自:互联网.时间:2014-04-16 作者:snow 来源:互联网 在很多情况下我们都不希望别人修改我们的文档内容,特别实在将W ...
- MongoDB--使用修改器修改文档
可以使用修改器啦修改文档,比如增加.删除文档的键值.使用修改器首先要定位到某个文档, 然后再增加相应的修改选项,需要使用update语句 1.$inc修改器修改文档 > db.users.fin ...
- dedecms后台每页文章条数如何修改(“文档列表”每一页显示的文档条数)
小明在学习采集,弄了个dedecms作为发布平台,几个小时后跑来报喜说好简单,但又不想制造那么多spam,每个分类只保留几条就好.在后台删除这些文章,每页只显示30个,看了下有100多页,立马沮丧了, ...
- bs4--官文--修改文档树
修改文档树 Beautiful Soup的强项是文档树的搜索,但同时也可以方便的修改文档树 修改tag的名称和属性 在 Attributes 的章节中已经介绍过这个功能,但是再看一遍也无妨. 重命名一 ...
随机推荐
- Nagios详解(基础、安装、配置文件解析及监控实例)
一.Nagios基础 1.简介Nagios是一款开源网络监视工具.可监控网络服务(SMTP.POP3.HTTP.NNTP.ICMP.SNMP.FTP.SSH.PING---).监控主机资源.根据需求设 ...
- C语言最后一次作业--总结报告
1.当初你是如何做出选择计算机专业的决定的? 经过一个学期,你的看法改变了么,为什么? 你觉得计算机是你喜欢的领域吗,它是你擅长的领域吗? 为什么? 当时选择计算机专业,是基于自己的高考分数和想出省的 ...
- poj-1056-IMMEDIATE DECODABILITY(字典)
Description An encoding of a set of symbols is said to be immediately decodable if no code for one s ...
- 【数据库】mysql深入理解乐观锁与悲观锁
转载:http://www.hollischuang.com/archives/934 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时 ...
- 【Flask】 WTForm表单编程
WTForm表单编程 在网页中,为了和用户进行信息交互总是不得不出现一些表单.flask设计了WTForm表单库来使flask可以更加简便地管理操作表单数据.WTForm中最重要的几个概念如下: Fo ...
- Nginx+Tomcat动静分离及Nginx优化
目的:nginx处理用户请求的静态页面,tomcat处理用户请求jsp页面,来实现动态分离,nginx处理静态页面效率远高于tomcat,这样一来就能更好的提高并发,处理性能. 准备软件: 下载jdk ...
- 关于BufferedReader的readLine方法遇到的坑
今天偶然用到BufferedReader,在读取文本后输出数据的时候遇到了隔行输出的问题. 如: 床前明月光 疑是地上霜 123456 789789 输出的为:疑是地上霜789789 找了一下,最终找 ...
- 简单爬虫 -- 以爬取NASA AOD数据(TIFF文件)为例
目录: 网站分析 爬取下载链接 爬取TIFF图片 1.网站分析 主页面:https://neo.sci.gsfc.nasa.gov/view.php?datasetId=MYDAL2_M_AER_OD ...
- 基于ECharts的饼状数据展示
一.导入ECharts文件 二.HTML代码 大小后期自己调 三.后台代码 四.js代码 不要问为什么- -我是扒下来的 可复制代码: //基于准备好的dom,初始化echarts实例 var myD ...
- Alpha第九天
Alpha第九天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...