OO unit3 总结

21231110-司亦菲 2024-05-18 18:41:54

一、测试过程

黑箱测试与白箱测试

黑盒测试和白盒测试是软件测试中两种不同的测试方法。它们的主要区别在于测试人员是否了解被测试系统的内部结构。

黑盒测试是一种基于需求规格说明书的测试,测试人员并不需要知道被测试软件的内部实现细节。黑盒测试的目的是检查软件能否符合规格说明书的要求,以及是否存在功能缺陷、性能问题、安全漏洞等。

白盒测试是一种基于代码实现的测试,测试人员需要了解被测试软件的内部实现细节。白盒测试的目的是检查软件的实现是否正确,并发现代码中存在的逻辑错误、复杂度问题、异常处理不当等。

对一些测试的理解

单元测试

单元测试是软件开发中的一项基础测试任务,它通常由开发人员编写。单元测试的目的是针对每个模块或函数进行测试,检查其是否符合预期的行为。在执行单元测试时,通常使用单元测试框架来自动化测试。

功能测试

功能测试是基于软件用户需求规格说明书进行的测试,它的目的是检查软件是否符合用户需求,并验证其是否按照需求进行正确的操作。功能测试通常包括手动测试和自动化测试两种方式。

集成测试

集成测试是指将已经测试过的模块、组件、子系统按照设计要求和接口规范进行组装、联调和测试的过程。集成测试的主要目的是检查不同模块或组件之间的交互是否按照定义的标准进行,以验证系统是否能够正常工作。

压力测试

压力测试是通过模拟大量用户请求,在不同负载情况下测试软件系统的稳定性和性能。压力测试的目的是确定系统能够承受的最大负载和性能瓶颈,以便为增加系统的负载和性能做出相应的调整。

回归测试

回归测试是指之前已经测试过的功能,在添加新的功能或修改功能后,重新进行测试以确保系统的稳定性和完整性。回归测试的主要目的是验证修改后的代码是否影响了之前已经测试的功能,并且修改后的系统是否仍然符合规定的标准。

测试工具

通过构造一些针对性的数据和借助他人评测机进行了测试,找出了一些错误。

二、作业的架构设计和问题

对本单元的大部分代码都是在规格的基础上设计的,只是其中部分方法的实现方式可能由于我的知识缺陷而显得有些呆。

大多数容器选择了HashMap

    private static Map<Integer, Integer> countMap = new HashMap<>();  // 记录每个 person id 触发此异常的次数

在Network的iscircle方法遇到了一些问题,该方法的作用是检查两个人员的id是否存在,并判断它们是否可以组成一个链表闭环。

我最初的想法来自于离散数学课上讲到的一个定理:世界上任意两个人一定通过六个人相识。因此写出了一个看起来很麻烦的循环,以下是其中一段

            if (flag == 0) {
                for (int v1 = v + 1; v1 < end; v1++) {
                    for (int v2 = v1 + 1; v2 < end; v2++) {
                        if (people.get(v1).isLinked(people.get(v))
                                && people.get(v2).isLinked(people.get(v1))
                                && people.get(v2).isLinked(people.get(end))) {
                            flag = 1;
                        }
                    }
                }
            }

因为工作量有些太大,所以循环最终只写到4,因此也导致了许多问题,后来才进行了修改

public boolean isCircle(int id1, int id2) throws PersonIdNotFoundException {
        Person person1 = getPerson(id1);
        Person person2 = getPerson(id2);
        // 检查 person1 和 person2 是否存在
        if (person1 == null) {
            throw new MyPersonIdNotFoundException(id1);
        }
        if (person2 == null) {
            throw new MyPersonIdNotFoundException(id2);
        }
        // 使用 HashSet 存储已经访问过的 Person 对象
        Set<Person> visited = new HashSet<>();

        // 使用 DFS 从 person1 开始检查是否存在到 person2 的路径
        return isCircleDFS(person1, person2, visited);
    }

三、对规格与实现分离的理解

规格是指对函数的功能、行为和限制条件进行描述的一种形式化的表达方式,作用是帮助开发人员准确地理解需求并定义系统的预期行为,从而使得程序设计和实现变得更加明确和确定性。在根据规格完成代码时,通常是先理解规格的具体要求,理解后再结合自己选择的容器和其他函数的实现进行新的功能的实现。

规格与实现分离指的是将规格与代码实现分开编写和维护的模式。这种模式的优点在于,规格可以独立于代码进行修改和维护,而不会影响代码本身的正确性。同时,规格的独立性也使得规格的可重用性更高,可以在不同的代码实现中进行共享。

分离规格和实现还有一个好处是可以降低代码耦合度。将规格与实现分离,意味着更容易将规格重构为更具通用性的形式。同时,也容易为不同的实现选择合适的规约。

四、体会

在有规格的情况下完成代码,着实比电梯月轻松了不少。但是对JML的阅读、理解、实现还是需要花费不少时间和精力。

偷偷说一句,第一次讲JML的时候,老师就说“未来再也不会用到了”,个人写的时候也感觉JML实在有点鸡肋,在需求和代码之间夹了一步JML,就像非要把古文加上标点再翻译一样,有它也不错,但明明没有也没啥影响。

最后还是再见了,JML月。

...全文
90 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