下载地址 :http://insttech.secretninjaformalmethods.org/software/jmlunitng/
去除了Person类和Group类的接口,改成了新的Person类和Group类。
需要补全代码中的HashMap<>括号里的内容。
修改重名的内容
命令行输入以下几条指令:
java -jar jmlunitng.jar test/Group.java javac -cp jmlunitng.jar test/*.java java -jar openjml.jar -rac test/Group.java test/Person.java java -cp jmlunitng.jar test.Group_JML_Test
结果如下:
[TestNG] Running: Command line suite Passed: racEnabled() Passed: constructor Group(-2147483648) Passed: constructor Group(0) Passed: constructor Group(2147483647) Failed: <<test.Group@64cee07>>.addPerson(null) Failed: <<test.Group@1761e840>>.addPerson(null) Failed: <<test.Group@5ecddf8f>>.addPerson(null) Failed: <<test.Group@3f102e87>>.delPerson(null) Failed: <<test.Group@27abe2cd>>.delPerson(null) Failed: <<test.Group@5f5a92bb>>.delPerson(null) Passed: <<test.Group@6fdb1f78>>.equals(null) Passed: <<test.Group@51016012>>.equals(null) Passed: <<test.Group@29444d75>>.equals(null) Passed: <<test.Group@44e81672>>.equals(java.lang.Object@60215eee) Passed: <<test.Group@4ca8195f>>.equals(java.lang.Object@65e579dc) Passed: <<test.Group@61baa894>>.equals(java.lang.Object@b065c63) Passed: <<test.Group@768debd>>.getAgeMean() Passed: <<test.Group@490d6c15>>.getAgeMean() Passed: <<test.Group@449b2d27>>.getAgeMean() Passed: <<test.Group@5479e3f>>.getAgeVar() Passed: <<test.Group@27082746>>.getAgeVar() Passed: <<test.Group@66133adc>>.getAgeVar() Passed: <<test.Group@7bfcd12c>>.getConflictSum() Passed: <<test.Group@42f30e0a>>.getConflictSum() Passed: <<test.Group@24273305>>.getConflictSum() Passed: <<test.Group@5b1d2887>>.getId() Passed: <<test.Group@46f5f779>>.getId() Passed: <<test.Group@1c2c22f3>>.getId() Passed: <<test.Group@33e5ccce>>.getRelationSum() Passed: <<test.Group@5a42bbf4>>.getRelationSum() Passed: <<test.Group@270421f5>>.getRelationSum() Passed: <<test.Group@52d455b8>>.getValueSum() Passed: <<test.Group@4f4a7090>>.getValueSum() Passed: <<test.Group@18ef96>>.getValueSum() Passed: <<test.Group@6956de9>>.groupSize() Passed: <<test.Group@769c9116>>.groupSize() Passed: <<test.Group@6aceb1a5>>.groupSize() Failed: <<test.Group@2d6d8735>>.hasPerson(null) Failed: <<test.Group@ba4d54>>.hasPerson(null) Failed: <<test.Group@12bc6874>>.hasPerson(null) Passed: <<test.Group@de0a01f>>.updateRelation(-2147483648, -2147483648, -2147483648) Passed: <<test.Group@4c75cab9>>.updateRelation(-2147483648, -2147483648, -2147483648) Passed: <<test.Group@1ef7fe8e>>.updateRelation(-2147483648, -2147483648, -2147483648) Passed: <<test.Group@6f79caec>>.updateRelation(0, -2147483648, -2147483648) Passed: <<test.Group@67117f44>>.updateRelation(0, -2147483648, -2147483648) Passed: <<test.Group@5d3411d>>.updateRelation(0, -2147483648, -2147483648) Passed: <<test.Group@2471cca7>>.updateRelation(2147483647, -2147483648, -2147483648) Passed: <<test.Group@5fe5c6f>>.updateRelation(2147483647, -2147483648, -2147483648) Passed: <<test.Group@6979e8cb>>.updateRelation(2147483647, -2147483648, -2147483648) Passed: <<test.Group@763d9750>>.updateRelation(-2147483648, 0, -2147483648) Passed: <<test.Group@5c0369c4>>.updateRelation(-2147483648, 0, -2147483648) Passed: <<test.Group@2be94b0f>>.updateRelation(-2147483648, 0, -2147483648) Passed: <<test.Group@d70c109>>.updateRelation(0, 0, -2147483648) Passed: <<test.Group@17ed40e0>>.updateRelation(0, 0, -2147483648) Passed: <<test.Group@50675690>>.updateRelation(0, 0, -2147483648) Passed: <<test.Group@3ac42916>>.updateRelation(2147483647, 0, -2147483648) Passed: <<test.Group@47d384ee>>.updateRelation(2147483647, 0, -2147483648) Passed: <<test.Group@2d6a9952>>.updateRelation(2147483647, 0, -2147483648) Passed: <<test.Group@22a71081>>.updateRelation(-2147483648, 2147483647, -2147483648) Passed: <<test.Group@3930015a>>.updateRelation(-2147483648, 2147483647, -2147483648) Passed: <<test.Group@629f0666>>.updateRelation(-2147483648, 2147483647, -2147483648) Passed: <<test.Group@1bc6a36e>>.updateRelation(0, 2147483647, -2147483648) Passed: <<test.Group@1ff8b8f>>.updateRelation(0, 2147483647, -2147483648) Passed: <<test.Group@387c703b>>.updateRelation(0, 2147483647, -2147483648) Passed: <<test.Group@224aed64>>.updateRelation(2147483647, 2147483647, -2147483648) Passed: <<test.Group@c39f790>>.updateRelation(2147483647, 2147483647, -2147483648) Passed: <<test.Group@71e7a66b>>.updateRelation(2147483647, 2147483647, -2147483648) Passed: <<test.Group@2ac1fdc4>>.updateRelation(-2147483648, -2147483648, 0) Passed: <<test.Group@5f150435>>.updateRelation(-2147483648, -2147483648, 0) Passed: <<test.Group@1c53fd30>>.updateRelation(-2147483648, -2147483648, 0) Passed: <<test.Group@50cbc42f>>.updateRelation(0, -2147483648, 0) Passed: <<test.Group@75412c2f>>.updateRelation(0, -2147483648, 0) Passed: <<test.Group@282ba1e>>.updateRelation(0, -2147483648, 0) Passed: <<test.Group@13b6d03>>.updateRelation(2147483647, -2147483648, 0) Passed: <<test.Group@f5f2bb7>>.updateRelation(2147483647, -2147483648, 0) Passed: <<test.Group@73035e27>>.updateRelation(2147483647, -2147483648, 0) Passed: <<test.Group@64c64813>>.updateRelation(-2147483648, 0, 0) Passed: <<test.Group@3ecf72fd>>.updateRelation(-2147483648, 0, 0) Passed: <<test.Group@483bf400>>.updateRelation(-2147483648, 0, 0) Passed: <<test.Group@21a06946>>.updateRelation(0, 0, 0) Passed: <<test.Group@77f03bb1>>.updateRelation(0, 0, 0) Passed: <<test.Group@326de728>>.updateRelation(0, 0, 0) Passed: <<test.Group@25618e91>>.updateRelation(2147483647, 0, 0) Passed: <<test.Group@7a92922>>.updateRelation(2147483647, 0, 0) Passed: <<test.Group@71f2a7d5>>.updateRelation(2147483647, 0, 0) Passed: <<test.Group@2cfb4a64>>.updateRelation(-2147483648, 2147483647, 0) Passed: <<test.Group@5474c6c>>.updateRelation(-2147483648, 2147483647, 0) Passed: <<test.Group@4b6995df>>.updateRelation(-2147483648, 2147483647, 0) Passed: <<test.Group@2fc14f68>>.updateRelation(0, 2147483647, 0) Passed: <<test.Group@591f989e>>.updateRelation(0, 2147483647, 0) Passed: <<test.Group@66048bfd>>.updateRelation(0, 2147483647, 0) Passed: <<test.Group@61443d8f>>.updateRelation(2147483647, 2147483647, 0) Passed: <<test.Group@445b84c0>>.updateRelation(2147483647, 2147483647, 0) Passed: <<test.Group@61a52fbd>>.updateRelation(2147483647, 2147483647, 0) Passed: <<test.Group@233c0b17>>.updateRelation(-2147483648, -2147483648, 2147483647) Passed: <<test.Group@63d4e2ba>>.updateRelation(-2147483648, -2147483648, 2147483647) Passed: <<test.Group@7bb11784>>.updateRelation(-2147483648, -2147483648, 2147483647) Passed: <<test.Group@33a10788>>.updateRelation(0, -2147483648, 2147483647) Passed: <<test.Group@7006c658>>.updateRelation(0, -2147483648, 2147483647) Passed: <<test.Group@34033bd0>>.updateRelation(0, -2147483648, 2147483647) Passed: <<test.Group@47fd17e3>>.updateRelation(2147483647, -2147483648, 2147483647) Passed: <<test.Group@7cdbc5d3>>.updateRelation(2147483647, -2147483648, 2147483647) Passed: <<test.Group@3aa9e816>>.updateRelation(2147483647, -2147483648, 2147483647) Passed: <<test.Group@17d99928>>.updateRelation(-2147483648, 0, 2147483647) Passed: <<test.Group@3834d63f>>.updateRelation(-2147483648, 0, 2147483647) Passed: <<test.Group@1ae369b7>>.updateRelation(-2147483648, 0, 2147483647) Passed: <<test.Group@6fffcba5>>.updateRelation(0, 0, 2147483647) Passed: <<test.Group@34340fab>>.updateRelation(0, 0, 2147483647) Passed: <<test.Group@2aafb23c>>.updateRelation(0, 0, 2147483647) Passed: <<test.Group@2b80d80f>>.updateRelation(2147483647, 0, 2147483647) Passed: <<test.Group@3ab39c39>>.updateRelation(2147483647, 0, 2147483647) Passed: <<test.Group@2eee9593>>.updateRelation(2147483647, 0, 2147483647) Passed: <<test.Group@7907ec20>>.updateRelation(-2147483648, 2147483647, 2147483647) Passed: <<test.Group@546a03af>>.updateRelation(-2147483648, 2147483647, 2147483647) Passed: <<test.Group@721e0f4f>>.updateRelation(-2147483648, 2147483647, 2147483647) Passed: <<test.Group@28864e92>>.updateRelation(0, 2147483647, 2147483647) Passed: <<test.Group@6ea6d14e>>.updateRelation(0, 2147483647, 2147483647) Passed: <<test.Group@6ad5c04e>>.updateRelation(0, 2147483647, 2147483647) Passed: <<test.Group@6833ce2c>>.updateRelation(2147483647, 2147483647, 2147483647) Passed: <<test.Group@725bef66>>.updateRelation(2147483647, 2147483647, 2147483647) Passed: <<test.Group@2aaf7cc2>>.updateRelation(2147483647, 2147483647, 2147483647)
从测试数据可以看出,JMLUnitNG基本都是在测边界数据,如构造Group时用的是0、最大int、最小int,测试传入person的时候用null。
Fail的一些方法主要是因为调用的时候保证了不会传入NULL。
JMLUnitNG只注重对边界情况的测试,对一般情况则几乎没有涉及,没有随机性,测试意义不是很大。
作业中需要注意存储方式,可能会给时间复杂度带来很大影响。最好多使用Hashmap,也可以与Arraylist结合使用,如Person类我用了一个动态数组存acquaintance,一个HashMap存acquaintance的id和value的对应。以及避免使用Arraylist.contains等可以避免的O(n)方法.
认真阅读JML规格避免看错条件。
第一次作业主要是熟悉JML,因此主要问题在认真阅读JML规格。
难点是isCircle方法的实现,我采用了bfs的方法实现。
用并查集会更好,不用每次都查找一遍。

相比第一次作业加入了Group类和很多查询方法,如果每次都遍历查找时间复杂度势必会很高,而且测试指令条数很多,要注意缓存。
在加关系的时候也要注意更新缓存。

第三次作业主要难点在三个函数,涉及了数据结构的图相关的知识。
queryMinPath 函数
求权值最小路径,采用堆优化迪杰斯特拉算法,用Java的优先队列存储节点。
queryStrongLinked 函数
判断两点是否点双联通,就是求是否存在两条通过两点且除这两点外没有相同点的路径,并且只有这两点直接连接的路径只能算一条。
采用暴力遍历与这两点联通的所有点,每次去掉一个点bfs看两点是否还联通,如果存在使两点不联通的点则不是点双联通。
注意两点直接连接的情况要单独考虑,去边后再bfs一次。
queryBlockSum 函数
采用并查集实现,求联通块的个数。
同时把isCircle也改成了并查集实现。

三次作业均未测出bug。
互测中第二次作业有同学在加关系时没有更新缓存,有同学没有进行缓存导致遍历复杂度过高。
互测中第三次作业有同学方法实现上复杂度过高。
规格撰写需要尽可能周到地考虑各种情况,注意JML格式。
阅读JML规格的时候要注意括号位置和符号的含义,看清楚数字,实现每一种情况。
这个单元接触了规格化设计,体会到了性能优化的重要性。但JML相关工具链还不太完善,有些表述也比较繁琐,使用还是需要进一步优化。
原文:https://www.cnblogs.com/ldyblog/p/12941667.html