测试优先的编程

        作为一名刚升上大二的软件工程学生,我对软件测试的重要性并不是非常清楚。但是事实上,在软件产品开发的生命周期中,软件测试是一个至关重要的环节。它是确保软件产品质量的最后一道防线,也是为最终用户提供可靠、稳定、高质量的产品的重要途径。

没有100%正确的测试 

        软件测试的目的是发现软件产品中存在的缺陷,通过不断地发现缺陷并反馈给开发团队进行修复,最终将软件产品中的缺陷降到最低,确保软件产品的质量和稳定性。但是,即使是最好的测试,也无法达到100%的无错误,仍会存在残留缺陷。即使我们已经在测试过程中投入了大量的人力、物力、财力,精心准备了测试计划和测试用例,也无法保证所有可能的缺陷都能够被发现。其中原因包括:测试覆盖率不够、人为主观因素和时间和资源限制。

        因此,即使我们在测试过程中不断努力和改进,尽最大努力发现尽可能多的缺陷,也无法保证测试可以覆盖所有可能存在的缺陷。为了更好地降低测试的风险和提高测试效率,我们需要采取一系列措施来提高测试覆盖率和准确度。

测试的等级与分类 

        在软件开发生命周期中,测试可分为多个等级,常见的测试等级有:

        1. 单元测试(Unit testing)

        单元测试是对软件的最小可测试单元进行测试,如一个函数、一个方法等。主要用于验证软件的功能是否已正确实现。单元测试通常由开发人员完成,可以借助自动化测试工具进行测试。

        2. 集成测试(Integration testing)

        集成测试是对多个单元进行测试,以验证它们在集成后是否正常运行。集成测试分为两种,即自下而上的增量式集成测试和自上而下的非增量式集成测试。集成测试通常由测试团队完成,可以结合自动化测试工具进行测试。

        3. 系统测试(System testing)

        系统测试是对整体软件系统进行测试,包括功能测试、性能测试、安全测试、可靠性测试等等。测试目标是验证系统是否满足客户需求以及软件质量是否达到预期水平。系统测试由测试团队或联合开发团队完成。

        4. 验收测试(回归测试)(Acceptance testing)

        验收测试是对软件最终交付前的最后一道测试,旨在验证软件是否符合客户的需求和期望。验收测试与用户需求紧密联系,通常由客户或最终用户完成,可以是手动测试或自动化测试。

        除了以上四个等级外,还有一些其他测试等级,如Alpha测试、Beta测试、回归测试等等,根据项目需要进行选择和应用。

        软件测试也可以根据不同的分类方式来进行分类,常见的分类方式有以下几种:

        1. 功能测试 vs 非功能测试

        按照测试目标的不同,可以将软件测试分为两类:功能测试和非功能测试。功能测试主要关注软件的功能是否满足要求,例如:输入正确的用户名和密码能否成功登录系统。非功能测试则关注软件的各项性能指标是否符合要求,例如:用户在一定时间内能否完成某项任务等。常见的非功能测试还包括可靠性测试、安全测试、可用性测试、性能测试等。

        2. 手动测试 vs 自动化测试

        根据测试执行方式的不同,测试可以分为手动测试和自动化测试。手动测试是由测试人员手动执行测试用例,对软件进行测试,需要耗费较长的时间和人力成本。自动化测试是借助测试自动化工具执行测试脚本,比手动测试更快速、准确、可重复,能够节省大量时间和成本。

        3. 黑盒测试 vs 白盒测试 vs 灰盒测试

        按照测试方法的不同,测试可以分为黑盒测试、白盒测试和灰盒测试。黑盒测试是不关注被测试软件的内部实现细节,只根据输入和输出进行测试,测试人员只通过用户界面进行测试。白盒测试则是基于被测试软件的内部结构和算法进行测试,主要应用于单元测试和集成测试中。灰盒测试则介于黑盒和白盒之间,既关注软件的功能,也关注其内部实现细节,主要应用于系统测试和验收测试。

        4. 静态测试 vs 动态测试

        按照测试执行时机的不同,测试可以分为静态测试和动态测试。静态测试是在不运行被测试软件的情况下对软件进行分析和测试,例如代码审查、文档评审等。动态测试则是在运行被测试软件时对其进行操作并进行测试。常见的动态测试方法包括黑盒测试、白盒测试、灰盒测试等。

        5. 模块化测试 vs 集成测试

        按照测试对象的不同,测试可以分为模块化测试和集成测试。模块化测试是对软件的最小可测试单元进行测试,例如函数、类等。集成测试则是对多个模块进行测试,以验证它们在集成后是否能够协同工作。常见的集成测试方法包括自下而上的增量式集成测试和自上而下的非增量式集成测试。

        当然,除以上分类方式外,也有其他的分类方式,如持续集成测试与非持续集成测试、前端测试与后端测试、测试环境分类等。根据实际需求和项目特点,可以采用不同的测试分类方式进行测试。

