白盒测试可以理解为一种专门用于评估代码及程序内部结构的测试技术,也有结构测试这么一说,因为白盒测试会涉及查看代码的结构。对于测试工程师而言,如果你知道软件产品系统或应用程序的内部结构,就尽早展开针对性的测试以确保程序内部操作是按照规范运行的,并且所有内部结构都能得到充分的测试执行。 随着互联网大数据AI时代的接踵而至,测试人员从原始的手工功能测试,进化到面向不同方向的自动化测试,与此同时职能岗位也从测试升级为测试开发。对于测试工程师而言,总有需要持续学习的东西,无论是领域、过程还是技术。今天我们就来聊一聊测试人员的技术阴暗面,为什么说这是一个阴暗面,因为大家不擅长嘛,无论是立志于从事测试行业的学生,还是在职测试工程师,都会有意无意避免这种被认为非常复杂、而对开发人员来说却又轻而易举的测试技术。没错,就是白盒测试! 1。白盒测试覆盖率(Coverage) 白盒测试中约定的代码覆盖率包含以下几个核心准则: (1)代码片段覆盖确保指定代码块中的每个代码语句都能被执行一次; (2)分支覆盖或节点测试覆盖每个代码分支中的所有可能; (3)复合条件覆盖对于多个条件,采用多个路径不同组合的情况下,确保每个条件都被触发执行对应的代码片段; (4)基础路径测试针对代码中每个独立路径进行测试; (5)数据流测试(DFT)DFT看似是个新名词,实则指的是特定变量的追踪,在测试中我们往往需要追踪一个变量值的变化(这似乎有点像你在pycharm中针对一个循环变量做断点调试,观察每次循环中变量值的变化),在白盒测试中,我们需要在代码中定义一组中间路径,用于跟踪我们关心的变量经过每一次代码计算后该值的变化。简而言之,跟踪每个数据变量并验证其是否被正确使用。这种方法往往会发现一些隐藏的bug,比如使用了未经初始化的变量,或者虽然声明了但却一直没有被使用的变量,等等; (6)路径测试即覆盖代码中所有可能的路径,这项任务也是相当耗时的; (7)循环测试这种测试策略分别针对于单个循环、串联循环(即循环中调用了包含循环的代码块)和嵌套循环有关。使用这种方法用于测试独立循环和依赖循环中涉及的代码及所关注的变量; 2。为什么需要白盒测试? 我们从代码质量保障和潜在BUG挖掘这两层面说明白盒测试的必要性: 确保以下几点: (1)确保模块中所有独立路径至少被执行一次。 (2)确保所有合乎逻辑的判断都要验证其真假值。 (3)确保所有循环边界值,及其操作范围内的内部数据结构的有效性。 尽可能发现由于以下因素引起的BUG: (4)当我们还未将功能的设计实现及其相关条件控制用代码来实现时,逻辑错误往往会潜入到我们的工作中; (5)程序逻辑与实际实现的差异而导致的设计错误; (6)程序语法语义错误及程序书写不规范引起的错误; 3。白盒测试能力要求测试范畴 由于我们需要编写测试用例来确保程序逻辑的完整覆盖,对程序的了解和认知是先决条件,我们必须详细理解被测代码及测试需求。对于大型系统进行全面测试是不可能的,毕竟这非常耗时耗力,我们不可能针对程序中循环的每一条路径进行测试,这就意味着测试人员需要通过选择重要的逻辑路径和数据结构进行切实有效且可行的测试。 在企业中进行白盒测试时,开发人员和测试人员往往会协同工作,例如分析哪一行代码被实际执行的,哪一行代码由于逻辑缺失而未被执行,哪些片断的代码存在拼写错误等。因此,白盒测试对代码的能力要求较高,需要对被测试代码使用的语言及代码间的逻辑关系有相当程度的认知及驾驭能力。 4。白盒测试主要测试技术 白盒测试技术主要分为:语句覆盖,分支覆盖,路径覆盖这三大类。值得一提的是这三类覆盖技术并不能识别出任何需要被修复的BUG或缺陷,而是为了发现程序中存在的那些从未被执行的语句,并以此为基础展开后续的测试活动。下面就这三大白盒测试技术逐一介绍。 (1)语句覆盖 在程序设计语言中,语句只不过是一行代码或一条指令,这些代码指令唯有计算机可以理解并据此进行执行操作。当程序中的语句被编译并转换为目标代码,且程序处于运行模式下,这些语句就成为可被执行的可执行语句。因此语句覆盖率,顾名思义,它是验证每一行代码是否至少被执行一次的方法。 (2)分支覆盖 程序设计语言中的分支类似于IF语句,IF语句由真和假两个分支构成,因此在分支覆盖率(有时也称为决策覆盖率)中,我们验证每个分支是否至少被执行一次。例如,对于任何IF语句将会有两个测试条件:一个是为了验证分支的正确性,另一个是验证错误分支。从理论上看,分支覆盖是一种测试方法,它在执行时确保了每个决策点的每个分支都应该被执行。 (3)路径覆盖 路径覆盖针对程序中所有路径的测试,这是一种全面的技术,可以确保程序中所有路径至少被遍历一次。路径覆盖比分支覆盖更强大,在测试相对复杂的程序结构时更具实用意义。 5。白盒测试DEMO详解 对三类白盒测试技术概念有了宏观了解后,我们将通过一则案例详细演示白盒测试技术的实际应用,帮助你从微观细节中东西白盒测试三类覆盖率的差异。假设我们有如下伪代码片段: 对于语句覆盖率我们只需一个测试用例来检查代码中所有行。这意味着:如果我们有测试用例TestCase01(A40和B70),那么所有代码行都将被执行。 现在问题又来了: 仅仅这个测试用例真的够吗?如果我们将测试用例变为A33和B45呢?又会怎么样呢? 很显然因为语句覆盖只覆盖了TRUE的一面,所以对于上述伪代码片段,只有一个测试用例不足以测试它。作为一个合格的测试人员,我们必须考虑负面情况。为了获得最大的覆盖率,我们需要引入分支覆盖,评估FALSE条件。由此可见,通过语句覆盖我们发现了伪代码中的逻辑问题,从而需要考虑分支覆盖。在现实情况下,我们就可以得出这样的结论:对于被测代码片段,需要为条件失败时添加上适当的语句,于是便有了以下的修复结果(更新后的伪代码片段): 鉴于语句覆盖不足以测试整个伪代码,我们需要分支覆盖来确保最大的覆盖率。 对于分支覆盖,我们需要如下两个测试用例来完成这段伪代码的测试,从而确保每行代码都能被有效执行: 通过以上语句覆盖VS条件覆盖不难得出结论: (1)分支覆盖对比语句覆盖能够确保更多的覆盖范围;分支覆盖比语句覆盖更强大; (2)100分支覆盖率意味着100语句覆盖率; (3)但是100语句覆盖率并不能保证100分支覆盖率; 现在让我们转向路径覆盖,之前我们提到路径覆盖用于测试复杂的代码片段,这些代码片段基本上包含循环语句,亦或是循环和判断语句的组合。我们来看这样一段伪代码片段: 为了确保最大的覆盖率,我们需要4个测试用例。通过观察我们发现,代码片段中有两个分支语句,对于每个分支判断语句,我们需要分别测试两个分支,一个是真,另一个是假。 因此,对于2个分支的判断语句,需要2个测试用例来测试为真的那一侧分支,2个测试用例来测试为假的一侧分支,由此可见共需4个测试用例。为了获得完整的覆盖,我们需要以下测试用例: 6。白盒测试工具 下面给出几款比较热门的白盒测试工具,感兴趣的话可根据实际需求自行研究使用: 〔Veracode〕:一款白盒测试工具,能以较低的成本快速、轻松识别和解决软件缺陷。它支持多种应用程序语言,如。net,c,JAVA等; 〔EclEmma〕:最初是为Eclipse工作台中的测试运行和分析而设计的,是一个免费的Java代码覆盖工具; 〔RCUNIT〕:一款免费的专门用于测试C程序的框架; 〔Cfix〕:CC单元测试框架之一,唯一目的是使测试套件的开发尽可能简单和容易; 〔GoogleTest〕:谷歌的一款C测试框架。可以实现参数化测试、致命和非致命失败、死亡测试、XML测试报告生成等功能。支持Linux,Windows,Symbian,MacOSX等平台; 〔Emma〕:一款易于使用的免费JAVA代码覆盖工具; 〔NUnit〕:一款易于使用的开源单元测试框架,它不需要任何人工干预来判断测试结果。支持所有。net语言,还支持数据驱动测试; 〔CppUnit〕:一个用C编写的单元测试框架,被认为是JUnit的端口。CppUnit的测试输出可以是XML格式或文本格式,通过用自己的类创建单元测试,并在测试套件中运行测试; 〔JUnit〕:一个简单的单元测试框架,支持Java编程语言的测试自动化。主要支持测试驱动开发并提供测试覆盖率报告; 〔JsUnit〕:被认为是JUnit到javascript的端口,它是一个开源的单元测试框架,支持客户端Javascript; 7。总结 文章基于白盒测试的覆盖率,常见白盒测试技术,测试范畴等结合案例为大家普及了一系列测试人员能力提升不得不知的白盒测试技能,文末给出了较受欢迎的白盒测试工具供大家参考。作为测试人员,乃至于测试开发人员,我们熟知仅仅依靠黑盒测试不足以达到最大的测试覆盖率,需要黑盒和白盒测试技术的有效结合来覆盖最大范围的缺陷。在软件研发过程中,如能合理有效地实施白盒测试,势必会对软件质量做出客观的贡献。于此同时对于测试人员而言,如果有机会参与到白盒测试中将会是一次受益匪浅的经历,因为这才是真正意义上的代码及深度测试,也是你技能能力得以体现的最佳场景。