测试过程分析

对黑白箱测试的理解

黑箱测试:从软件外部对软件实施的测试,也称功能测试或基于规格说明的测试,不需要了解软件的内部结构和源代码,只关注软件的输入数据和输出结果是否符合要求。

白箱测试:对软件的内部结构和逻辑进行分析后的测试,也称结构测试或逻辑驱动测试,要求测试人员具有编程技能和对软件的深入了解,并能访问所有源代码和文档。

对其他测试类型的理解

单元测试:对软件的最小设计单元/模块进行正确性检验的测试工作,目的是消除局部模块的逻辑和功能上的错误和缺陷,通常采用白盒测试方法,例如这单元编写的 OK test 测试程序。

功能测试:对软件的功能需求进行验证的测试,目的是保证软件满足用户的期望和需求,通常用黑箱测试,例如这单元的中强测。

集成测试:将通过单元测试的模块组装成系统或子系统,并进行接口和功能的测试工作,目的是发现模块间的接口问题和集成后的功能问题,通常采用黑箱和白箱相结合的方法。

压力测试:对软件在特定负载条件下进行性能表现的测试工作,目的是检查软件能否承受高负荷、高并发、高数据量等极限情况。例如第十一次作业强测的第 4 和第 9 个点,以及互测房的狼王课下 hack。

回归测试:在修改了软件代码后重新执行已有测试用例的测试工作,目的是确保修改没有引入新的错误或影响原有功能。

测试工具

这单元的课下测试其实是前面作业最容易实现的,只要考虑数据构造,剩下的找一两位同学对拍。我使用了 python 工具,对拍部分沿用前两个单元,不同的是增加了 jar 包的 CPU 时间记录功能,方便校验课下的复杂度。不仅如此,这单元的测试指令特别多,bug 出现率更高,肉眼发现 bug 概率更低,加上中测实在太弱(看提交的通过率就知道了),因此课下对拍更不能少。

数据构造策略

需要检验:

  1. 指令正常执行时程序内部变量是否正确修改;
  2. 指令触发各种异常时能否抛出对应异常,以及异常输出是否正确;
  3. 能否通过压力测试,人数极多或关系极多或人数和关系数数量级相同等情况下是否超时。

对于前两条的正确性测试,我在 python 中用全局变量 prob_exc 控制数据出现异常的频率。先将该变量调为非 0(也不可过大),超过 1w 条数据测试异常抛出情况。测试完成后,将 prob_exc 调为 0,从而实现更高效率的测试。

对于第三条的压力测试,比较复杂以及容易出错的有 qbs , qts , qba, qcs , qgvs , qlm 等。采用两种大数据测试:大量修改关系网,最后用少量 query 指令,用于针对动态维护;每次修改关系网都进行相应 query ,用于针对每次查询时才进行计算的程序。可怜鼠鼠费尽心机,最后互测时一个 CTLE 都没找到,反而鼠鼠的程序速度是房里倒数的。

提高 bug 出现率的数据生成程序修改:

  1. 两个人之间的关系权值随机性越小,出现 bug 的指令越靠前,部分同学的程序也跑得越慢。看了同学的代码,原因如下:出错概率上升的原因是从 hashMap 取出的 value 是 Integer 型数据,比对时使用了 == 而非 equals 方法,而随机性降低意味着出现相等概率更大,这样 value 值比对就会出错。跑得更慢的原因是程序用了堆优化,猜测值相同时堆的实时维护更耗时,不过都用了堆优化了,我也甭想让它超时。也别太非随机。
  2. 减少 group 个数,限制为 1~3 个。课下测试出 message 和 group 型的 bug 效率更高。
  3. message 专门测试:(构造一些人在 group 里,一些人不在)先 store 足够的 emojiId ,再 add 足够的各类型 message ,再 send 一半的 message ,然后执行少量的删除信息相关的指令(cn, dce)后,紧跟相关的查询指令。完全随机数据要跑出相关 bug 可能跑 10w 条也找不到。对其他的指令测试也可以用类似的思路。

单元架构设计

这单元有个重要的选择:是否动态维护。

第九次作业

复杂度高的指令只有 query_block_sumquery_triple_sum ,对于 qbs 使用并查集动态维护,增加人或关系时用路径压缩的并查集复杂度略大于查询时,查询时复杂度为 O(1)。为什么用动态维护而不是查询时计算?因为就平均而言,并查集动态维护复杂度比查询时计算低,绝对不会超时,并且往届学长也这么用,所以算法小白就这样跟风啦。

query_triple_sum 的复杂度按 JML 实现的话是 O(n3) 复杂度,面对 1w 条的强测数据,查询时计算是不可取的,应该动态维护。维护方式是:每加入一个 A B 关系,就查询 A B 之间的共同熟人,triple_sum 则加上共同熟人的个数。细节:查找共同熟人的时候遍历熟人较少的那个人的熟人。

第十次作业

比较麻烦的是 modify_relation 后的 query_block_sum 。平时查到的并查集算法是解决已确定所有点和边的情形,没有考虑删边。QQ 水群里(应该最开始是 tyjj)提出了并查集分裂的改进法:删除 AB 边,则用 bfs 遍历与 A 有直接或间接关系的点,如果没有遍历到 B,那么将并查集分裂为分别以 A 和 B 为根的二层的两个并查集。相关代码如下:

