301
社区成员
发帖
与我相关
我的任务
分享黑箱测试主要是指不关注程序的具体实现方式,仅通过程序的运行结果和其他指标来测试程序。
与之相对,白箱测试关注程序实现的具体方式,测试的构建是基于程序的结构与逻辑的。
举例来说,在我们的作业中,评测机等是黑箱测试,代码走查等是白箱测试。
对程序的局部单元进行测试,确保每个单元在独立的情况下工作正常。单元测试的目的是通过局部的正确实现全局的正确。
在我们的作业中,Junit 测试就是一种单元测试。
针对程序的某个特定功能进行测试,验证程序能否满足规格要求。
将许多模块集中在一起进行测试,确保各个模块或组件在组合后能够协同工作。集成测试的目的是测试不同模块之间的接口与交互是否存在问题。
使用极端数据(数据量接近极限或其他极限环境)测试程序。压力测试的目的是测试程序性能的可靠性与稳定性。
强测中的大数据量并且特殊构造的数据对我们的程序进行了压力测试。
回归测试检查在加入新的代码后,程序的原有功能是否被破坏。
在我们的 bug 修复环节中,每次提交需要通过未通过的数据点并不产生新的 bug 才算一次有效修复,其中检查是否产生新 bug 的测试可以看做回归测试。
可以分别构造随机数据、边缘数据与大规模的压力数据来保证对程序的正确性与性能做出较为全面的测试。
第一次作业引入了 Person 类(图结构中的结点)、Network 类(图结构),其中 Person 之间的关系构成了一个图的结构。
第二次作业引入了 Tag 类,一个 Tag 可以看做是许多 Person 的集合,Person 之间的可以不止通过他们之间的关系关联起来,这使图的结构更加丰富。
第三次作业引入了 Message 类以及一些子类,Message 可以通过 Person 之间的关联进行传递,这也实现了一个社交网络的基本功能。
由于图的总体结构已经基本由 JML 确定,因此在完成 JML 内容后,图结构就已经被建立起来。在之后的迭代中,新添加的内容往往是在原有功能的基础上添加新的内容,较少涉及对原有内容的修改(不需要重构),因此只需要按照 JML 添加新内容即可。
参考强测的数据规模,复杂度为 O(n^2) 的算法即可通过测试,因此对于每一条指令(一般对应着 Network 中的一个方法)其能保证时间复杂度在 O(n) 以下即可。
但是,如果使用 JML 的规格描述的算法,有很多方法并不满足 O(n) 的时间复杂度,需要设计与 JML 不同的算法以满足效率要求,主要可以在以下几个方面实现:
此外,选择一个较好的容器也是十分有必要的。JML 中使用数组描述规格,但在实现时可以使用 HashMap、LinkedList 等容器更好的(更方便、效率更高)实现方法。
按照上述策略实现的程序在强测与互测中都没有出现性能问题。
我的 Junit 测试是按照对应方法 JML 规格编写的。Junit 测试不需要考虑时间复杂度,因此可以通过 JML 中的方法计算出标准结果并与测试结果比较。除了基本的功能测试,Junit 测试应着重测试一些 JML 中篇幅较少的部分,比如测试不应被修改的属性是否被修改、JML 的不变性约束是否被满足等,这些内容往往占据了 Junit 测试程序的大量篇幅。
总的来说,这一单元由于不需要自己设计架构,工作量与难度与之前的作业相比少了不少。JML 的内容虽然比较长,但结合作业的总体结构还是比较好理解的(很多时候可以大体上猜出要求再看 JML 验证)。
我认为在这一单元涉及一些算法知识是很有必要的。很多时候 JML 规格给出的算法已经可以正确的实现功能,但是好的算法能大幅地提升程序性能,因此对性能的要求可以引导同学们思考 JML 规格与具体代码实现的差异。而且新算法的引入也让通过在 Junit 测试时编写暴力对拍程序进行正确性验证的测试方式更有可行性。但是一味地强调算法并不应是这门课的目的,与往年相比,今年的作业涉及图论算法的内容有所减少,因此同学们可以把更多的注意力放在按照规格编写代码上,我认为这是一个比较好的改进。