测试用例应该具备的特征
好的测试用例
- 等价类划分法
边界值法
路径分析法
断言
简单案例
- 目标代码及功能说明
单元测试设计
总结
前言
=================================================================
思量良久在考虑要不要写这一篇,是不是直接看门见山将在项目中怎么进行单元测试。最后想想觉得是不是太猴急了写那样,就好比你想和一个姑娘滚床单,是不是先应该请姑娘吃顿饭、送点礼物什么的。所以我才决定写这篇序言,让我们一起慢慢的揭开单元测试的面纱。
什么是单元测试
======================================================================
这个在网上有很详细的解释。我这就简单的给出一个概念:
单元测试是开发者编写一小段代码,用于检测被测代码的一个很小的、很明确的功能是否正确。
单元测试是对软件基本单元进行的测试,实际应用中是对public 函数进行的测试。
执行单元测试,是为了验证某段代码的行为确实和开发者所期望的一致。
为什么要进行单元测试
=========================================================================
理由千千万,我只宠这三点:
减少调试时间
自动化测试
令设计变得更好
我们或多或少也都听说过单元测试,只知道用来检测写的代码有没有问题,这导致之前都没有写过测试用例,测试一些重要的方法最多也一个 main方法正常的数据调通了就过了,这样导致后期出现各种各样的问题,一遍遍的改代码,一遍遍的改bug。费时费力还不一定能处理好。我以为这是软件开发的诟病,其实不然,是因为我们不能确认我们写的那部分代码没有问题,所以总花费很长时间找问题上。所以才需要进行单元测试,虽然在刚开始写单元测试会花费时间,但是我们单元测试全都通过之后,我们对自己写的代码更有自信,可以确定没有代码没有问题了,而不是自己认为没有问题的那种。这样后期修复bug,也可以通过单元测试哪些执行成功哪些执行失败可以快速的定位到问题。我觉得这一点就足以让我们为我们写的代码编写相应的单元测试啦,毕竟找问题真是太痛苦,大家应该也深有体会。
单元测试怎么做
======================================================================
简单而言,就是对一个 public 方法编写测试用例,那测试用例又怎么写呢?
测试用例说白了也是一个方法,用来验证目标方法是否符合我们的预期。
那这样就知道怎么写了吧,就是和我们平时写方法一样,但是它有一个标准
俗称 “3A 模式” Arrange-Act-Assert(准备上下文环境–执行被测函数–断言)。也就是说一个测试用例的方法包含三部分就可以了。
测试用例应该具备的特征
==========================================================================
上面说的测试用例包含这三部分就可以了,那我们的测试用例应该具备怎样的特征呢,短小精悍且快准繁
小:一个测试几行代码(15)
精准:一个测试之测一个场景
隔离:每个测试都可以独立、重复运行,无耦合
快:每个测试都应该是毫秒级别的
频繁:应该频繁的执行,没增加、修改、删除一个测试都要运行一遍
那什么样的是好的单元测试呢?
自动化
可重复的
彻底的
独立的
专业的
好的测试用例
=====================================================================
测试用例应该短小精悍且快准狠。这些是对测试用例的函数本身而言的,但在实际项目中出问题往往就是某些情况没有考虑到导致程序出错的,我们在自测的时候往往会测试正常数据的情况然而却忽略的了错误情况和边界值的测试,这些才是校验一个项目的健壮性的标准。所以好的测试用例必定是有全面的测试数据。那怎样获取全面的测试数据呢?
在这之前需要知道哪些是好的测试数据
最优可能抓住错误的
不是重复的,多余的
一组相似测试用例中最有效的
既不是太简单,也不是太复杂
那怎样获取好的测试数据呢?有等价类划分法、边界值法、路径分析法。
等价类划分法
等价类划分法是把所有可能的输入数据,划分成若干个子集,然后从每个子集中选取少数的具有代表性的数据作为测试用例。
该方法是一种重要的、常用的黑盒测试用例设计方法。
有效等价类:对程序的规范说明是合理的,有意义的输入数据构成的集合。
无效等价类:对程序的规范说明不是合理的或者无意义的输入数据构成的集合。
我们来看一个例子:计算两个点距离的函数
public double getDistance(double x1, double y1, double x2, double y2)
边界值法
边界值分析法是对输入或者输出的边界值进行测试的一组黑盒测试方法。
通常情况下,边界值分析法是作为等价类划分法的补充,这种情况下,其测试用例来自等价类的边界。
比如上面一个例子中取边界值做为测试用例。
路径分析法
基本路径测试是一种白盒测试方法,它在程序控制图的基础上,通过分析程序的流程,构造导出基本可执行路径集合,从而设计测试用例的方法。
设计出的测试用例要保证在测试程序中的每一个可执行语句至少执行一次。
我们来看一个例子
可能的路径为:
1-2-3-4-5
1-2-3-4-6
1-2-4-5
1-2-4-6
断言
=================================================================
我们这里说的断言只是Junit断言,java 本身也有断言的,但是貌似我们使用的很少以至于我们都忘记了它的存在。
Junit 断言说是断言,其实也就是一份方法,没有什么语法。我们测试用例中使用断言,也就是使用这些方法来进行验证是否达到我们的预期。
方法有很多,大家可以看看源码,我这里给出几个常见的。
| 函数名 | 描述 |
| — | — |
| assertEquals | 判断实际产生的值与期望值是否相等 |
| assertNull | 判断对象是否为null |
| assertNotNull | 判断对象是否为非null |
| assertSame | 判断实际产生的对象与期望对象是否为同一个对象 |
| assertNotSame | 判断实际产生的对象与期望对象是否为不同的对象 |
| assertTrue | 判断bool变量是否为真 |
| assertFalse | 判断bool变量是否为假 |
| Fail | 使测试立即失败 |
上面这样说好像没有什么效果,我们先来看其中一个断言方法的源代码。我们就看第一个assertEquals 吧
可以看到有很多assertEquals方法。这样的方法的重载在底层很常见。我们来看下三个参数类似是Object的这个吧。
public static void assertEquals(String message, Object expected, Object actual) {
if (!equalsRegardingNull(expected, actual)) {
if (expected instanceof String && actual instanceof String) {
String cleanMessage = message == null ? “” : message;
throw new ComparisonFailure(cleanMessage, (String)expected, (String)actual);
} else {
failNotEquals(message, expected, actual);
}
}
}
private static boolean equalsRegardingNull(Object expected, Object actual) {
if (expected == null) {
return actual == null;
} else {
return isEquals(expected, actual);
}
}
private static boolean isEquals(Object expected, Object actual) {
return expected.equals(actual);
}
private static void failNotEquals(String message, Object expected, Object actual) {
fail(format(message, expected, actual));
}
static String format(String message, Object expected, Object actual) {
String formatted = “”;
if (message != null && !message.equals(“”)) {
formatted = message + " ";
}
String expectedString = String.valueOf(expected);
String actualString = String.valueOf(actual);
return expectedString.equals(actualString) ? formatted + "expected: " + formatClassAndValue(expected, expectedString) + " but was: " + formatClassAndValue(actual, actualString) : formatted + “expected: but was:”;
}
equalsRegardingNull() 函数就是判断两个值是否相等,底层还是相当于用的object.equals()。如果两个值相等就断言通过,如果不相等就判断expected和actual是否是string类型,如果是直接将message输出。如果不是就failNotEquals().failNotEquals方法的源码我也贴出来了,可以看也很简单,就是message、expected、actual转换成string格式输出出来,并执行fail()使得测试失败。
从上面看断言也就不过如此(Junit 断言)。我们会使用常用的方法就可以写好测试用例啦,至于其他的方法,我们用到的时候可以直接其源代码,毕竟也不会很复杂。
简单案例
===================================================================
目标代码及功能说明
这段代码在项目中的作用是对特殊字段的对应的值进行处理并返回。
如果字段是包含time,那将值改成日期格式返回。
如果字段是包含iphone,那将值截取后11位返回。
其他情况,直接返回。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数软件测试工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
-zZzKRy3g-1712734678351)]
[外链图片转存中…(img-i84ZaIu1-1712734678351)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-0USouO6x-1712734678352)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...