private void delBlock(int id1, int id2) {HashSet<Integer> circled1 = new HashSet<>();((MyPerson) people.get(id1)).setCircled(circled1);if (!circled1.contains(id2)) {int circleSize = 0;for (Integer pid : circled1) {pres.put(pid, id1);circleSize += 1;}preSize.put(id1, circleSize);HashSet<Integer> circled2 = new HashSet<>();circleSize = 0;((MyPerson) people.get(id2)).setCircled(circled2);for (Integer pid : circled2) {pres.put(pid, id2);circleSize += 1;}preSize.put(id2, circleSize);blockSum++;}
}

其中 pres 是 ID → 并查集树上该点父节点的 ID 的 hashMap 映射;setCircled() 方法是 bfs 方法,执行后里面存储所有可达点的 ID。

现在回想起来,虽然说维护并查集用到的 bfs 只是在一个并查集小圈子里使用,而非整个 people ,但说不定不用维护并查集,直接在 qbs 时用 bfs 的复杂度也不算很高?

第十一次作业

挺折腾人的,query_least_moments 查询过指定源点的最小环长度。由复杂性可以排除动态维护的思想。

单次查询时,我先用 dijkstra 查找所有点到源点的最短路径,并在这个过程中维护最短路径生成树;接下来,用这篇博客提到的算法,分两类进行最小环查询。设整棵树为 0 级子树,往下的子树分别为 1,2,3 级子树。

  1. 遍历一级子树下的所有点(不包括一级子树根节点),如果这个点与源点有直接路径,则用 该点到源点的最短路径+该点与源点的直接路径 就能得到一个环的长度,依此更新最小环。
  2. 遍历一级子树下的所有点(包括一级子树根节点),如果被遍历点 A 与另一棵一级子树上的点 B 直接相连,则用 A 到源点的最短路径+ B 到源点的最短路径+ AB 之间直接路径 得到一个环的长度,依此更新最小环。

通过上面两类遍历后,就能得到最小环长度;如果最小环长度为初始值,说明没有找到环。为什么这样我也不知道,希望有 dalao 能发篇博客引引流。

更进化的 dijkstra 算法是堆优化,能够大幅度优化稀疏图的查询速度,对稠密图的速度似乎也会有提升,不过经过大量本地测试后认为不会超时,就没有继续优化。互测房里有见到用 Pair , ArrayQueue , TreeSet 等数据结构的,稀疏图速度是我没有堆优化的三倍以上。

规格与实现:性能与正确性

由于代码是看到群u的讨论结果后再下手,因此性能方面没有出现问题。关于性能的改进,除了动态维护算法的选择,还有一点:遍历时遍历对象的选取。例如第九次作业动态维护 triple_sum 时,遍历熟人较少的那个点,而不是随机选两人中的一人,也不是遍历 people 容器中的所有点。再例如第十一次作业的第二类最短路径树遍历时,可以选取源点的 value 容器遍历。

规格与实现的分离

课程组给的 JML 规格往往假定容器是一个数组,然后描述一个函数的功能也是“暴力”描述:在数组容器中,取出或者查询一个指定元素都是通过 for 循环。这样就导致了一些功能的描述(例如 query_least_moments )会出现大于等于二/三层的 for 循环,导致超过 O(n2) 甚至 O(n3) 的复杂度。

程序编写者要做的,就是不带歧义地理解程序设计者的意图:这个函数要实现什么功能(也就是翻译成自然语言),哪些变量不能被修改或重赋值,等等。在这些约束下,编写者应当作出变通:根据需要选择容器(以及数据结构)(HashMap 查询 key 快,TreeSet 动态维护最值,ArrayList 保证 message 的顺序),根据函数实现复杂度额外实现需要的方法,或者额外实现一个辅助类等。

OK 测试体验

OK test 是让我们从测试员的角度看待规格,编写单元测试程序,对代码的单元功能进行测试,看是否严格符合 JML 规格。

这单元编写的 OK test 方法将被修改容器的数据和其他关键变量的数据,以及被测试方法的返回值传入该测试方法,在测试方法内完全按照 JML 规格检测数值正确性。

单元学习体会

经过本单元学习,我体验了程序设计者、编写者和测试者这三个身份,大概了解了 0 级 JML 语言描述,同时深深体会了编写程序过程中对各种异常情况的考虑也依赖于 JML 才能周到。不仅如此我也学到了自定义异常的使用,学到了图论的一些算法知识。但其实就收获而言,除了这单元的图论算法,我感到收获甚微。相较之下,第一单元应对表达式各层级结构要自主考虑 package 和 interface 结构带来的便利以及递归下降的灵活使用,第二单元的多线程更是打开新世界的大门,它们给我“面向对象”的感受也更深刻。

虽然如此,第三单元面向规格编程(其实 OK test 并没有被我用来测试)还是让我有了新的体验。

