BUAA_oo_Unit3_blog

**

分析本单元的测试过程

关于黑箱测试、白箱测试的目的、意义及其对比
黑箱测试和白箱测试是软件测试中的两种基本方法,它们在测试的关注点、测试时机、执行方式和适用范围上有所不同。

黑箱测试(Black Box Testing)
黑箱测试是一种功能性的测试方法,测试人员不需要了解被测试的软件系统的内部结构、设计和实现。测试的目的是检查软件的各个功能是否符合用户的需求和规格说明书。测试人员只需关注输入和输出,选择合适的输入数据,观察软件是否产生预期的输出。黑箱测试可以用来发现界面问题、输入输出错误、数据结构或外部数据库访问错误等。

白箱测试(White Box Testing)
白箱测试则侧重于程序的内部逻辑和代码结构。测试人员需要了解程序的内部工作原理,根据程序的内部逻辑来设计测试用例。白箱测试通常可以检查代码中的每个逻辑路径,确保所有语句都至少执行一次,并且能够发现内部结构上的错误,如算法错误、逻辑错误等。

对比

  • 目的:黑箱测试关注软件的功能性,白箱测试关注软件的结构和内部逻辑。
  • 知识要求:黑箱测试不需要测试者具备编程知识,而白箱测试通常需要测试者有一定的编程和内部结构知识。
  • 测试用例设计:黑箱测试基于需求和规范,白箱测试基于代码结构和逻辑。
  • 适用阶段:黑箱测试可以在软件开发的早期阶段进行,而白箱测试通常在单元测试阶段进行。
  • 测试范围:黑箱测试更适合于集成测试和系统测试,白箱测试更适合于单元测试。
    在实际的软件开发过程中,黑箱测试和白箱测试往往是互补的,结合使用这两种测试方法,可以更全面地确保软件的质量。

关于单元测试、功能测试、集成测试、压力测试、回归测试的理解与应用
单元测试、功能测试、集成测试、压力测试和回归测试是软件测试过程中的不同类型,它们各自有不同的目的和关注点。

单元测试(Unit Testing)
单元测试是最小的测试单位,它针对软件中的最小可测试部分进行检查和验证。通常,一个单元是指一个函数或方法。单元测试的目的是确保每个单元都能按照预期工作。开发人员通常会在编写代码的同时编写单元测试,以验证代码的每个部分是否正确执行。单元测试可以由开发工具或专门的测试框架自动执行。

功能测试(Functional Testing)
功能测试也称为行为测试,它侧重于软件的功能性和业务逻辑。测试人员会根据软件的需求规格说明书设计测试用例,检查软件的功能是否符合预期。功能测试可以是黑盒测试,测试人员不需要了解代码的内部结构。功能测试通常在单元测试之后进行,以确保各个功能模块在集成后能够正常工作。

集成测试(Integration Testing)
集成测试是在单元测试之后进行的,它旨在验证不同模块或服务之间的接口是否能够正确地协同工作。集成测试可以检测模块间的接口问题、数据通信问题、数据一致性问题和潜在的性能瓶颈。集成测试可以是自上而下的(从高层模块开始测试),也可以是自下而上的(从底层模块开始测试),或者采用灰盒测试的方式。

压力测试(Stress Testing)
压力测试是评估软件在极端工作负载下的性能和稳定性。这种测试通过模拟高负载、持续的工作状态来检查软件是否能够正常处理大量的请求和数据,以及是否能够在压力下恢复和稳定运行。压力测试的目的是找出软件的极限,并确保在正常工作范围内软件的性能是可接受的。

回归测试(Regression Testing)
回归测试是在软件发生变更(如添加新功能、修复错误或性能改进)后进行的测试,以确保变更没有引入新的错误或导致现有功能失败。回归测试可以是自动化的,通过自动测试脚本来执行一系列的测试用例,确保软件的稳定性和质量。回归测试是持续集成和持续部署过程中的重要组成部分。

在实际的软件测试过程中,这些测试类型通常是按照一定的顺序进行的,以确保软件的每个层面都得到了充分的验证。通过综合运用这些测试方法,可以大大提高软件的质量和可靠性。

数据构造有何策略

  1. 覆盖网络操作的接口:包括add_person、add_relation、query_value、add_tag、add_to_tag、query_social_value、load_network等接口。这些测试用例涵盖了网络操作的基本功能。
  2. 验证异常情况:包括重复添加同一Person对象、添加不存在的Person对象关系、查询不存在的Person对象关系值、为不存在的Person对象添加Tag、将不存在的Person对象添加到Tag中等异常情况。这些测试用例能够验证接口对异常情况的处理。
  3. 测试不同规模的网络:包括只包含2个Person对象的小网络,以及包含3000个Person对象的大网络。这些测试用例能够验证接口在不同规模网络上的性能和稳定性。
  4. 测试网络的不同连接方式:包括完全连接、星型连接、链式连接等不同连接方式的网络。这些测试用例能够验证接口对复杂网络结构的处理能力。
  5. 测试不同类型的Tag和Message:包括为Person对象添加不同id的Tag、向Tag中添加不同id的Person对象、添加不同类型的Message等。这些测试用例能够验证接口对复杂对象的处理能力。
  6. 测试网络操作接口的组合:包括先加载网络,然后进行增删改查操作,最后进行网络查询等组合操作。这些测试用例能够验证接口组合使用的正确性。
  7. 测试性能:包括测试添加大量Person对象和关系、查询大量Person对象关系的性能。这些测试用例能够验证接口的性能。
    这些测试用例从不同角度对接口进行了全面测试,能够有效验证接口的正确性、稳定性和性能。

