Grails unit/intergration 测试
Grails unit/intergration testing
我正在尝试为我的 grails 应用程序添加单元测试和集成测试,但我在如何区分两者以及何时使用单元或集成来测试我的控制器操作和服务方面遇到了一些问题。
网上找的教程不是很干净。我找不到要跟进的完整示例。
能否分享有用的主题?
集成测试的一个问题是它们的速度。对我来说,集成测试需要 15 秒以上才能启动。在那段时间里,某些事情确实会从脑海中消失。
我更喜欢在 2 秒内开始的单元测试,并且可以在这 15 秒内 运行 多次。
单元测试的另一个论点是它们迫使您解耦代码。集成测试总是引诱您只依赖于其他一些现有的和已初始化的组件。
重要链接:
http://spockframework.org/spock/docs/1.0/interaction_based_testing.html
http://docs.grails.org/latest/guide/testing.html
不幸的是,这不仅仅是一个问题偏好或速度。这是一个很大的课题,但我可以根据我的经验给你一些建议。
如果您希望通过使用单元测试来覆盖您的数据库访问代码(查询、事务行为),那您就是在自欺欺人。您正在测试您的查询如何符合 GORM 的内存实现。不是休眠,不是你的数据库。
我通常有两种类型的测试。单元和功能测试。功能测试将执行完整测试,运行针对真实数据库,并像用户一样刺激系统(如果它是一个通过 Geb 的网站,如果它是一个 REST api,通过一个 REST 客户端)。
功能测试将首先通过执行某种固定代码来设置启动状态。例如,这可以是注册用户并让他们登录。然后测试将 运行,然后检查后置条件。在这里,您可以通过 GORM API 访问数据库或使用生产 API 调用来检查后置条件(存在用另一个错误覆盖错误的危险)。
有时,您的系统会与第三方系统交互。在这里,如果可以的话,您可以通过将模拟实现注入被测系统来模拟第三个系统的实现。
您还拥有像 Spring Cloud Contract 这样的工具,它允许您为被测系统创建一个模拟服务器,并为您的第三方系统创建一个规范。参见 https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html
单元测试,我用来彻底测试给定 class 的所有执行路径。我将尝试触发所有异常状态,所有次要场景,以确保涵盖所有内容。我认为通过使用功能或集成测试来达到 100% 的覆盖率是不现实的。
我遵循以下准则:
尽可能多地编写单元测试。它们可以为控制器、服务、域 类 或任何其他 groovy 类 编写。这个想法是单元测试是开发人员的朋友。编写足够的单元测试将
确保开发人员犯的错误较少。当他们执行
很快,这意味着快速验证。但是单元测试无法测试以下内容:
- 条件查询,HQL 查询
- 实际数据库交互(查询、事务行为、更新、数据库约束等)
- 模块间交互
所以我们也编写集成测试
集成测试需要更长的时间来执行。编写集成测试通常需要引导数据。但它们确实有助于端到端测试功能(不包括通过 UI 编写的功能测试的实际用户交互)。所以集成测试可以写成:
- 将所有数据库交互作为单元测试进行测试实际上并不测试数据库交互。这还包括测试标准、hql 等,
- 测试事务行为(依赖于数据库)
- 端到端测试实施。所以这也将测试两个独立创建的模块如何相互交互,并确保我们正确地创建了它们。
我正在尝试为我的 grails 应用程序添加单元测试和集成测试,但我在如何区分两者以及何时使用单元或集成来测试我的控制器操作和服务方面遇到了一些问题。
网上找的教程不是很干净。我找不到要跟进的完整示例。
能否分享有用的主题?
集成测试的一个问题是它们的速度。对我来说,集成测试需要 15 秒以上才能启动。在那段时间里,某些事情确实会从脑海中消失。
我更喜欢在 2 秒内开始的单元测试,并且可以在这 15 秒内 运行 多次。
单元测试的另一个论点是它们迫使您解耦代码。集成测试总是引诱您只依赖于其他一些现有的和已初始化的组件。
重要链接: http://spockframework.org/spock/docs/1.0/interaction_based_testing.html http://docs.grails.org/latest/guide/testing.html
不幸的是,这不仅仅是一个问题偏好或速度。这是一个很大的课题,但我可以根据我的经验给你一些建议。
如果您希望通过使用单元测试来覆盖您的数据库访问代码(查询、事务行为),那您就是在自欺欺人。您正在测试您的查询如何符合 GORM 的内存实现。不是休眠,不是你的数据库。
我通常有两种类型的测试。单元和功能测试。功能测试将执行完整测试,运行针对真实数据库,并像用户一样刺激系统(如果它是一个通过 Geb 的网站,如果它是一个 REST api,通过一个 REST 客户端)。
功能测试将首先通过执行某种固定代码来设置启动状态。例如,这可以是注册用户并让他们登录。然后测试将 运行,然后检查后置条件。在这里,您可以通过 GORM API 访问数据库或使用生产 API 调用来检查后置条件(存在用另一个错误覆盖错误的危险)。 有时,您的系统会与第三方系统交互。在这里,如果可以的话,您可以通过将模拟实现注入被测系统来模拟第三个系统的实现。 您还拥有像 Spring Cloud Contract 这样的工具,它允许您为被测系统创建一个模拟服务器,并为您的第三方系统创建一个规范。参见 https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html
单元测试,我用来彻底测试给定 class 的所有执行路径。我将尝试触发所有异常状态,所有次要场景,以确保涵盖所有内容。我认为通过使用功能或集成测试来达到 100% 的覆盖率是不现实的。
我遵循以下准则:
尽可能多地编写单元测试。它们可以为控制器、服务、域 类 或任何其他 groovy 类 编写。这个想法是单元测试是开发人员的朋友。编写足够的单元测试将 确保开发人员犯的错误较少。当他们执行 很快,这意味着快速验证。但是单元测试无法测试以下内容:
- 条件查询,HQL 查询
- 实际数据库交互(查询、事务行为、更新、数据库约束等)
- 模块间交互 所以我们也编写集成测试
集成测试需要更长的时间来执行。编写集成测试通常需要引导数据。但它们确实有助于端到端测试功能(不包括通过 UI 编写的功能测试的实际用户交互)。所以集成测试可以写成:
- 将所有数据库交互作为单元测试进行测试实际上并不测试数据库交互。这还包括测试标准、hql 等,
- 测试事务行为(依赖于数据库)
- 端到端测试实施。所以这也将测试两个独立创建的模块如何相互交互,并确保我们正确地创建了它们。