oo第三单元博客(22230611-黄瑞翔)

黄瑞翔-22230611 学生 2024-05-17 14:24:56

目录

  • oo第三单元作业博客(22230611-黄瑞翔)
  • 一、本单元测试过程
  • 1. 对黑箱测试、白箱测试的理解
  • 2. 对单元测试、功能测试、集成测试、压力测试、回归测试的理解
  • 3. 数据构造策略
  • 第九次作业
  • 第十次作业
  • 第十一次作业
  • 二、架构设计、图模型与维护策略
  • 1. 架构设计
  • 2. 图模型
  • 3. 维护策略
  • 第九次作业
  • 第十次作业
  • 第十一次作业
  • 三、性能问题及其修复情况
  • 四、对规格与实现分离的理解
  • 五、如何利用规格信息来更好的设计实现Junit测试 & Junit测试检验代码实现与规格的一致性的效果
  • 六、学习体会

oo第三单元作业博客(22230611-黄瑞翔


一、本单元测试过程

1. 对黑箱测试、白箱测试的理解

  • 黑箱测试是指测试人员在不考虑程序内部逻辑和结构的情况下,仅根据软件的需求规格说明书来设计测试用例。这种测试方法通常需要生成大量的数据去测试程序的正确性,它的优点是覆盖面积非常广泛,但可能覆盖不了一些极端情况。黑箱测试也是评测机通常使用的测试方法。
  • 白箱测试是指测试人员可以查看程序的内部逻辑、结构和源代码,并基于这些信息来设计测试用例。测试人员将软件视为一个“白箱”或“透明盒”,能够深入了解其内部实现。同时,在面对一些极端的情况时,白箱测试能够发挥较明显的作用。在互测中,我们常常会采用白箱测试的方式,通过阅读他人的代码去构造针对性的样例来测试。

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

  • 单元测试:
    是对系统中最小可测试单元进行测试的过程,这些单元通常是代码中的函数、方法、类、模块等。在面对一些较为复杂的方法时,我们可以编写专门针对这些方法的测试,这样能够快速地定位问题所在。
  • 功能测试:
    目的是对产品的各功能进行验证,检查产品是否能满足用户对功能的需求。它需要根据功能测试用例,逐项测试,以确保软件功能符合设计文档与用户需求。功能测试关注软件的实际功能,而不关心其内部逻辑和结构,因此它属于黑盒测试。
  • 集成测试:
    是在单元测试的基础上,将所有模块按照设计要求组装成为子系统或系统,进行整体测试。它的主要目的是检查模块之间的接口和交互是否正常,以及整个系统是否能够正常工作。集成测试有助于发现模块之间的冲突和错误,以确保系统的稳定性和可靠性。
  • 压力测试:
    是模拟实际应用的软硬件环境及用户使用的系统负荷,长时间或超大负荷地运行测试软件,以测试被测系统的性能、稳定性等,其对于确保软件性能与稳定性的保障具有重要意义。本单元的强测有一部分就是针对特定负荷情况的压力测试。
  • 回归测试:
    是指在对软件进行修改、修复漏洞或进行其他类型的更新后,重新运行已有的测试用例,以确保新的更改没有产生新的错误或导致现有功能的中断。其主要目的是验证软件的稳定性和兼容性,确保软件在更新后仍然能够正常工作。

    3. 数据构造策略

    第九次作业

    这次作业测试的是queryTripleSum方法。其数据构造策略相对简单,我设计了K(5,5)完全图、完全图删几条边以及非连通图等几个不同的情况。其实还是通过手动构造样例去尽可能地覆盖更多的可能。

    第十次作业

    这次作业测试的是queryCoupleSum方法。本次作业需要设计更多的样例以覆盖,增加了全是孤立点的情况。这次作业也让我意识到前一次作业在数据构造方面的不全面性。

    第十一次作业

    这次作业要测试的是deleteColdEmoji方法,由于本次作业增加了消息类,总体更加复杂,因此手动构造样例的方法难以覆盖所有情况。因此在这次测试中,我采取了“手动+随机”的构造方法。addPersonaddRelation均为手动加入指令,随后在表情的数量、总消息的数量、消息被send的数量、limit均利用了随机数进行生成。增大testNum,可以较全面地覆盖到大多数情况。

二、架构设计、图模型与维护策略

1. 架构设计

本单元的作业的架构设计是以课程组给出的官方包为基础展开的。

2. 图模型

MyNetWork中,采用HashMap存储Person节点,每个Person都有自己的aquaintance数组,总体上形成的是邻接表式的无向图结构,此外,每两个Person之间的value代表图中这条边的权值。

3. 维护策略

第九次作业

isCircle:如果直接实现,需要在每次调用此方法时使用dfs,会极大地增加时间开销。因此可以采用并查集进行实现。并查集,即利用一个HashMap记录每个结点的父节点。并查集的维护如下:

  • 在每次addPerson时,将这个人的父节点设为自己;
  • 在每次addRelation时,将一人的根结点设为另一人的根结点的父节点;
  • 在每次modifyRelation时,如果遇到删边的情况:如果在删边之后两点不再连通,那么分别将两点各自所在的连通图的所有节点的父节点设为自己;反之,则直接把连通图所有节点的父节点设为两点的其中一个。
  • 路经压缩:为减少时间消耗,在寻找每个结点的根结点的方法中,可直接将此根结点设为该节点的父节点。
    public int getRoot(int id) {
          if (id != union.get(id)) {
              union.put(id, find(id)); //即路经压缩,其中find方法的作用是寻找结点的根结点
          } return union.get(id);
      }
    

在调用isCircle方法时,只需比较两点的根结点是否相同即可。

queryBlockSum:这个方法的本质是求连通分支的个数。可以设置全局变量进行维护。在addPerson时,该变量加一;在addRelation时,如果两点本来不连通,该变量减一;在modifyRelation删边时,如果删过边之后两点不再连通,则该变量加一。

queryTripleSum:如果直接按JML语言实现,需要使用三重循环,时间开销太大。因此设置全局变量tripleSum,在每次addRelation加边以及modifyRelation删边的时候,通过遍历所有人,找到两点共同的熟人,对变量进行维护。

第十次作业

queryAgeMeanqueryAgeVar:需要在MyTag中设置属性ageMean,每次加人或减人时对其进行维护,求解时直接调用该变量即可。

queryBestId:在MyPerson类中设置属性bestId,在addRelationmodifyRelation时对其进行维护。addRelation时,通过和原bestIdvalue比较确定是否需要更改;modifyRelation时,如果原本的bestId是对方,则需要通过遍历确定来新的bestId

queryCoupleSum:直接实现需要两重循环。在具体实现时,可以采用只遍历一遍的方式,找到某个人的bestId后再确认他的最佳好友的bestId是否是他自己,如果满足,结果就加一。

getValueSum:如果直接实现,需要采用两重循环。因此可以考虑采用全局变量维护:

  • MyTagaddPersondelPerson中,需要遍历Tag中的所有人,将全局变量按照每个人与指定人的value进行2倍的增减。
  • addRelation时,遍历找到两个人共同的熟人,然后修改他们tag中的valueSum变量;
  • modifyelation时,同addRelation一样。但注意如果遇到删边的情况,对valueSum减少的不是参数value,而是两人原来的queryValue值。

queryShortestPath:采用bfs广度优先搜索即可。

第十一次作业

本次作业在性能提升方面并无太多的要求。有一个点需要注意:在MyPerson中,可以采用LinkedList存储messages

三、性能问题及其修复情况

  • 本单元作业在hw10的互测中出现了ctle,问题在于没有维护MyTag中的ageMean,而是在每次调用时都要循环遍历。
  • 修复方法:在MyTag中设置属性ageMean,每次加人或减人时对其进行增减,求解时直接调用该变量即可。
  • 这个bug也提醒我在对于循环要敏感一些,考虑一下是否可以通过维护变量的方法避免或降低循环带来的复杂度。

四、对规格与实现分离的理解

规格给出了某个方法需要实现的目标与规范,但是实现时并不一定需要根据规格逐字逐句编写程序,只需要保证最终的结果满足规格中的所有要求即可。比如,在本单元作业中,JML语言给出的是数组(类似于ArrayList)形式,而在实现时大多都采用HashMap存储,最终达成的效果是一样的,只不过实现的方式可以提高性能。

五、如何利用规格信息来更好的设计实现Junit测试 & Junit测试检验代码实现与规格的一致性的效果

  • 要保证只能修改\assignable允许修改的内容,对于明确\not_assigned的内容,应严格检查其是否被修改;
  • 对于pure标记的方法,需要检查这个类在调用方法前后是否严格一致;
  • 在编写test方法时,需要逐步检查每个\ensures是否得到保证;
    按照上面的原则编写测试方法后,在数据构造上仍需要花不少功夫,尽可能的构造全面的数据样例,才能让你测试的效果得到保证。

六、学习体会

本单元的学习相较于前两单元轻松了一些。学习完本单元之后,我熟悉了JML语言,了解了规格在编程中的意义。但我感觉,本单元的作业相较于对规格的理解,在算法上的要求更高,我也从中温故了数据结构与算法的相关知识,感受到了维护策略带来的便利。希望在以后的学习中,能够更加深入地理解规格的意义,同时也要不断提升自己对于各种算法的运用能力。

...全文
38 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