BUAA-OO-Unit3 单元总结

樊浩宇+22371055 学生 2024-05-16 10:46:35

BUAA-OO-Unit3 单元总结

在OO_Unit3单元中,我们学习并实践了如何使用JML进行规格化设计。例如,我们可以使用JML来描述一个方法的输入参数、输出结果以及可能的异常,这样不仅可以帮助开发者更好地理解方法的使用方式,还可以在后续的代码实现和测试过程中提供指导。

单元介绍

本次作业,需要完成的任务为实现简单社交关系的模拟和查询,学习目标为 入门级 JML 规格理解与代码实现。

JML,即JAVA Modeling Language,是一种基于Larch方法构建的行为接口规格语言,主要用于对Java程序进行规格化设计。
JML的优点在于它的精准性与可读性。使用JML,我们可以将模糊的自然语言描述替换为逻辑严密的规格语言,从而更好地表达设计思路,并为代码书写规格,提高代码的可读性和可维护性。

分析本单元的测试过程

  • 谈谈你对黑箱测试、白箱测试的理解
    • 黑箱测试又叫功能测试、数据驱动测试或基于需求规格说明书的功能测试。该类测试注重于测试软件的功能性需求。
      在Junit代码编写过程中,我们面对作业Network 类中的 queryTripleSum 方法,queryCoupleSum 方法,deleteColdEmoji 方法,进行测试时候采用随机参数生成,构建出来的就是简略版黑箱测试。
      在该过程中,我们没有考虑到方法是如何实现,完全不考虑程序内部的逻辑结构和内部特性,只考虑到方法实现后的效果,即通过大量的数据测试来实现测试Bug的作用。

    • 白盒测试又称为结构测试或逻辑驱动测试,它是把测试对象看成一个透明的盒子,它允许测试人员利用程序内部的逻辑结构设计测试用例,对程序所有逻辑路径进行测试。
      我们这次面对的JML规格来编写的Junit测试代码,属于白盒测试,保证\ensures,\assignment,\not_assigned,pure等功效都要验证是否实现相应的功能。

  • 对单元测试、功能测试、集成测试、压力测试、回归测试的理解
    • 单元测试(unit testing),
      单元测试是指对软件中的最小可测试单元进行检查和验证。
      “单元”可以是一个函数、方法、类、功能模块或者子系统。单元测试通常和白盒测试联系到一起。
      基于这个理解,我们编写的Junit的前置条件,后置条件,其他都要进行相关的测试断言,和白盒测试的作用大体相同。
    • 功能测试
      功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。所以功能测试和黑盒测试经常联系在一起.
    • 集成测试
      集成测试也称联合测试(联调)、组装测试,将程序模块采用适当的集成策略组装起来,对系统的接口及集成后的功能进行正确性检测的测试工作。集成主要目的是检查软件单位之间的接口是否正确。测试方法采用黑盒测试与白盒测试相结合
      在执行集成测试之前,必须先进行单元测试。
    • 压力测试
      压力测试是一种软件测试,用于验证软件应用程序的稳定性和可靠性。压力测试的目标是在极其沉重的负载条件下测量软件的健壮性和错误处理能力,并确保软件在危急情况下不会崩溃。它甚至可以测试超出正常工作点的测试,并评估软件在极端条件下的工作情况。
      对于压力测试,强测中的超强数据点,例如qtvs * 1000超多qts等,会出现CTLE的错误,这是由于压力测试下,代码的时间复杂度较高。面对作业中的压力测试,我们尽可能采取 $O(n^2)$ 以下的算法和相对优良的存储容器。
    • 回归测试
      回归测试(Regression Test)是指在软件项目中,开发人员在修改了软件的代码以修复已经发现的bug后,测试人员在需要重新测试前面已经测试过的内容,以确认此次修改没有引入新的错误。
      落实到我们的代码中,修复Bug后的代码不改变修改前正确的测试样例。例如,Bug修复部分需要保证修复后的代码不会引起新的错误,否则无法提交。
  • 数据构造有何策略?
    • 单元测试
      • 针对每一个方法,进行正确性测试,确保方法实现的正确性。覆盖面广。
    • 压力测试
      • 针对时间复杂度较高的单个方法,进行压力测试,进而出现TLE的错误。
    • 极端数据
      • 特征变量的返回,例如ture返回1,false返回0,针对此,可以构建相应的数据来实现错误也会返回0.
      • 爆数据范围,int型,compare排列的返回不能直接作差,爆int。

梳理本单元的架构设计,分析自己的图模型构建和维护策略。

  • 架构设计
    • 主要是采用JML语言进行代码编写,没有进行过多的卷,让自己的性能进行过多的优化。
      以下是我的第三次作业UML图

      img


      图模型的构建,采用最原始的无向图结构,删删减减,添加即常规操作。查找算法采用双dfs,进行优化,防止TLE问题。
    大多数同学采用的是并查集,进行路径压缩。
    存在重建问题,(1)全部重建,会TLE (2)局部重建,能过

分析作业中出现的性能问题及其修复情况,谈谈自己对规格与实现分离的理解。

  • JML规格来描述一个方法的输入参数、输出结果以及可能的异常,这样不仅可以帮助开发者更好地理解方法的使用方式。
  • 实现可以采用完全按照JML规格来编写代码,但是会存在TLE等性能优化问题,所以最合理也最正常的方法是理解了JML规格的描述,进而采取相对应简单的存储方式和实现方法。例如qts,qtvs,qtav等采取动态优化,qsp 采用迪杰斯特拉,bfs等,qba采用优先队列。
  • 客户需求是死的,实现客户需求的方法是多种多样的。即上有政策下有对策。

本单元中同学们实现了Junit测试方法,总结分析如何利用规格信息来更好的设计实现Junit测试,以及Junit测试检验代码实现与规格的一致性的效果

  1. 理解规格信息: 深入理解规格文档中描述的功能需求、接口规范和行为预期。这包括理解输入输出的前置条件、后置条件、副作用、格式、边界条件、异常情况等。

  2. 编写测试用例: 基于理解的规格信息编写测试用例。测试用例应该覆盖规格中描述的各种情况,包括正常情况和异常情况。确保测试用例能够检验代码的各种行为。

  3. 使用参数化测试: 使用参数化测试来轻松随机模拟地覆盖JML描述的情况。参数化测试允许使用不同的输入参数运行相同的测试方法。

  4. 断言和验证: 确保每个测试用例都有明确的断言和验证步骤,验证代码的输出是否符合规格中描述的预期行为。

  5. 边界条件测试: 规格中描述边界条件和特殊情况,例如输入的最大值、最小值、空值、相等条件等。在编写测试用例时,要特别关注这些边界条件,确保代码在边界条件下的行为符合预期。

本单元学习体会

学会使用JML规范编写代码对于本单元作业至关重要。理解后,编写规范的代码需要技巧和实践。尤其需要注重的是如何高效地实现方法规范,这需要技巧和算法的积累。JML在软件开发中扮演重要角色,因此学会阅读,并且熟练掌握掌握它是必要的。

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

302

社区成员

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

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