【格言1】若程序的某项功能没有经过自动测试,那该功能基本等于不存在
【格言2】敏捷测试的第一步就是不要敏捷,先一步步把自动化做好,把持续集成做起来,创建更多的测试工具来提高测试效率,把质量反馈系统做起来,代码质量检查做起来等等,这些建立起来后,你就很敏捷了
【格言3】如果在功能测试和单元测试选一个来做的话,那你应该选择功能测试,70%的应用程序错误都可以通过功能测试来找回的。
参考文献
1、《junit in action》 电子工业出版社
2、《软件测试的艺术》
机械工业出版社【力荐】
一、理论知识点
1、什么叫做测试阶段,什么叫做测试方法?
测试阶段:单元测试、集成测试、功能测试、系统测试,这个叫做测试阶段
测试方法:从大的分类讲,白盒测试、黑盒测试、灰盒测试、人工测试,这个叫做测试方法
2、什么样的测试叫做单元测试?单元到底是什么,多小多大的东西才叫单元?
百度百科说法:要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。
《junit in action》说法:单元测试测的是独立的一个工作单元。在java应用程序中,“独立的一个工作单元”常常指的是一个方法。一个工作单元是一项任务,它不依赖于其他任务的完成。
《软件测试的艺术》说法:单元测试是对程序中的单个子程序、子程序或过程进行测试的过程,是对构成程序的较小模块的测试。
各位看官,你们看懂了么?反正我没看懂。上面有说单元是java中的一个类,又说是java代码中的一个函数方法,这到底是闹哪样。以下是我猜测的结论:被测单元的粒度大小是由程序员规定的,“单元”不仅仅是对应一个代码中方法或某个类,应该说一个具有独立任务的功能代码短(软件编程有一个单一原则,一个方法对应一个功能点)。
3、什么样的测试叫做集成测试?
单元A + 单元B = 更大单元C
单元A:保存用户数据信息到数据库
单元B:下发邮件(短信)到用户邮箱(手机)
更大单元C:注册功能
插曲,请回过头来理解这句话:“《junit in action》一个工作单元是一项任务,它不依赖于其他任务的完成”。第一:单元A和单元B互不依赖;第二:输入可以使用其他单元的输出数据
集成测试:各个单元组合测试,完成某一大功能的测试。单元A测试正确之后,把单元B加入测试。注意:尽量使用增量测试,就是说A,B,AB,C,ABC,D,ABCD这样顺序,而不是A,B,C,D,ABCD这样,虽然少了一点,但是错误不好定位。
4、什么样的测试叫做功能测试?
看看上面的注册功能测试C,可以当作功能测试中的一个步骤了。
功能测试:测试软件表现的是不是符合spec上面规定的
5、什么样的测试叫做系统测试?
系统测试:测试软件表现的是不是符合最初目标(用户需求),包含安全性测试、性能测试、容量测试、可靠性测试等。
6、黑盒测试有哪些方法?
黑盒测试:有正确输入和预期的输出,用正确的输入来测试软件,看看输出数据(表现状态)是否和预期的一致。
我们只讲主要的:等价类测试、边界分析值测试、错误猜测、因果图等方法
等价类测试:
有效(正确的)输入作为一类,其他无效的作为另一类,注意了其他无效的应该是分开的
比如用户名8到16个字符,正确的有效的一个类:对于8个小于16个
错误的类需要分开,而不能写成这样作为一个等价类:小于8或者大于16,因为编译器遇到小于8的时候,就不会忽略后面的错误了。
错误等价类:1、小于8 2、大于16 独立性
边界测试:一般是对数量、个数啊、是、否、有、无、相同、不同、最高、最低进行边界数据测试(包含输出的结果反推到输入数据,比如y=sinx函数,他对输入x没有边界,但是对输出y是有边界的,那就是当y=1的时候,x的那个值需要被测试)
原则:
1、有效值边界,最大值、最小值、比最小少一点、比最大大一点,比如用户名是8到16位,那么边界测试用例数据包含:8,16,7,17
2、输入和输出是有序的,注意第一个和最后一个元素
3、数据库最大记录数,最小记录数
因果图测试:一般是两个输入组合作为条件产生输出的。比如买雪碧,需要两个输入条件1:投入钱币数额2、用户按了哪个按钮。
可能用户投入的是1.5元,按了可乐,那自动饮料机就会输出可乐了。。。输出由两个输入组合决定。
错误猜测:靠猜,可能某些容易犯错误。
7、白盒测试有哪些方法?
白盒测试:语句覆盖测试、判定覆盖测试、条件覆盖测试、判定/条件覆盖测试、多重条件覆盖测试等。
亲,在实际项目中比较靠谱的是多重条件覆盖测试,其他的你可以忘掉。
不想看具体说明的,下面可以跳过
-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-
白盒测试:覆盖程序逻辑结构(源代码)的程度,完全的白盒测试是将程序中每条路径都执行到,然而对有带有循环的程序,完成路径测试是不切合实际的。
完全路径测试是测试不出来真正的错误。语句覆盖——每条语句都覆盖过——较弱的逻辑覆盖准则
判定覆盖或分支覆盖——较强的逻辑覆盖准则。要求必须编写足够的测试用例,使得每一个判断都至少有一个为真和为假的输出结果。每一条语句都必须覆盖过
If(b==2 || a > 1) 这种判断覆盖,他只负责if真和假的路径,测试用例可以这样 b=2 a=1或者b=3 a=1 。但是正确的语句应该是if(b==2 || a <1),这样测试用例测试不出来
条件覆盖——要对if中的判断语句每个条件的所有可能都覆盖到,比如IF(A&B) 测试用例可以是:1(A为真,B为假) 或者 2(A为假,B为真),你瞧瞧A的真假都设计到,B的真假都设计到了,他们满足条件覆盖的测试用例,但是if语句中的then没有被执行。于是引入了判定/条件覆盖
判定/条件覆盖准则——较强的测试用例设计准则,每个判断中的每个条件的所有可能的结果至少执行一次,每个判断的所有可能的结果至少执行一次。要求是设计出充足的测试用例。
还是例子IF(A&B) ,1:条件A和B所有可能结果是A为真,A为假,B为真,B为假,
2:判断的所有可能A&B为真 , A&B为假。
测试用例:1(A为真,B为真) 2(A为假,B为假)满足这个准则,想想有问题么?
具体点if(a>0 && b>1) 其中A代表a>0, B代表b>1
测试用例:1(a=2, b=3)真,执行then语句;2(a=-3,b=1)假,不执行then语句。满足上面判定/条件覆盖准则
问题:其实逻辑判断语句b>1是错误的,他应该是b>2
正确的逻辑代码是if(a>0 && b>2)
结论:判断/条件覆盖准则的测试用例发现不了这个问题。
多重条件覆盖准则——,将每个判定中的所有可能的条件结果进行组合,所有的入口点都至少执行一次。注意了,不是多重判定/条件覆盖准则,但是他满足了判定准则、条件覆盖准则(不用说)、判定/条件覆盖准则。IF(A&B)
对于这个,测试用例必须覆盖下面4个组合是:
A
|
B
|
结果
|
0
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
0
|
1
|
1
|
1
|
\
较上面多了2个
他做到了条件组合,但是并没有做到一个方法内部的判定组合:
If(a>1
&& b==0) {
X
= x /a; 。。。。。。。。。。。。。。。。。。。。。。。。。运行1
}
If(a == 2 || x
> 1) {
X
= x + 1;。。。。。。。。。。。。。。。。。。。。。。。。。。。运行2
}
8种条件组合
|
a
|
b
|
x
|
结果
|
1
|
>1
|
=0
|
|
1
|
2
|
>1
|
<>0
|
|
×
|
3
|
<=1
|
=0
|
|
×
|
4
|
<=1
|
<>0
|
|
×
|
5
|
=2
|
|
>1
|
2
|
6
|
=2
|
|
<=1
|
×
|
7
|
<>2
|
|
>1
|
×
|
8
|
<>2
|
|
<=1
|
×
|
只要测试用例覆盖了以上的组合就可以了
a
|
b
|
x
|
覆盖了
|
2
|
0
|
4
|
1,5
|
2
|
1
|
1
|
2,6
|
1
|
0
|
2
|
3,7
|
1
|
1
|
1
|
4,8
|
上面给出的4个具体的测试用例,覆盖了所有的条件组合。同样也覆盖了所有的语句,但是某些组合判定没有被覆盖到。比如1,6组合,运行了语句1,其他不运行。
-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-
总结:从上面几个来看,最完整的应该建议使用多重条件覆盖测试准则。
8、哪个测试阶段会使用某些测试方法?
1、单元测试
若你是敏捷开发者,单元测试肯定是黑盒测试方法。(因为先写测试代码)
若不是,单元测试使用白盒测试、黑盒测试多种方法组合
2、集成测试
集成测试是单元测试基础上,如何把单元模块组装起来一起测试,测试方法采用黑盒。组装方式有自顶向下和自下向上两种。
比如之前说的
单元A + 单元B
+ 单元C = 更大单元D
单元A:保存用户数据信息到远程UCenter数据库
单元B:下发邮件(短信)到用户邮箱(手机)
单元C:保存用户数据信息到本地数据库
更大单元D:注册功能,保存成功之后
对于单元D,要求是单元A成功后,才能运行单元B和C,他们的关系A在顶端,BC在下面
自顶向下:A, B, C,AB,ABC
自下向上:B ,C, A,BC,ABC
原则:关键单元先测,然后在组合其他的
注意:A是调用远程接口,我们在开发的时候远程代码还没有完成,那我们该如何完成上面的集成测试了?使用mock,自己模拟写一个A的功能,此功能不处理任何逻辑。或者用stub,需要你实现逻辑。Ps:为什么计算机中把stub翻译成桩,很难理解!!
9、一般测试的步骤是什么样的?
第一步:单元测试
1、选择测试方法,到底是选择白盒测试、还是黑盒测试
一:一般是使用组合测试方法,但是如果是敏捷开发方式,只能用黑盒测试方法了
二:选择白盒测试中的多重条件测试准则
三:如果接口文档中说输出是由输入条件组合才能得出,请使用黑盒的因果图分析方法
四:任何情况都要使用边界值分析方法
五:其他情况,使用等价类和错误猜测技术增加更多的测试用例进行补充
2、设计测试用例
根据1中列出来的测试方法来列出测试用例,覆盖白盒测试中的条件组合,
表格如下:
测试用例编号
|
输入
|
预期的输出
|
注释
|
1
|
|
没有返回值,表示成功
|
|
2
|
。。。。
|
。。。。
|
。。。
|
原则1:测试用例尽量少
原则2:一个测试用例覆盖尽量覆盖多个组合(其实和原则1相辅相成)
3、起单元测试方法名称
某被测方法或者功能userRegister
原则1:测试名使用驼峰式
xxYyyZzz
原则2:命名规则,由以下组成test+被测方法+预期输出的类型。如上面测试用例1,他的命名testUserRegisterSuccess。
原则3:一个测试方法,只处理一种预期类型(个人理解)。
在《junit in action》书中说道:“一个单元测试等于一个测试方法,不要试图把多个测试塞进一个方法” 什么意思啊?看懂了么?
表格如下:
方法名
|
检查到的测试用例(这里是测试用例表中的序号)
|
testAccountExistUserInfoNull
|
9
|
testAccountExistUsernameExisted
|
3
|
testAccountExistEmailExisted
|
4
|
testAccountExistMobileNumExisted
|
6
|
testAccountExistUserTrue
|
1、2、5
|
4、写测试代码方法内部使用Assert.fail(“未测试”);Why?避免遗漏测试方法,养成好习惯:)
5、最后填充测试方法
原则一:对于assertTrue/assertNotNull/assertNull/assertFalse测试方法,请记住第一个参数sring需要写,便于失败原因。
原则二:把共有初始化行为放在setUp方法中
第二步:集成测试
1、有时候需要写mock或者stub
2、重要功能的单元测试先加进来,然后加上不重要的单元
其他:功能测试、系统测试,这里不讲
二、具体实践
0、已有模块代码:
此模块的测试描述:用户判断用户名、手机号码、邮箱地址是否重复
1、选择测试方法,到底是选择白盒测试、还是黑盒测试
N1:选择白盒测试中的多重条件测试
N2:选择黑盒测试中的边界值分析法
N3:其他补充(错误猜测法)
2、设计测试用例
N1:基于上面多重条件测试方法。
把所有的if和while等判断语句找出来
判定(代码行数)
|
条件
|
正确结果
|
错误结果
|
297
|
User.getUsername()!=null
|
用户名不为空
|
用户名为空
|
299
|
USERNAME_EXIST.equals(resultStr)
|
用户名已经存在
|
用户名不存在
|
304
|
User.getEmail()!=null
|
邮箱地址不为空
|
邮箱地址为空
|
306
|
EMAIL_EXIST.equals(resultStr)
|
邮箱地址已经存在
|
邮箱地址不存在
|
311
|
User.getMobile()!=null
|
手机不为空
|
手机为空
|
311
|
User.getMobile().getMobileNum()!=null
|
手机号码不为空
|
手机号码为空
|
313
|
MOBILE_EXIST.equals(resultStr)
|
手机号码已经存在
|
手机号码不存在
|
1、用户名为空
2、用户名不为空,用户名重复
3、用户名不为空,用户名不重复
4、邮箱地址为空
5、邮箱地址不为空,邮箱地址重复
6、邮箱地址不为空,邮箱地址不重复
7、手机号码为空
8、手机号码不为空,手机号码重复
9、手机号码不为空,手机号码不重复
那么测试用例必须覆盖上面的9个组合,注意了:一个测试用例尽量覆盖多个上面的组合条件
测试用例编号
|
输入
|
预期的输出
|
注释
|
1
|
username=””
email=”email”//邮箱地址可以注册
mobileNum=””
|
程序状态不变
Result=0
|
覆盖了条件:1、6、7
|
2
|
username=“username”
email=””
mobileNum=””
此用户名不存在数据库中
需要给出数据库预置的内容
|
程序状态不变
Result=0
|
覆盖了条件:
3、4、7
|
3
|
username=”existed_username”
email=””
mobileNum=””
|
程序返回1
|
覆盖了条件:
2、4、7
|
4
|
email =”existed_ email”
username=””
mobileNum=””
|
程序返回2
|
覆盖了条件:
1、5、7
|
5
|
mobileNum =“123123123123”
此手机号码不存在数据库中
需要给出数据库预置的内容
Username=””
Email=””
|
程序状态不变
Result=0
|
覆盖了:1、4、9
|
6
|
mobileNum =”32132132131”
此手机号码重复
Username=””
Email=””
|
程序返回3
|
覆盖了:1、4、8
|
7
|
Username=””
Email=””
mobileNum=””
|
程序返回4
|
覆盖了:1、4、7
|
N2:选择黑盒测试中的边界值分析法
还记的上面讲的原则么?
原则:
1、有效值边界,最大值、最小值、比最小少一点、比最大大一点,比如用户名是8到16位,那么边界测试用例数据包含:8,16,7,17
2、输入和输出是有序的,注意第一个和最后一个元素
3、数据库最大记录数,最小记录数
但是我发现这个单元很难找到边界值,单元并没有对输入值范围、大小进行明确的规定。读者,您有好的用例么?帮忙给出。谢谢了。
N3:其他补充(错误猜测法)
User如果为空,上面的方法就是废物,而且运行期会抛出空指针异常。所以有时候设计用例的时候,会反过来发现代码设计的有问题。这部分白盒测试没办法指导。
测试用例编号
|
输入
|
预期的输出
|
注释
|
8
|
User=null
|
程序返回4
|
返回是无效参数
|
其他的错误猜想,没想到,请各位看官指点一二。
3、起单元测试方法名称
方法
|
检查到的测试用例
|
testAccountExistUserInfoNull
|
7,8
|
testAccountExistUsernameExisted
|
3
|
testAccountExistEmailExisted
|
4
|
testAccountExistMobileNumExisted
|
6
|
testAccountExistUserTrue
|
1、2、5
|
4、写测试代码方法内部使用Assert.fail(“未测试”);Why?避免遗漏测试方法,养成好习惯:)
5、最后填充测试方法
待续~
三、总结
分享到:
相关推荐
单元测试是测试一个代码单元的行为,而集成测试是测试多个组件之间的集成。在 Spring Boot 中,我们可以使用 JUnit 和 Hamcrest 框架来进行单元测试,然后使用@SpringBootTest 注解来标记集成测试。 本文详细介绍了...
单元测试是软件开发中的一个重要环节,它主要针对程序的最小可测试单元——模块进行。单元测试的基本属性包括明确的功能定义、可定义的规格以及与其他单元清晰的接口划分。其目的主要是发现模块内部的错误,采用的是...
根据不同的测试目的与范围,可以将测试分为单元测试、集成测试以及系统测试等不同阶段。本文将详细探讨这三种测试的区别及其各自的特点。 ### 单元测试 单元测试(Unit Testing)主要关注于对软件中的最小可测试单元...
单元测试就是对已实现的软件最小单元进行测试,以保证...采用大棒集成方法,先是对每一个子模块进行测试(单元测试阶段),然后将所有模块一次性的全部集成起来进行集成测试 。 自顶向下:深度优先 自顶向下:宽度优先
"测试入门--7单元测试"这个主题聚焦于单元测试这一特定的测试方法,它是软件开发过程中的基础环节。单元测试是对软件中的最小可测试单元进行检查和验证,通常是函数、方法或类。下面将深入探讨单元测试的原理、目的...
WinAMS 嵌入式软件单元测试集成测试自动化工具 WinAMS 是一种嵌入式软件单元测试工具,旨在提供自动化的单元测试解决方案,满足汽车行业对安全性要求极高的需求。该工具支持嵌入式微机,能够对嵌入式 C/C++ 软件...
单元软件测试中基于V模型的单元测试,集成测试,系统测试1)为什么要进行单元测试:系统测试是一种黑盒测试,也就是不需要了解系统内部结构,只关心外部实现,那么这样发现的问题将不会太彻底,而单元测试是一种白盒...
黑盒测试、白盒测试、单元测试、集成测试、系统测试、验收测试的区别 黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。 白盒测试:已知产品的内部工作过程,可以通过测试证明每...
在.NET开发过程中,单元测试是一项至关重要的任务,它有助于确保代码的质量、可维护性和稳定性。单元测试允许开发者独立地测试代码的各个部分,确保每个功能模块都能按预期工作。本案例将深入探讨如何在.NET环境中...
在软件开发过程中,单元测试是一种重要的质量保证手段,它针对代码的最小可测试单元——函数、方法或类,进行独立验证。本示例主要聚焦于C++编程语言中的单元测试,我们将探讨如何进行白盒测试的基本实现方法和结构...
软件测试单元测试和集成测试.ppt
集成测试的模板
本文旨在探讨软件开发过程中的几种主要测试方法:单元测试、集成测试、确认测试及系统测试,并对其应用场景与实践方法进行深入解析。 #### 消除对软件测试的误解 目前,在软件开发领域内,对于软件测试仍存在一些...
在C/C++项目中应用测试驱动开发(TDD)的方法,从单元测试到集成测试,详尽介绍了测试的基础、框架选择、实际应用及最佳实践。文章首先阐述了TDD的核心理念及其优势,包括提升代码质量、减少错误和改进设计等。接着...
单元集成测试系统验收不仅是确保软件产品质量的重要手段,也是提升团队开发效率的有效方式之一。通过遵循上述原则和方法,可以构建出更加稳定可靠的软件系统。在未来的发展中,随着技术的进步和新工具的应用,单元...
**系统集成测试**是一项重要的软件质量保证活动,旨在验证不同模块或组件之间的集成是否符合预期的功能和性能要求。它不仅关注单个模块的行为,还着重于检测模块间的交互问题。 #### 二、报告模板内容详解 **1. ...