关于Java白盒测试的介绍与方法
最近由于离职换一份软件测试的工作,顺便在温习一下软件测试的一些相关知识,于是便看到这一篇文章《测试方法之Java白盒测试(一)》
一、测试方法的分类
静态测试方法
动态测试方法
1.静态测试方法
不执行程序的测试方法。
主要用于测试文档和代码(文档)。
2.动态测试方法
通过运行程序来发现缺陷的测试方法。
√ 黑盒测试方法
√ 白盒测试方法
2.1黑盒测试
也称为功能测试、数据驱动测试、基于规格说明书测试。
从用户观点出发,主要以软件规格说明书为依据,对程序功能和接口进行测试,对
输入输出数据之间的对应关系进行测试。
它不涉及到程序的内部结构,如果外部特性本身有问题或规格说明书有问题,则无
法察觉。
√ 安全性测试、互操作性测试也属于功能测试。
√ 方法如大纲法、场景法、等价类、边界值、决策表、错误猜测等。
黑盒测试方法还用于测试软件的非功能性特性。
√ 非功能测试用于测试系统工作的怎么样,包括但不限于
✰ 可用性/可靠性/稳定性/健壮性/可恢复性测试
✰ 可维护性测试
✰ 易用性测试
✰ 可移植性/兼容性测试
✰ 配置测试
✰ 文档测试
✰ 国际化测试/本地化测试
√ 当不涉及程序内部结构时,上述测试类型也使用黑盒测试方法。
2.2白盒测试
也称结构测试、逻辑驱动测试、基于程序本身的测试、程序员测试。
结构测试需要完全了解程序结构和处理过程,按照程序内部逻辑测试程序,检验程
序中每条通路是否按照预定要求工作。
2.3黑盒测试与白盒测试的区别
二、静态测试方法
静态测试方法包括评审和静态分析方法。
1.评审
1.1评审的含义、过程和目的
1.2评审的角色
1.3评审的分类
文档审查
代码审查
代码走查
1.4代码审查
1.4.1代码审查的含义、过程和目的
1.4.2代码审查的方法和范围
具体做法方法
√ 互查
通常合格的代码应具备正确性、清晰性、规范性、一致性和高效性,概括起来,
代码审查的工作涵盖下列方面
√ 业务逻辑的审查
√ 算法的效率
√ 代码风格
✰ if(1j)与 if(j1),问:以上哪种代码风格较好?
✰ if(j>MAX_NUM)与 if(j>2000),哪个好?
√ 编程规则
1.5 代码走查
2.静态分析方法
2.1数据流分析
使用了未声明/定义的变量
变量声明了没有使用
2.2控制流分析
2.3复杂度分析
复杂度分析给出一组能描述程序代码的复杂度特征的度量。
计算复杂度
复杂度为:边(17)- 点(13)+ 2 = 6
3.静态测试的意义
4.静态测试可以发现的缺陷
引用一个没有定义值的变量;
从未使用的变量;
模块和组件之间接口不一致;
不可达代码(unreachable code)或死代码(dead code);
违背编程规则;
安全漏洞;
代码和软件模型的语法错误等。
5.一些静态分析工具
[OSS]代表开源软件,[PROPRIETARY]代表付费软件。
三、白盒测试方法
1.单元测试用例的设计方法
白盒测试方法
黑盒测试方法
以白盒测试方法为主,并适当地结合黑盒测试方法
2.白盒测试方法
逻辑覆盖法
√ 语句覆盖
√ 判定覆盖
√ 条件覆盖
√ 判定-条件覆盖
√ 条件组合覆盖
路径覆盖法
3.白盒测试方法的步骤
3.1获得需求、获得/画出程序流程图/算法图
3.2画出控制流图
根据需求来画
根据算法图/流程图来画
弄清预期结果
3.3选择覆盖方法设计测试用例
3.3.1语句覆盖法 C0
目标
√ 程序中的每个可执行语句至少被执行一次。
度量(覆盖率)
√ 被执行的语句数/所有可能的语句数。
√ 被执行的路径数/所有可能的路径数。
用例
√ a=2,b=1,c=6
√ 用例对语句的覆盖率:100%
√ 用例对路径的覆盖率:25%
语句覆盖能发现语句错误
语句覆盖不能发现逻辑错误/条件错误
3.3.2 分支/判定覆盖 C1
目标
√ 程序中的每个判定的取真分支和取假分支至少执行一次。
用例
√ a=2,b=1,c=6
√ a=-1,b=1,c=1
√ 用例对语句的覆盖率:100%
√ 用例对路径的覆盖率:50%
分支/判定覆盖能发现逻辑错误
分支/判定覆盖不能发现组合判断中的条件错误
3.3.3 条件覆盖 C2
目标
√ 程序每个判定中每个条件的可能取值至少满足一次。
未必比 C1 更全面。
不能发现逻辑错误。
用例
思考:覆盖率?
3.3.4 判定-条件覆盖 C1+C2
目标
√ 每个条件中的所有可能取值至少执行一次,同时,每个判定的可能结果至少执行一次。
可能会导致某些条件掩盖了另一些条件。
用例
3.3.5 条件组合覆盖/多条件覆盖 C3
目标
√ 每个判定中的所有的条件取值组合至少执行一次。
比 C2 全面。
用例
3.3.6 路径覆盖 C4
目标
√ 用例覆盖程序中的所有可能的执行路径。
不切实际
√ 因为涉及到相当长和几乎无穷尽的路径数。
√ 任何可能的循环在程序段中都被视为是可能的路径。
用例
路径覆盖优化
√ McCabe 的基路径方法
√ 从源节点到汇节点的线性独立路径数(根据圈复杂度计算)
✰ V(G)=e-n+2p=10-7+2=5
✰ 当规模很小时,我们可以直观地标识独立路径。
√ 以下给出的是用节点/边序列表示的路径:
✰ p1:A,B,C,G/1,4,9
✰ p2:A,B,C,B,C, G/1,4,3,4,9
✰ p3:A,B,E,F,G/1,5,8,10
✰ p4:A,D,E,F,G/2,6,8,10
✰ p5:A,D,F,G/2,7,10
案例
四、白盒测试工具
内存资源泄漏检查工具
√ 如 Numega 中的 BounceChecker,Rational 的 Purify 等;
代码覆盖率检查工具
√ 如 Numega 的 TrueCoverage , Rational 的 PureCoverage , TeleLogic 公司的 Logiscope;
代码性能检查工具
√ 如 Logiscope 和 Macabe 等。
静态源代码分析工具
√ 类似于编译器,能够检查源代码,发现违反编程语言语法规则和大量定义编程规范的代码。
面试题:
答案:
语句覆盖:
√ 要求:A<5 & B=5 & A=2 | X>2
√ 用例:A=2,B=5,X=3(此时X=多少都无所谓,因为A=2已经满足了条件)
判定覆盖
√ 要求:
A<5 & B=5 对一次,错一次 A=2 | X>2 对一次,错一次
√ 用例:
A=2,B=5,X=3
A=6,B=6,X=1
条件覆盖
√ 要求:
A<5 对错各一次 B=5 对错各一次 A=2 对错各一次 X>2 对错各一次
√ 用例:
A=2,B=5,X=3
A=6,B=6,X=1
判定-条件覆盖
√ 要求:
A<5 对错各一次 B=5 对错各一次 A<5 & B=5 对一次,错一次 A=2 对错各一次 X>2 对错各一次
A=2 | X>2 对一次,错一次
√ 用例:
A=2,B=5,X=3
A=6,B=6,X=1
多条件覆盖
√ 要求:
A<5对,B=5对 A<5对,B=5错 A<5错,B=5对 A<5错,B=5错 A=2对,X>2对
A=2对,X>2错
A=2错,X>2对
A=2错,X>2错
√ 用例:
A=2,B=5,X=3
A=6,B=6,X=1
A=2,B=6,X=1
A=6,B=5,X=3
路径覆盖
√ 要求:
A<5 & B=5 对,A=2 | X>2 对
A<5 & B=5 对,A=2 | X>2 错
A<5 & B=5 错,A=2 | X>2 对
A<5 & B=5 错,A=2 | X>2 错
√ 用例:
A=2,B=5,X=3
A=6,B=6,X=1
A=2,B=6,X=1
A=4,B=5,X=1
最终的用例:(按照一条用例尽可能多的去覆盖其他测方法)
A=2,B=5,X=3
A=6,B=6,X=1
A=2,B=6,X=1
A=4,B=5,X=1
A=6,B=5,X=3
五、使用 JUnit 进行单元测试
1.JUint 简介
JUnit 是一个开放源代码的 Java 测试框架,用于编写和运行可重复的测试。
JUnit 测试是程序员测试,即所谓白盒测试,是一个 Java 语言的单元测试框架,多数 Java 的开发环境都已经集成了 JUnit 作为单元测试的工具。
JUnit 在极限编程和重构(refactor)中被极力推荐使用,因为在实现自动单元测试的情况下可以大大的提高开发的效率。
每编写完一个函数之后,都应该对这个函数的方方面面进行测试,这样的测试我们称之为单元测试。
√ 在编写大型程序的时候,需要写成千上万个方法或函数,也许我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的。但是,我们同时应该确保每一个函数都完全正确,因为如果我们今后如果对程序进行扩展,用到了某个函数的其他功能,而这个功能有 bug 的话,那绝对是一件非常郁闷的事情。
2.JUnit 中的注解
JUnit 使用注解进行单元测试。
√ 注解用于修饰测试方法或测试类,写在测试方法或测试类的前面。同时,使用这些注解时,需要导入相应的包。
比较重要的注解大致有 Fixture 注解、@Test 注解、@Ignore 注解、@Parameters 注解、@RunWith 注解。
2.1 Fixture 注解
表示“在某些阶段必然被调用的代码”。
一般包括@Before 注解、@After 注解、@BeforeClass 注解、@AfterClass 注解,这些注解一般用于修饰测试方法,测试方法名随意。
@Before 注解
√ @Before 修饰的方法在每个测试方法之前执行。
@After 注解
√ @After 修饰的方法在在每个测试方法之后执行。
@BeforeClass 注解
√ @BeforeClass 修饰的方法在所有测试方法执行之前执行。
@AfterClass 注解
√ @AfterClass 修饰的方法在所有测试方法执行之后执行。
2.2 @Test 注解
@Test 注解
√ 用于修饰测试方法,表示要对被测试类的某个或某些方法进行测试。
@Test(timeout=xxx)注解
√ xxx 表示时间,以 ms 为单位;
√ 一般称为限时测试或超时测试,用于设置当前测试方法在一定时间内运行完,否则返回错误。
✰ 对于那些逻辑很复杂,循环嵌套比较深的程序,很有可能出现死循环,因此一定要采取一些预防措施,限时测试是一个很好的解决方案,给测试函数或方法设定一个执行时间,超过了这个时间,程序就会被系统强行终止,并且系统还会汇报该函数结束的原因是因为超时,这样就可以发现这些Bug 了。
2.3 @Ignore 注解
@Ignore 注解用于修饰测试方法,表示忽略测试用例;
其含义是“某些方法尚未完成,暂不参与此次测试”。这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore 标注删去,就可以进行正常的测试。
2.4 @Parameters 注解
用于修饰产生数据集合的方法,用于参数化。
测试时,可能需要测试大量不同的路径,从而要使用大量的数据,使用@Parameters注解只需要编写一个测试代码即可众多数据进行多次测试。
2.5 @RunWith 注解
用于指定一个测试运行器(Runner),@RunWith 用来修饰类,而不能修饰函数。
要对一个类指定了 Runner,那么这个类中的所有函数都被这个 Runner 来调用。
常用的内置测试运行器有 Parameterized(参数化数据)和 Suite(测试集)。
3.JUnit 中的方法
3.1 断言
用来断定程序中是否存在缺陷。
assertEquals(预期结果,实际结果)
√ 用于测试期望结果的断言,即测试两个对象是否相等,这个方法使用非常多。
fail(错误消息内容)
√ 其中错误消息可选,假如提供,将会在发生错误时报告这个消息。该断言会使测试立即失败,通常用在测试不能达到的分支上(如异常)。
3.2 setUp 和 tearDown
说明: JUnit中的setUP和tearDown跟Python中的unittest框架的setUP和tearDown是一个道理;setUpBeforeClass和setUpAfterClass与setUpClass和tearDownClass同理
在实际的测试中我们测试某个类的功能是常常需要执行一些共同的操作,完成以后需要销毁所占用的资源(例如网络连接、数据库连接,关闭打开的文件等),JUnit提供了 setUp 方法、tearDown 方法、setUpBeforeClass 方法、tearDownAfterClass方法。
setUp方法
√ 在每个测试方法之前都会运行。
√ 主要实现测试前的初始化工作。
tearDown方法
√ 在每个测试方法结束以后都会执行。
√ 主要实现测试完成后的垃圾回收等工作。
setUpBeforeClass方法
√ 在所有测试方法执行之前执行。
tearDownAfterClass方法
√ 在所有测试方法执行之后执行。
实际使用时,setUp 方法可用@Before 注解代替,tearDown 方法可用@After 注解代替,setUpBeforeClass 方法可用@BeforeClass 代替,tearDownAfterClass 方法可用 @AfterClass 代替。
————————————————
版权声明:本文为CSDN博主「cdtaogang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41782425/article/details/103615186
最后我再推荐一个微信公众账号:小海购FL(shenghuohui2021)实时更新淘宝优惠券,天猫优惠券,拼多多,京东优惠券直接领取平台,先领劵在购物不仅自购省钱,还能分享赚钱。