Part 1 JML基础
Java Modeling Language(JML)是一种行为规范语言吗,用于规定Java类和方法的行为和接口。通过jml可以严谨的定义方法和类的行为,只需要阅读jml就可以无歧义的理解类和方法的功能,并可以开展测试。
使用JML的两个主要好处是:
1、对Java程序模块(即类和接口)的行为的准确,明确的描述以及Java代码的文档
2、工具支持的可能性
jml工具目前仍在开发中(疑似弃坑),工具链尚不完善
jml工具链:
openJML:对JML注释的完整性进行检查。
JMLUnitNG:根据jml自动生成测试样例并进行测试。
Part 2 JMLunit测试
感谢https://www.cnblogs.com/nbao01/p/12935615.html这位同学的傻瓜式教程
C:\Users\a0061\Desktop\jmltest>java -cp jmlunitng.jar test.MyGroup_JML_Test [TestNG] Running: Command line suite Failed: racEnabled() Passed: constructor MyGroup(-2147483648) Passed: constructor MyGroup(0) Passed: constructor MyGroup(2147483647) Failed: <>.addPerson(null) Failed: < >.addPerson(null) Failed: < >.addPerson(null) Passed: < >.addRelationn(-2147483648, -2147483648, -2147483648) Passed: < >.addRelationn(-2147483648, -2147483648, -2147483648) Passed: < >.addRelationn(-2147483648, -2147483648, -2147483648) Passed: < >.addRelationn(0, -2147483648, -2147483648) Passed: < >.addRelationn(0, -2147483648, -2147483648) Passed: < >.addRelationn(0, -2147483648, -2147483648) Passed: < 51016012>>.addRelationn(2147483647, -2147483648, -2147483648) Passed: < >.addRelationn(2147483647, -2147483648, -2147483648) Passed: < >.addRelationn(2147483647, -2147483648, -2147483648) Passed: < >.addRelationn(-2147483648, 0, -2147483648) Passed: < >.addRelationn(-2147483648, 0, -2147483648) Passed: < >.addRelationn(-2147483648, 0, -2147483648) Passed: < >.addRelationn(0, 0, -2147483648) Passed: < >.addRelationn(0, 0, -2147483648) Passed: < >.addRelationn(0, 0, -2147483648) Passed: < >.addRelationn(2147483647, 0, -2147483648) Passed: < >.addRelationn(2147483647, 0, -2147483648) Passed: < >.addRelationn(2147483647, 0, -2147483648) Passed: < >.addRelationn(-2147483648, 2147483647, -2147483648) Passed: < 5479e3f>>.addRelationn(-2147483648, 2147483647, -2147483648) Passed: < 27082746>>.addRelationn(-2147483648, 2147483647, -2147483648) Passed: < >.addRelationn(0, 2147483647, -2147483648) Passed: < >.addRelationn(0, 2147483647, -2147483648) Passed: < >.addRelationn(0, 2147483647, -2147483648) Passed: < 24273305>>.addRelationn(2147483647, 2147483647, -2147483648) Passed: < >.addRelationn(2147483647, 2147483647, -2147483648) Passed: < >.addRelationn(2147483647, 2147483647, -2147483648) Passed: < >.addRelationn(-2147483648, -2147483648, 0) Passed: < >.addRelationn(-2147483648, -2147483648, 0) Passed: < >.addRelationn(-2147483648, -2147483648, 0) Passed: < >.addRelationn(0, -2147483648, 0) Passed: < >.addRelationn(0, -2147483648, 0) Passed: < >.addRelationn(0, -2147483648, 0) Passed: < >.addRelationn(2147483647, -2147483648, 0) Passed: < >.addRelationn(2147483647, -2147483648, 0) Passed: < >.addRelationn(2147483647, -2147483648, 0) Passed: < >.addRelationn(-2147483648, 0, 0) Passed: < >.addRelationn(-2147483648, 0, 0) Passed: < >.addRelationn(-2147483648, 0, 0) Passed: < >.addRelationn(0, 0, 0) Passed: < >.addRelationn(0, 0, 0) Passed: < >.addRelationn(0, 0, 0) Passed: < >.addRelationn(2147483647, 0, 0) Passed: < >.addRelationn(2147483647, 0, 0) Passed: < >.addRelationn(2147483647, 0, 0) Passed: < >.addRelationn(-2147483648, 2147483647, 0) Passed: < >.addRelationn(-2147483648, 2147483647, 0) Passed: < >.addRelationn(-2147483648, 2147483647, 0) Passed: < >.addRelationn(0, 2147483647, 0) Passed: < >.addRelationn(0, 2147483647, 0) Passed: < >.addRelationn(0, 2147483647, 0) Passed: < >.addRelationn(2147483647, 2147483647, 0) Passed: < >.addRelationn(2147483647, 2147483647, 0) Passed: < >.addRelationn(2147483647, 2147483647, 0) Passed: < 50675690>>.addRelationn(-2147483648, -2147483648, 2147483647) Passed: < >.addRelationn(-2147483648, -2147483648, 2147483647) Passed: < >.addRelationn(-2147483648, -2147483648, 2147483647) Passed: < >.addRelationn(0, -2147483648, 2147483647) Passed: < >.addRelationn(0, -2147483648, 2147483647) Passed: < >.addRelationn(0, -2147483648, 2147483647) Passed: < >.addRelationn(2147483647, -2147483648, 2147483647) Passed: < >.addRelationn(2147483647, -2147483648, 2147483647) Passed: < >.addRelationn(2147483647, -2147483648, 2147483647) Passed: < >.addRelationn(-2147483648, 0, 2147483647) Passed: < >.addRelationn(-2147483648, 0, 2147483647) Passed: < >.addRelationn(-2147483648, 0, 2147483647) Passed: < >.addRelationn(0, 0, 2147483647) Passed: < >.addRelationn(0, 0, 2147483647) Passed: < >.addRelationn(0, 0, 2147483647) Passed: < >.addRelationn(2147483647, 0, 2147483647) Passed: < >.addRelationn(2147483647, 0, 2147483647) Passed: < >.addRelationn(2147483647, 0, 2147483647) Passed: < >.addRelationn(-2147483648, 2147483647, 2147483647) Passed: < >.addRelationn(-2147483648, 2147483647, 2147483647) Passed: < >.addRelationn(-2147483648, 2147483647, 2147483647) Passed: < >.addRelationn(0, 2147483647, 2147483647) Passed: < >.addRelationn(0, 2147483647, 2147483647) Passed: < >.addRelationn(0, 2147483647, 2147483647) Passed: < >.addRelationn(2147483647, 2147483647, 2147483647) Passed: < >.addRelationn(2147483647, 2147483647, 2147483647) Passed: < >.addRelationn(2147483647, 2147483647, 2147483647) Failed: < >.delPerson(null) Failed: < >.delPerson(null) Failed: < >.delPerson(null) Passed: < >.equals(null) Passed: < >.equals(null) Passed: < >.equals(null) Passed: < >.equals(java.lang.Object@4b6995df) Passed: < >.equals(java.lang.Object@591f989e) Passed: < >.equals(java.lang.Object@61443d8f) Passed: < >.getAgeMean() Passed: < >.getAgeMean() Passed: < >.getAgeMean() Passed: < >.getAgeVar() Passed: < >.getAgeVar() Passed: < >.getAgeVar() Passed: < >.getConflictSum() Passed: < >.getConflictSum() Passed: < >.getConflictSum() Passed: < >.getId() Passed: < >.getId() Passed: < >.getId() Passed: < >.getRelationSum() Passed: < >.getRelationSum() Passed: < >.getRelationSum() Passed: < >.getValueSum() Passed: < >.getValueSum() Passed: < >.getValueSum() Failed: < >.hasPerson(null) Failed: < >.hasPerson(null) Failed: < >.hasPerson(null) Passed: < >.size() Passed: < >.size() Passed: < >.size() =============================================== Command line suite Total tests run: 121, Failures: 10, Skips: 0 ===============================================
jmlunit只能对int参数测试0 极大 极小三个值,对其他参数测试null,基本不能起到帮助作用
Part 3 架构设计
hw9:
概述:
用每个person分别保存自己的link集合来保存整个社交网络,network只保存id到person的映射关系。从图上可以看出,person用一个hashmap保存id-value的link信息,并保存所有name age等个人属性,network只保存id-person的hashmap
hw10:
概述:
这次添加了Group,需要额外维护group层的人数、年龄平均等信息。
与Group层级有关的询问的信息都保存在group里,每次addRelation和addToGroup时对更新所有group的信息。从图中可以看到valuesum agemean都以数值形式直接保存在group类中。
hw11:
概述:
这次group增加了删除的需求,network层面增加了查询最短路、双连通等需求,还另外添加了借钱这个功能。并不需要改变架构,只需要添加对这些需求的支持。从图中可以看出Network类中增加了dfn、low、fa用于支持图操作,增加了money用于支持借钱。
Part 4 BUG分析
hw9:
wa:认为自己与自己没有relation,导致querylink等函数出错。
hw10:
wa:如果addrelation重复添加自己,则会重复计数。
oe:提交了官方包
hw11:
wa:稍微修改了一下tarjin算法,因为我们只需要求两个点是否双连通,但是出了bug。bug实现:从一个询问人出发,dfs到另一个人,若路上所有人的子孙都有返祖边,则stronglink。修改:在dfs树上确认另一个点的位置后从该点开始,记录其子孙返祖边返回的最高点,跳到高度为该点+1的点,若能一直返回根则stronglink
tle:有一个qmp测试点ctle。qmp我采用了每次dfs的方法实现,在极限数据下时间比较接近时间限制。
Part 5 心得体会
这个单元我们主要学习了契约式设计、规格化设计,完成了三次面向规格编程的作业和一次完善规格的实验。相比指导书,规格描述部分需求时更加简便、无歧义,但是在描述一些复杂功能时非常冗长,比如查询连通块和查询双连通等功能。由于工具链尚不完善,在编写规格时往往也会出现一些难以察觉的问题,这些在实验和作业中都有所体现。测试是一个复杂的工程,只根据jml生成完备的测试显然是不现实的,我觉得jml这样一种规格语言用途也不在于自动测试,而在于辅助我们实现契约式设计,将一个大的工程拆分为互不干涉的模块。感谢课程组的老师和助教的辛苦付出;感谢分享自己宝贵经验的同学们。