面向对象】第三单元JML总结

胡睿希22230603 学生 2024-05-16 14:29:30

本单元测试过程

  • 黑箱测试与白箱测试
    • 黑箱测试完全不考虑代码的具体实现而仅在意输出是否满足要求,即主要检测代码的功能是否实现。常用的测评机(无论是官方的还是我们自己写的)都属于黑箱测试
    • 白箱测试则是检测具体代码的过程错误,是一种基于代码的测试。比如说这次要求编写的Junit,便是已知JML,即代码的细节,来对代码细节是否完全实现的检测。合格的白箱测试应该覆盖所有的分支,在本次作业中,则体现为应该实现对每一条JML的检测
  • 单元测试
    • 单元测试是指对软件中的最小可测试单元进行检查和验证。而在本次作业中,则是对每一个类是否完成要求功能的测试。一份合格的高内聚低耦合的代码,其中的大部分类应该都能进行单元测试
  • 功能测试
    • 功能测试是指对于代码功能是否实现的检测,本质上与黑箱测试一致。仅考虑输出是否满足功能要求
  • 集成测试
    • 集成测试是基于单元测试的基础上的,仅仅每个单元保持正确并不能保证整体程序的正确。集成测试主要指对于模块之间接口与交互的测试,保证多个单元聚合的正确性。
  • 压力测试
    • 在程序运行的极限情况下,对程序进行测试。模拟多用户、高并发等场景,保证程序在压力下的稳定运行。在本单元作业中,压力测试是检验是否超时的主要手段,通过模拟大规模人、大规模关系以及不断地查询等操作,检验程序的效率与稳定性。
  • 回归测试
    • 回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。在本单元作业中主要体现为,当迭代了新的作业之后,对原有的功能进行测试。
  • 使用的测试工具
    • 主要使用的测试工具还是自己生成数据并通过简单的对拍器与同学进行结果的比较
  • 数据构造策略
    • 由于每次迭代作业绝大多数都不改变原有的方法,因此我每次作业生成的数据都主要针对当前作业新增的几条指令。针对不同的新增指令,为其构造基础图(大多数为边数与节点数都极大的图)。在基础图的基础上,增加新增的基础指令(比如添加tag等不需要算法的操作以及非查询指令),同时进行小规模的增加节点、增加修改边等操作,同时夹杂大量新增查询或者其他需要算法的操作指令。在数据生成的过程中,控制生成异常的数量(尽量控制personid等基础指令的异常,但不完全避免基础指令的异常)

框架设计与维护策略

本单元的主要框架已经由JML给出,整体框架如下图所示

img

在具体实现中,我对于大部分需要计算查询的方法(非算法类)都采用了动态维护的策略,其中包括 block_sum triple_sum tag_value_sum age_sum 等(在第二次作业中,我未维护 tag_value_sum 导致超时)

性能问题与修复情况

本单元作业披着JML看似和善的外衣,但本质上最考察的就是对算法的应用(超时实在是太太太太难测了,与其是考JML,不如说考算法应用)
考察算法的指令如下:

  • query_block_sum: 采用了优化的并查集算法,动态维护父节点
  • query_triple_sum: 动态维护三角形数量
  • isCircle: 与query_block_sum一致,查询父节点
  • query_tag_value_sum: 动态维护value_sum
  • query_tag_age_var: 动态维护age_sum
  • query_best_acquaintance: 动态维护best_acquaintance的id
  • query_shortest_path:深度优先搜索

出现的性能问题与bug

主要问题出在hw10

  • query_tag_value_sum未使用动态维护,而是采用双重循环计算,导致严重超时——后续改正为动态维护
  • query_shortest_path原采用Dijkstra算法,但由于数据结构没学好,没有使用队列进行存放未查找结点,标注是否查找时出现错误,导致搜索很慢且最后出现死循环错误。后续重学了一下bfs的队列实现,用bfs重写了最短路径方法。

规格与实现的分离

规格与实现的分离实际上是将需求与具体实现的分离,在实现之前必须明确需求所在,而规格则是以一种规范的方式来描述需求。因此两者的分离可以大幅度提高代码的健康性,在具体实现阶段,只需要保证自己的实现满足规格,而不用再去分析需求。

Junit测试对检验代码实现与规格一致性的作用

在本单元中,junit主要用于检测代码实现是否符合规格。在编写junit的过程中,考虑对每一条JML要求都进行检测,全方面覆盖JML来实现对于一致性的检测。但个人认为这种检测对于数据构造的要求极高,但即使再全面的数据构造,也会存在漏洞,个人认为这种检测与直接的黑箱检测也并没有本质上的区别。

在公测阶段,junit测试点反而是最卡人的地方,大部分问题都处在数据构造不够全面,但这种不够全面的修改方式也只能一点一点的尝试,并没有什么很好的办法

本单元学习体会

与其说本单元考察的是JML,不如说本单元考察的是算法与数据生成。算法不佳导致爆时,但爆时在本地极其难测;数据生成不佳导致爆junit测试点,但在本地也无法知道该点需要怎样的数据。种种情况导致本单元我的提交次数与上几个单元相比增长幅度极大。在正确性方面,在清明放假期间错了强测之后,五一放假期间的作业又错了……只能说假期快乐吧,希望下次放假别再错了(

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

301

社区成员

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

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