301
社区成员
发帖
与我相关
我的任务
分享黑箱测试:
黑箱测试主要关注软件功能是否能按照需求规格说明正确执行,测试者无需了解程序内部结构或逻辑。主要测试输入输出,验证功能和系统行为是否符合预期。
白箱测试:
白箱测试也称为结构测试,测试者需了解程序内部逻辑结构,通过测试内部代码逻辑的路径,确保每个逻辑路径都被测试到。可以测试到代码的内部结构,有助于发现隐蔽的代码缺陷。
单元测试:
功能测试:
集成测试:
压力测试:
回归测试:
整体的架构和JML中的书写相同,需要特别注意的是isCircle,queryBlockSum,queryTripleSum这三个函数的实现.
queryBlockSum 和 queryTripleSum 都用的是动态维护的方法来计算blockSum,tripleSum的值。通过在addPerson,addRelation,modifyRelation时及时更新blockSum,tripleSum的值。
对于isCircle,我构建了并查集。并查集通过路径压缩优化查找效率,确保快速响应查询请求。
我采用了深度优先搜索(DFS)来辅助并查集的操作,在removeBlockSum方法中使用。
blockCount ,反映新的群体数量。我使用广度优先搜索算法(BFS)在 queryShortestPath 方法中找到两个人物之间的最短路径。
本次作业迭代中,主要增加了MyTag类,我使用大顶堆来维护了bestAcquaintanceHeap,在调用bestAcquaintance方法时,直接从堆顶取出,效率是 $O(1)$ .
public MyPerson(int id, String name, int age) {
this.bestAcquaintanceHeap = new PriorityQueue<>(getAcquaintanceComparator());
...
}
public Comparator<Person> getAcquaintanceComparator() {
return (p1, p2) -> {
int value1 = queryValue(p1);
int value2 = queryValue(p2);
if (value1 != value2) {
return Integer.compare(value2, value1);
} else {
return Integer.compare(p1.getId(), p2.getId());
}
};
}
在本次作业迭代中,主要增加了几个Message类,没有什么复杂度比较高的方法,我也没有做进一步的优化,直接根据JML写的。
本次作业,我一开始没有采用并查集,只是用Hash Map存了图,用DFS遍历的,时间复杂度比较高,尤其是多次调用 queryBlockSum 和 queryTripleSum 时,会导致TLE。
解决方法是按上面架构设计与图模型构建-HW9的方法来优化算法。
本次作业中,我的queryTagValueSum方法处理不到位,我没有考虑到在调用M有Tag类中的getValueSum时,时间复杂度是 $O(N^2)$ ,导致了TLE。
解决方法是在添加或删除标签内的成员、添加或删除成员间的关系,以及修改现有关系的值时,动态的维护MyTag类中的valueSum的值。动态维护时可以只扫两个人共同邻居的tag里是否有这两人,简化方法。
Set<Integer> neighbors1 = person1.getAcquaintance().keySet();
Set<Integer> neighbors2 = person2.getAcquaintance().keySet();
Set<Integer> commonNeighbors = new HashSet<>(neighbors1);
commonNeighbors.retainAll(neighbors2);
for (Integer neighborId : commonNeighbors) {
MyPerson neighbor = (MyPerson) getPerson(neighborId);
for (Tag tag : neighbor.getTags().values()) {
((MyTag) tag).updateTagValueSum();
}
}
本次作业中,我由于JML读的不细致,没有读到/@ public invariant socialValue == money * 5;,所以我没有给MyRedEnvelopeMessage,MyNoticeMessage,MyEmojiMessage中的socialValue赋值,导致了较为严重的bug。Bug修复也比较简单,加上一句赋值即可。
规格描述“做什么”,实现描述“怎么做”。规格应清晰、完整,又不能太过细节 容易局限住实现的方式,实现应尽量独立,便于修改和维护。
根据JML编写Junit测试,注意先检验是否符合规格的数据要求,拷贝一份network。比对修改的network和旧的network,更改的部分是否符合规格要求,不能更改的部分是否没有更改。
修改的network要能满足修改后的各项要求,且需要用一个正确的方法进行比对。
本单元的任务其实不是非常困难,起初难点是JML的理解,随着对JML的理解逐渐深入,根据JML写出符合规格的代码实现也不再困难。容易出错的地方变成了算法是否高效,以及JML的阅读是否足够细致。由于很多情况下,需要多次调用计算结果的类,所以这类方法要尽量保证$O(n)$的复杂度,否则很容易造成超时。