OO2023-U3-JML相关推荐

  1. 在VmWare Workstation 6.5上安装Esx 3.5 U3之二

    三.安装VMware ESX 3.5 Update3 在二.中,设置好了ESX 3.5在VMware 6.5中得以顺利安装的环境,接下来就要进行ESX 3.5 U3的安装了. 安装ESX 3.5 U3 ...

  2. JML规格编程——BUAA OO第三单元作业总结

    整体概述 这个单元整体围绕Java Model Language(JML)展开,通过学习JML规格了解契约式编程的过程,课上实验中进行了JML规格的简要编写,课下实验主要通过阅读规格并按照规格的要求正 ...

  3. 闪迪U3利用工具U3-Pwn

    闪迪U3利用工具U3-Pwn 闪迪U3是闪迪公司为Sandisk Cruzer系列U盘提供的一个功能.该模块支持数据加密和CD启动功能.U3-Pwn就是针对U3的一个利用工具.渗透测试人员可以通过该工 ...

  4. BUAA_OO第三单元作业总结——JML

    BUAA_OO第三单元作业总结--JML 单元任务 本单元的主要内容是熟悉JML相关的理论知识,能够根据JML规格实现对应方法,通过一步步实现地铁系统来熟悉JML规格. 一.JML语言的理论基础.应用 ...

  5. OO第三单元JML总结

    目录 目录一.JML语言的理论基础二.应用工具链三.部署SMT Solver四.部署JMLUnitNG/JMLUnit五.三次作业分析第一次作业第二次作业第三次作业六.总结与心得体会 一.JML语言的 ...

  6. OO Unit 3 JML

    目录 梳理JML语言的理论基础.应用工具链情况 部署JMLUnitNG/JMLUnit 按照作业梳理自己的架构设计,并特别分析迭代中对架构的重构 按照作业分析代码实现的bug和修复情况 阐述对规格撰写 ...

  7. OO第三单元总结:JML

    目录 第三单元--jml.junit与图 第三单元--jml.junit与图 〇.问题描述 ​ 本单元主题为JML的学习,问题载体为一个无向图路径管理系统.在三次作业种,情景不变,需求递增.因此需要在 ...

  8. oo第三次博客-JML规格

    这三周的作业主要是围绕以JML来约束代码开发,以确保程序的正确性与鲁棒性. Part 1:三次作业的实现与bug 第一次作业没有任何算法和数据结构上的难度,对于Path和PathContainer的各 ...

  9. OO_BLOG3_规格化设计(JML学习)

    目录 JML语言学习笔记 理论基础 应用工具链情况 JMLUnit/JMLUnitNG UNIT3 作业分析 作业 3-1 实现两个容器类Path和PathContainer 作业 3-2 实现容器类 ...

  10. 千元优品vivo U3上架:骁龙675处理器+5000mAh超大电池

    随着2019进入尾声,今年各大品牌的大部分旗舰级新机都已发布完毕,仅剩少数机型也将于近期亮相,除此之外,还有几款中端机型会在这最后的时间与我们见面.现在有最新消息,近日一款被称为"千元优品& ...

最新文章

  1. TIOBE 7 月编程语言榜:TypeScript 进入前 50 名
  2. java url下载ics_使用Microsoft Graph API处理外部(Internet / .ics)日历URL
  3. 软件与软件工程的概念
  4. html浏览xsd,XSD 简易元素
  5. delphi 10.4来了
  6. android 辅助功能_关于辅助功能的9个神话
  7. 真实的软件测试日常工作是咋样的?
  8. 浏览器禁用第三方Cookie
  9. servlet.ServletException: java.lang.NoClassDefFoundError: cn/huiyuan/lwj/vo
  10. NDB Cluster 基本介绍
  11. 计算机图形学中需要掌握的数学基础知识有哪些?
  12. Jenkins框架原理
  13. 易灵思Ti60 FPGA专题(1)-器件和需求介绍
  14. 处理图片有困难?分享一款在线图像处理软件给你
  15. SQL-Server常用系统存储过程
  16. 4G网络车载GPS定位器隐藏装在车头影响LTE网络信号影响及因素
  17. 先吞噬后反刍,擒贼擒王--java之我注六经之二
  18. spring不停机部署_spring cloud 学习(7) - 生产环境如何不停机热发布? - 菩提树下的杨过 - 博客园...
  19. php代码实现xml格式转换,PHP实现XML与数据格式进行转换类实例
  20. 人机交互的软件工程方法

热门文章

  1. 彻底解决安装了显卡驱动后,Ubuntu开机无法进入图形化界面、黑屏、左上角光标闪烁问题
  2. 微信下线模板消息,订阅通知如何使用?
  3. 【python】15行代码实现人脸检测(opencv)
  4. Scrapy框架--CrawlSpider (详解+例子)
  5. tomcat下载解压包
  6. ORA-00904标识符无效(太坑了!!)
  7. 基于springBoot框架开发短视频去水印源码项目+IntelliJ IDEA运行测试+本地实现功能
  8. vue3 (五) 规范一:定义界面模版
  9. 云南大学计算机专业双一流排名,2019年云南双一流大学最终名单_双一流大学排名...
  10. 深耕精品智能小车市场,推动奇瑞新能源品牌产品智能化