本单元的测试过程
黑箱测试&白箱测试
白盒测试:
是测试人员要了解程序结构和处理过程,按照程序内部逻辑测试程序,检查程序中的每条通路是否按照预定要求正确工作.它主要的针对被测程序的源代码,测试着可以完全不考虑程序的功能.
白盒测试流程:
源程序-->分析程序内部逻辑结构-->流程图-->制定测试用例-->被测程序-->执行路径-->覆盖情况分析
黑盒测试:
是根据功能需求来测试程序是否按照预期工作,是要从用户的角度分析.尽量发现代码所表现的外部行为的错误.黑盒测试应该是由测试团队来完成的.根据某个给定的输入,应该能够理解并详细说明程序的预期输出.
黑盒测试流程:
功能需求-->产生测试用例-->被测程序-->输出实际结果-->与预期结果比较-->分析功能是否实现.
数据构造策略
1、分析可能会影响受测试的方法的构建方法,用所有这样的构建方法构造数据
2、测试数据不需要过大但需要保证覆盖率,可以用利用Random函数随机数据
3、需要保证极端情况的测试必定存在
架构设计
hw9
queryBlockSum和queryTripleSum若完全按照JML描述构造会导致性能低下,我们选择用dfs算法维护BlockSum,用并查集在改变Relation的方法处维护TripleSum。
hw10
queryTagValueSum
显然按照JML实现的时间复杂度是不能忍受的,但对ValueSum进行维护时面对ModifyRelation,不可避免的需要遍历全体Tag修改ValueSum,对此我们可以用一个容器存储每个人被包含在哪些tag中,从person直接对应Tag修改ValueSum优化性能。
queryTagAgeVar
由于需要计算AgeMean,我们很自然想到对方差公式进行化简,只需要维护一下age的总和和平方和就可以实现对AgeVar的维护,不过计算时应当完全按照JML进行避免int取整由于计算顺序导致的误差。
queryBestAcquaintance
相对简单的方法是每次addRelation对比维护BestAcquaintance,这种方法的缺点是在删除BestAcquaintance后必须重新遍历取BestAcquaintance。Treemap维护更为适合。
hw11
hw11相较于实现更难的是理解JML,正确解释JML即可轻松实现方法。
性能问题
本次作业出现了两次性能问题,第一次是由于不了解JML的使用,实现方法时完全按照JML进行导致原本靠HashMap中get方法完成的方法也进行了遍历;第二次是ValueSum的维护,本bug由于hw10强测互测数据太弱导致我在hw11才发现未在modifyRelation对valueSum维护,目前使用全部遍历出现CTLE,尚未完成intag的实现。
对规格与实现分离的理解
从hw9就可以明显感受到规格与实现明显不同,规格类似“说明书”,它的重点在于可读性和准确性而非性能,不能死板地偷懒套用JML实现。
通过规格编写Junit测试
在本次作业中通过规格,来编写junit测试。
- 首先,应该详细的分析不同的behavior和signal的前置条件,对于每种不同前置条件,都应该构造出对应的测试数据,
以此,测试出规格中的不同分支是否工作正常。 - 对于一致性,首先是ensures中关于返回值,或修改的内容的正确性,可以根据jml内容,编写一个朴素的,正确性验证方法,来校验其正确性。
- 最后,要记得实现对pure的检测。
学习体会
在本单元的学习中,我通过学习、使用JML规格、按照JML编写自己的实现与单元测试,对规格的严谨性,清晰性的理解有了认识,JML规格在保证方法正确性,便于函数之间的调用与参数的传递的基础上,既能屏蔽函数实现细节,又能向他人展示前置条件与严谨的返回值,极大地方便了我对代码的迭代与和同学间的交流。