301
社区成员
发帖
与我相关
我的任务
分享本单元要求使用JUnit进行测试,并且需要在中测中用JUnit对课程组的代码进行测试,并hack掉错误的代码
由于测试中需要自己构造数据,应该有很多同学手工捏造了很多边界数据来hack课程组代码,但是实际上在实践中发现,纯粹随机产生的数据是完全可以测试出课程组的代码错误的力大砖飞
如果你的数据没有成功,那一定是你的组数不够
我所写的测试大概是以下结构
// generate random dataset
prepareData();
// calculate std
var std = calculateStd(stdNetwork);
// check for problem
assertEqual(std, testNetwork.someOperation());
其中
测试中我设计了一个基类用来构造数据,其子类中实现具体的单元测试
黑箱测试:也称为功能测试,测试人员在不知道程序内部结构和实现细节的情况下,根据软件的功能规格说明书和用户需求来设计测试用例,验证软件系统的功能是否符合预期。其目的是从用户的角度验证软件的输入和输出是否正确,确保软件在各种条件下都能正常工作。
JUnit
白箱测试:也称为结构测试或透明盒测试,测试人员需要了解软件内部的代码结构和实现细节。通过对程序内部逻辑、代码路径、条件分支等进行测试,确保软件内部操作按预期进行,且代码覆盖率高,从而提高软件质量和可靠性。
互测

架构就是按照JML规格实现的,其实没什么特别值得讲的
Network中包含了一个并查集,其他绝大部分的数值都是动态维护的。
本单元绝大部分的性能要求都可以通过动态维护满足
大部分携带Id域的数据都通过hashmap维护,Person中的acquaintance由PersonNode维护Person和Value
private final HashMap<Integer, PersonNode> acquaintance;
public class PersonNode {
private final Person person;
private final int value;
public PersonNode(Person person, int value) {
this.person = person;
this.value = value;
}
public Person getPerson() {
return person;
}
public int getValue() {
return value;
}
}
正如前面所说,绝大多数的性能问题都可以通过动态维护解决
public T getValue() {
if (resetValue) {
this.value = calculateValue();
}
return value;
}
可达性问题通过并查集解决,大部分同学都是这样处理的,没有叙述的必要
对于最短路径,我采用了Dijkstra算法
PriorityQueue<Path> queue
= new PriorityQueue<>(Comparator.comparing(Path::getValue));
HashSet<Integer> visited = new HashSet<>();
Path current = new Path(id1, id1, 0);
while (current.getTo() != id2) {
for (PersonNode personNode
: ((MyPerson) getPerson(current.getTo()))
.getAcquaintance().values()) {
MyPerson person = (MyPerson) personNode.getPerson();
if (visited.contains(person.getId())) {
continue;
}
queue.add(new Path(id1, person.getId(), current.getValue() + 1));
visited.add(person.getId());
}
current = queue.poll();
}
return current.getValue() - 1;
按照规格的写既不好维护又慢
正如在测试部分所说,断言部分严格按照JML的描述来实现,一定程度上简化了书写测试的难度
然而,我相信写JML的人极度的痛苦,所以这不过是把问题从一个部分移到了另一个部分
JML在绝大部分情况下都是这样的,本质上把实现的困难放到了书写JML的过程里,没有什么意义
JML真没什么用,看的痛苦,恐怕写的也痛苦,建议删了,没有什么自然语言描述不了的情况