梳理本单元的架构设计,分析自己的图模型构建和维护策略

顶层类图
Network中只保管着Person和未发送的Message。而每个Person负责管理自己的tags、acquaintances和messages. Tags里再管理其中的Person.

分析作业中出现的性能问题及其修复情况,谈谈自己对规格与实现分离的理解

CPUTimeErrorExit是最主要的性能问题,其产生的原因是查询操作
O(n^2)的时间复杂度,其修复的方法主要由有两个方向。
其一是缩小查询的范围。比如qcs操作可以由O(n^2)的时间复杂度降低到O(n)的时间复杂度。
其二是动态维护,其实现类似于DP算法,比如qvs操作。
关于规格与实现分离,在笔者看来,规格本质上是面向结果的,实现是面向对象的。
实际上JML规格是对调用者和被调用者的行为以及调用前后产生的影响进行限制,从而保证程序运行结果的有效和安全。
规格与实现的分离是自我检查,自我测试的重要方法。将预期结果通过规格化的语言描述出来,达到分离程序实现的过程和程序测试的过程的目的。

总结分析如何利用规格信息来更好的设计实现Junit测试

在软件开发过程中,JUnit 是一个广泛使用的Java单元测试框架。要有效地使用 JUnit 设计和实现测试,首先需要理解规格信息,它通常包括需求文档、设计文档、API 文档以及相关的用户故事或用例。以下是利用规格信息更好地设计实现 JUnit 测试的步骤:

  1. 理解需求和规格
    • 需求分析:详细阅读需求文档,理解功能点、业务规则以及用户期望。
    • API 文档:对于要测试的类和方法,查看其 API 文档以理解输入、输出和可能的异常。
  2. 识别测试点
    • 根据规格信息,识别每个功能点或方法的重要测试场景。
    • 为每个测试点确定预期结果和可能的边界条件。
  3. 设计测试用例
    • 每个测试用例应该包括测试步骤、预置条件、执行条件和预期结果。
  4. 编写测试代码
    • 使用 JUnit 的注解(如 @Test)来标识测试方法。
    • 实现测试方法,确保它们符合测试用例的设计。
    • 使用断言方法(如 assertEquals(), assertTrue(), assertThrows() 等)来验证实际结果与预期结果是否一致。
  5. 处理边界条件
    • 确保测试覆盖了所有边界情况,包括最大值、最小值、空值、异常值等。
    • 对于边界测试,可能需要设计特殊的测试用例。
  6. 实现测试固件
    • 使用 JUnit 的 @Before@After 注解来设置测试固件(setUp)和拆除测试固件(tearDown)。
    • 测试固件用于初始化测试环境,确保每次测试都在相同的环境中进行。
  7. 测试驱动开发(TDD)
    • 如果可能,采用测试驱动开发(TDD)的方法,先编写测试,再编写实现代码。
    • 这样可以确保代码的设计和实现与测试规格紧密对应。
  8. 持续集成
    • 将 JUnit 测试集成到构建过程中,如使用 Jenkins、Travis CI 或其他 CI/CD 工具。
    • 确保每次代码提交或合并都会触发测试运行。
  9. 测试覆盖率
    • 使用工具如 JaCoCo 来测量测试覆盖率,确保代码的主要路径被测试覆盖。
    • 不断地改进测试,提高代码的测试覆盖率。
  10. 回归测试
    • 当代码变更后,运行完整的测试套件以确保新的变更没有破坏现有功能。
  11. 文档和报告
    • 记录测试结果,并在需要时编写测试报告。
    • 确保测试代码的可维护性,必要时添加注释说明测试目的和逻辑。
      通过上述步骤,可以确保 JUnit 测试的设计和实现与规格信息保持一致,并且能够有效地验证代码的正确性和稳定性。

本单元学习体会

为了实现越来越具体的目的,我们研发了愈加复杂的系统。这里就产生了一个矛盾。
一方面,对于实现的正确性,只有投入到生产实践才能知道;另一方面,想要投入到生产实践,就必须保证实现的正确性。
为了解决或者阶段性解决上面提出的矛盾,对于将要实现的甲程序,就必须在实现甲程序的过程中加入自我检查的程序。也就是说,甲程序可能包括甲1、甲2、甲3等程序,但是在上面的组成部分基础之上,一定包括一个甲test程序,这样就产生了程序构造的两个必要过程,即实现过程和测试/修正过程。
我们在实现的过程中,可能产生了若干个BUG,然后在测试过程中对它们进行修复,这样的过程中,两个阶段的任务是分开的,实现的过程没有考虑到修复的过程,这样的构造过程比较原始,效率较低,程序质量的期望较低。
在这样的情况下,我们引入规格,规格作为实现的一部分,以接口的形式存在于程序中,有效降低程序实现过程中BUG产生的几率,同时为测试过程提供比对的样板,有效提高测试效率。
规格的引入,将实现过程和测试过程相互联系、有机结合,促进复杂系统的实现效率和正确性的提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值