JUnit单元测试 

        JUnit是一个Java编程语言的单元测试框架。JUnit框架的设计使它适用于各种类型的Java应用程序,包括基于J2EE的Web应用程序、企业应用程序和传统的独立应用程序。JUnit的测试结果会展示测试用例的执行结果,包括成功、失败、错误和忽略等。

        在完成实验的过程中,我都是使用了JUnit4,而JUnit4的函数主要包括以下一部分。若想知道完整的函数列表,可查询源代码 Assertions · junit-team/junit4 Wiki · GitHub

等价类划分

        等价类划分(Equivalence Partitioning)是软件测试中的一种测试方法,它将输入值分为有效等价类和无效等价类,以检查系统对这些不同输入的处理方式是否正确。

        等价类划分的目标是尽可能少地测试各种可能的情况,而且对于相同等价类中的所有输入值,期望的输出结果都应该是一致的。为了获取有效等价类和无效等价类,需要基于输入项的规范(Specification)来确定输入参数的限制条件。

        同时,在进行等价类划分时,还得采用边界值分析方法,这是对等价类划分的补充。而且许多的错误都是出现在边界,而非中央。

        而为了覆盖分区,对不同的等价类有两个极端方法:笛卡尔乘积(全覆盖)与覆盖每个取值(最少覆盖一次)。有如下例子:

         可以发现,笛卡尔乘积的方法:测试完备,但用例数量多,测试代价高;覆盖每个取值:测试用例少,代价低,但测试覆盖度未必高。

代码覆盖度 

        代码覆盖度(Code Coverage)是一种用于评估软件测试质量的指标,其衡量的是已经运行的测试用例中覆盖源代码行数的百分比。是软件测试的一个重要指标之一,可以通过帮助测试人员了解测试用例的执行效果从而确定测试的覆盖面和有效性。代码覆盖度通常包括以下几个方面:

        1. 语句覆盖率(Statement Coverage):语句覆盖率是指测试用例是否执行了所有的源代码语句。如果被测试的方法共有10条语句,测试用例执行了其中的8条,那么语句覆盖率为80%。

        2. 判断覆盖率(Decision Coverage):判断覆盖率是指测试用例是否执行了所有可能的条件判断路径。如果被测试的方法中有一个 if...else... 语句,测试用例覆盖了其中的 if 分支并执行了其中的语句,那么判断覆盖率为50%。

        3. 条件覆盖率(Condition Coverage):条件覆盖率是指测试用例是否覆盖了所有的条件组合。一个包含两个条件的 if...else... 语句,每个条件有两个可能的取值,那么条件覆盖率至少要执行四个测试用例。

        4. 分支覆盖率(Branch Coverage):分支覆盖率是指测试用例是否覆盖了所有可能的分支。例如,一个包含两个分支的 if...else... 语句,至少需要执行两个测试用例才能覆盖所有分支,分支覆盖率为100%。

        通过对代码覆盖度进行测试,可以帮助开发人员评估测试用例是否已经足够覆盖源代码中的所有路径和可能的条件,从而优化测试用例的设计和测试效果,提高软件质量和可靠性。

        总而言之,在做任何开发时,都应该牢记软件测试,进行测试优先的编程。为每个ADT中的用例写spec,再根据spec写测试策略,进而写出测试用例,这是成为一名优秀软件工程师的必经之路 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值