BUAA-OO Unit3总结

文章详细阐述了黑箱测试与白箱测试的区别,以及单元测试、功能测试、集成测试、压力测试和回归测试等不同类型的测试理解。作者还介绍了自己在数据构造、性能优化方面的实践,如使用并查集解决连通性问题,以及针对特定查询问题的算法优化,包括降低Dijkstra算法的复杂度。此外,讨论了规格与实现分离的概念以及OKTest在一致性验证中的作用。
摘要由CSDN通过智能技术生成

测试过程

谈谈你对黑箱测试、白箱测试的理解

黑箱测试是针对软件的外部行为进行测试的方法。黑箱测试只关注软件的输入及其相应的输出是否符合预期不需要了解程序的内部结构和实现方法

白箱测试是根据软件源代码和内部结构来进行测试的方法。白箱测试可以深入到程序的内部结构去查看代码是否符合预期,通过阅读代码判断程序每一行代码的正确性,更仔细、精确地发现代码错误和漏洞,并可以发现可能只通过构造输入难以发现的问题。

对单元测试、功能测试、集成测试、压力测试、回归测试的理解

  1. 单元测试

单元测试是针对代码的最小可测试单元的测试,一般对一个类或函数进行测试,用来检查前置、后置条件,及功能实现正确性等等。

  1. 功能测试

功能测试是对整个软件的各项功能进行测试,以确认整个软件系统是否符合规格要求、是否符合需求、是否做出正确的反馈。这种测试依赖于手动或自动化的测试用例,且需要按照预定的流程进行测试。

  1. 集成测试

集成测试是对不同的模块或组件相互作用进行测试,检查它们是否能够顺利地协同工作。

  1. 压力测试

压力测试是模拟系统在高负载或超负载状态,用来评估系统的处理稳定性、可靠性,即在负载增加时是否能够保持稳定的性能等等。

  1. 回归测试

回归测试是在修改、迭代软件代码后进行测试,以确保新的代码与老的代码之间没有矛盾或错误。

测试工具和数据构造

在本单元中,我使用了讨论区各位大佬的评测机,也设计了自己的对拍器和数据生成器,我的数据生成器主要是通过随机数生成指令,即将各个指令编号,通过生成的随机数的范围来判断下一个生成的指令是什么。同时我在数据生成器中使用了若干容器,存储目前的指令已经成功添加的人、组、关系等等,从而根据生成的随机数和目前人、组的情况综合决定是否生成当前指令。例如 若存储person的容器中person较少,则应尽可能多生成ap(即add person指令),而非是ar、atg之类的指令。

同时,我还手动构造了一些测试样例,主要是根据各个方法的jml规格中不同的分支,例如抛出异常的情况,第一个分支的情况等等。这样通过构造多个分支充分的测试用例,尽可能多的覆盖可能的输入情况.

架构设计与性能优化

由于这个单元的作业主要是针对规格进行代码撰写,所以大部分架构基本相似,不作赘述。

由于这次作业中涉及两个人的连通性,两个人的最短路径等等,类似于图。可以把人作为节点,人和人之间的关系作为边,构造一个图来解决上述问题。

连通性,我的解决方案是并查集,我构造了一个并查集类,通过判断两个节点跟是否相同来判断是否连通。同时结合路径压缩等方法,降低了使用并查集进行运算的复杂度。

在第十一次作业中,qlm函数要求我们求过某一点的最小环,这同样可以通过图论的方法解决。我首先想到的是删边,然后使用最短路径算法求解,但这样带来了一个复杂度的问题,即即使最短路径使用堆优化后的dijkstra算法,方法总复杂度依然高达 O ( m 2 l o g n ) O(m^2log n) O(m2logn),这无疑是个很高的复杂度

在之前的基础上,我又对删边进行了简化,只删除经过这个点的边,即仅删除这个人与熟人的边。同时,我还进行了剪枝,使用中间变量存储目前的最短路径长度,当下一轮算出的最短距离的中间节点,到起点的距离已经大于目前的最短路径长度,则不去更新最短路径数组,从而降低了一定的复杂度。但是这依然使得,当qlm查询多次且边较多时,每次都要进行 O ( n ) O(n) O(n)次dijkstra,复杂度较高

后来在查阅资料的情况下,我使用了在单次查询中复杂度为两次dijkstra的算法,这个算法的原理在于,首先求出输入的点到各点的最短路径长度,同时记录最短路径。然后求出输入的点到各点的次短路径,即这个路径的长度不短于最短路径,但是此路径的第二个点(即直接与输入的点相邻的点)与最短路径的该点不同。这样仅需求出该图中除了输入的点,其他点的最短路径和次短路径的长度之和最短的情况,即是函数所要求的最小环长度。

其他性能优化

这三次作业中还有诸多可以优化性能的方法,例如qbs、qba等等,这些方法具体实现的复杂度并没有qlm那么高,但是这些方法仅在加入或删除人、关系、组时发生变化,且其他指令并不会影响这些方法的结果,所以可以在加入或删除人、关系、组时立即更新,避免出现虽然避免了加入、删除时方法复杂度增大,但是导致运行多个此类指令以致耗费时间较长的情况。例如qbs,这个函数就可以在并查集添加关系时来维护。同样的,qba仅在添加或修改或删除关系时更新或重新求最大值即可。

对规格与实现分离的理解

规格是为了严谨、全面、准确地表达程序或者函数的需求,需要考虑到所有情况,且避免歧义,让所有人读了只会理解一种意思,虽然这可能导致繁琐和理解难度较高。同时,规格的标准化还可能有助于生成自动化测试的程序等等。

但是在根据规格具体实现方法时,可能并不需要代码浅显易懂,更可能需要优化的数据结构或者算法,在保证满足规格、维持代码美观性的前提下,尽可能更快、更简洁的实现功能。

OKTest

OKTest正是检验规格和实现一致性的重要方法。他通过严格按照规格撰写的程序检查当前的输入应有的输出,与实际的输出是否相符,从而检查实现的方法是否存在规格与实现不一致的情况。在第九次作业中,我就错误的理解了OKTest的用法,错误的将输入转化成了我的程序可以接受的输入,通过调用相应检查的函数得到结果,与OKTest输入的实际输出结果进行比较。但这违背了OKTest的初衷,在实际运行场景下,程序使用者本就通过代码撰写者的功能函数进行输入输出,若此时使用这个OKTest进行一致性检验,则无论如何都无法发现问题。

学习体会

本单元的学习任务相较于前两个单元少了不少,但是依然让我明白了代码严谨性的重要性、算法的重要性等等,在此次作业getAgeVar()方法中,我虽然注意到了平均数需要取整,但是仍然因为,错误的使用double导致出现精度问题。这让我更加警醒了即使在规格较明确时,也不能对可能出现的问题缺少思考和检查。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值