测试驱动开发实践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 的章节中已经介绍过这个功能,但是再看一遍也无妨. 重命名一 ...
随机推荐
- 用three.js创建一个简易的天空盒
本文创建的天空盒是用六张图片来创建的.笔者会论述两种方法来创建,都是最简单基本的方法,不涉及着色器的使用.一种是创建一个盒子,然后将图片作为盒子6个面的纹理贴上来创建.另一种则是简单的将纹理作为场景的 ...
- 设计模式 --> (8)组合模式
组合模式 组合模式,是为了解决整体和部分的一致对待的问题而产生的,要求这个整体与部分有一致的操作或行为.部分和整体都继承与一个公共的抽象类,这样,外部使用它们时是一致的,不用管是整体还是部分,使用一个 ...
- Spring Cloud Consul 实现服务注册和发现
Spring Cloud 是一个基于 Spring Boot 实现的云应用开发工具,它为基于 JVM 的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布 ...
- python socket编程制作后门木马(原创)
不知道为啥,懒得解释怎么写出来的,直接上代码,爱看不看 Client: 简单连接服务器 #!/usr/bin/python #coding:utf-8 import socket import sy ...
- kvm之三:本地安装虚拟机
1.格式化新添加的磁盘 [root@kvm ~ ::]#fdisk /dev/sdb Command (m for help): n //新建分区 Command action e extended ...
- css3控制div上下跳动-效果图
效果图演示,源代码
- Leetcode 12——Integer to Roman
12.Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be withi ...
- 20162328蔡文琛week06
学号 2016-2017-2 <程序设计与数据结构>第X周学习总结 教材学习内容总结 继承是从已有类派生出一个新类的过程. 继承的目的之一之复用已有的软件. 继承呢在子类和父类见建立了is ...
- ios swift例子源码网址总结
http://blog.csdn.net/woaifen3344/article/details/40079351 http://www.ruanman.net/swift/learn/4607.ht ...
- 亚马逊的PuTTY连接AWS出现network error connection refused,终极解决方案。
使用PuTTY连接AWS的时候,一直出现network error connection refused.百度了这个问题,大家都说是SSH要设置成22.但是我已经设置过了,为什么还是遇到这个问题呢? ...