目录
单元总结
一、本单元的测试过程
黑箱测试
白箱测试
单元测试、功能测试、集成测试、压力测试、回归测试
数据构造
二、架构设计
三、性能问题和BUG问题
四、JUNIT测试
五、学习体会
单元总结
HW9:实现简单社交关系的模拟和查询,Person和Network类,主要有添加、删除好友操作以及查询关系网。
HW10:新增Tag类,可以理解为是分组标签,主要有添加、删除分组标签和组内好友的操作。
HW11:新增Message类,主要模拟发送信息。
一、本单元的测试过程
黑箱测试
- 黑箱测试是通过输入预设的数据和观察输出结果来评估程序的正确性和质量,更注重测试的结果和表现,不考虑内部逻辑和算法。
- 从用户角度对程序进行测试。
- 优势:简单直观,测试用例的设计比较容易上手。
- 劣势:不能直接对特定的程序段进行测试,因此很难发现一些代码缺陷、算法问题等细节问题,测试的覆盖率难以确定。
白箱测试
- 白箱测试是基于对内部结构和实现细节的了解,设计测试用例,着重于验证内部逻辑的正确性,发现错误和缺陷。
- 从程序设计者的角度对程序进行测试。
- 优势:可以检测出程序中的错误和异常情况,测试覆盖率可以被确定。
- 劣势:需要了解程序的内部结构和实现细节,需设计和执行更多的测试用例,增加了成本和时间。
单元测试、功能测试、集成测试、压力测试、回归测试
- 单元测试:单元测试是对程序中最小可测试单元进行检查与验证,如在本单元中实现的Junit
- 功能测试:功能测试是黑箱测试,需要测试程序的各个模块是否满足设计需求。
- 集成测试:集成测试是测试两个模块之间的交互和协作的正确性。
- 压力测试:让程序在极限的情况下运行、观察程序的性能缺陷,用于验证程序的稳定性和可靠性。
- 回归测试:在修改代码后,需要进行回归测试以确认是否引进了新的错误。
数据构造
一般上我只会写代码时为了测试某个功能是否正确而构造一些简单的数据,大部分时候都会使用同学搭建的评测机。
二、架构设计
本次单元的作业架构基本跟着JML搭建,其中加了一些类来动态维护数据等。
在HW9的queryBlockSum和queryTripleSum主要是动态维护,在addRelation、modifyRelation时更改blocks以及增加或减少tripleSum的数量。isCircle则是根据已有的blocks,找出id1和id2是否同时在一个圈子里。
HW10在新增的MyTag中,主要性能问题是getValueSum,修复bug时将循环判断改为判断person1的acquaintance中是否有person2就能解决性能问题。对于queryShortestPath,我选择使用BFS,没有遇到CTLE。
HW11没有特别的架构设计,大部分都是根据JML规格,除了将emojiIdList和emojiHeatList合并为一个HashMap,前者记录emojiId,后者记录emoji的热度值。
private HashMap<Integer, Integer> emojiIdList = new HashMap<>();
三、性能问题和BUG问题
- HW9 - 强测没有遇到任何性能问题和bug,也没有hack中人
- HW10 - 在qtvs遇到了ctle,将循环中的isLinked换成该Person的Acquaintance便能解决问题。本次作业还被人hack中一个WA,主要的错误是在找BestAcquaintance时,我将bestAcquaintance的id初始化为Integer.MAX_VALUE。若数据恰好为2147483647,在queryBestAcquaintance时出现异常,将判断异常换成该person是否存在acquaintance即可。
- HW11 - 成功hack到一个getReceivedMessage。本次作业没有性能问题,没有被hack中,但强测有多个WA。第一个问题是在sendMessage时的MyTagIdNotFoundException传错id,传了Person的id。第二个是在MyRedEnvelopeMessage中type==1时,money=luckyMoney,我写成了money=luckyMoney*5,Person1的addMoney我也没有严格按照JML中要求的减去,导致WA。
四、JUNIT测试
由于规格信息已经让一个大框架,我们可以根据它的功能构建Junit测试,需要构建的数据包括:
- 正常的输入情况
- 输入值处于边界,以确保程序可以处理极端值,如边界数据
- 异常数据,确保程序在面对错误或异常输入时可以正确输出异常情况
Junit测试验证与规格是否一致我一般是通过使用assertEquals和assertTrue的方法,确保Junit的测试数据输出与规格输出一致。
五、学习体会
本单元比较起前面的两个单元还是比较简单的,因为我们只需要实现给定的架构,只需要考虑性能的问题。由于JML很长,读起来会比较花时间,但是看久了理解得也就更快了。通过三次作业,我理解的JML的重要性,它对程序员来说有着逻辑严密的规格,不带有二义性,但是在实现时又可以根据自己的理解选择不同的数据结构或算法。