在端到端测试中处理第三方 API 请求
Handling third-party API requests in End-to-End testing
我想通过端到端测试来测试我的 Rest API。据我了解,集成测试之间的区别在于我们不进行内存系统配置,而是使用真实的测试数据库和网络请求。
但我无法理解如何处理第三方 API 请求(例如 GitHub 或 Bitbucket API)。
创建一个假的 Github 帐户并使用我的测试获取的假数据是正常的做法吗?
以及如何处理访问令牌,并非所有服务都是 public,甚至 public 服务也会因速率限制而失败。
Is it a normal practice to create a fake Github account with fake data that would be fetched by my tests ?
是的。 E2E 测试(相对于集成测试)的目的是验证整个系统是否与所有实际系统组件一起工作,包括您控制的和您不控制的组件。这可能很难设置并且很难维护;但其中许多痛点将暴露您的生产服务中真正的潜在问题。您的服务如何应对这种不稳定性本身就是一项需要测试的功能:您的系统会崩溃和烧毁,还是会优雅地显示错误消息并支持良好的重试处理?
这也为您提供了一种 mock 无法提供的覆盖范围:如果您使用的第三方 API 很顽皮并引入了某种破坏性变更,您的 E2E 测试将捕捉到它。这是持续 运行 您的 E2E 套件的一个很好的理由;不仅仅是在部署期间。
此类测试的下一级别是 chaos engineering,您不仅要测试您的生产系统,还要有目的地引入故障(是的,引入产品)以确保您的服务能够真正处理压力。
And what to do with access tokens, not all services are public and even public services can fail with rate limit.
您的暂存环境应该为外部服务配置单独的沙箱帐户。我不确定你所说的 "not all services are public" 是什么意思,但只是努力让你的登台环境(或测试用户)尽可能与真正的产品用户相同。对于不支持多个访问令牌的服务,您可以发挥创意并尝试在他们的系统中清楚地描述您的测试数据。
速率限制可能很烦人,但如果您已经接近到足以让您的测试超出限制,那么无论如何您都应该采取一种策略来解决这个问题(与服务协商,获得多个帐户,. ..).
运行 当服务关闭或网络延迟触发某些测试超时时,您针对第 3 方服务的测试可能会导致测试缓慢且不稳定。更不用说您 运行 触发 API 速率限制的风险,具体取决于您使用的第 3 方服务。理想情况下,您的测试应该是确定性的,而不是随机失败,并且不需要条件逻辑来处理特定测试用例中的错误。如果您希望需要处理错误,那么应该有一个特定的测试用例来覆盖每个构建中 运行 的那些错误,而不是等待来自第 3 方的非确定性故障。
人们会提出的一个论点是,如果第 3 方 API 由于某种原因中断,您的测试应该通知您。不过,一般来说,大多数主要的第 3 方 API 都非常稳定,不太可能做出重大更改。即使它确实发生了,这种发现 API 损坏的方式也是一种尴尬和令人困惑的方式,而且很可能,您的测试不会是您首先听到它的地方。您的客户和您的生产错误跟踪器更有可能通知您。如果您想跟踪这些服务何时更改或关闭,进行某种定期生产检查来验证它是有意义的。
至于如何围绕这些情况编写测试,那就有点棘手了。 Ruby 中有 VCR in Ruby which work well for stubbing out your language's internet connections and allowing you to stub out, record, and customize responses (there's a list of similar implementations in other languages further down in their readme). That doesn't work for when your browser connects to those resources in automated end-to-end tests, though. There are tools that proxy your browser's web connection such as Puffing Billy 等工具,但设置过程非常复杂,包括管理安全证书。当某些东西运行不正常时,这看起来非常脆弱且难以调试。
编写确定性和可维护的测试的最佳选择可能是在测试模式下伪造服务。 thoughtbot has a pretty decent video on this and here's a high-level article from CircleCI。本质上,您在测试模式下换入一个适配器,代表您的第 3 方服务集成。也许您可以在本地计算机上做的是,可以通过环境变量选择性地使用真实服务或适配器,以验证测试 运行 是否与两者相同。您还可以针对真实情况设置 运行 的每日构建,以便它可以验证测试是否仍然正常工作,而不会给您更频繁的构建引入很多不稳定因素。不过,我 运行 遇到的一个问题是,即使我在第 3 方服务上设置了一个测试帐户,结果也会随着时间的推移而改变,因为我为了测试新功能而添加或修改了信息,例如添加新的存储库、修改问题等。需要额外考虑将您的测试帐户维护为所有测试的一组固定装置。
我遇到的另一个可能有用的工具是 ngrok-tunnel(又是 Ruby)之类的工具。这仅在您需要第三方服务联系您的应用程序的情况下才有意义,因为他们无法通过网络向 localhost:3000
发送请求。如果您配置了某种网络挂钩,像这样的服务可以使测试更加简单。
我想通过端到端测试来测试我的 Rest API。据我了解,集成测试之间的区别在于我们不进行内存系统配置,而是使用真实的测试数据库和网络请求。
但我无法理解如何处理第三方 API 请求(例如 GitHub 或 Bitbucket API)。
创建一个假的 Github 帐户并使用我的测试获取的假数据是正常的做法吗?
以及如何处理访问令牌,并非所有服务都是 public,甚至 public 服务也会因速率限制而失败。
Is it a normal practice to create a fake Github account with fake data that would be fetched by my tests ?
是的。 E2E 测试(相对于集成测试)的目的是验证整个系统是否与所有实际系统组件一起工作,包括您控制的和您不控制的组件。这可能很难设置并且很难维护;但其中许多痛点将暴露您的生产服务中真正的潜在问题。您的服务如何应对这种不稳定性本身就是一项需要测试的功能:您的系统会崩溃和烧毁,还是会优雅地显示错误消息并支持良好的重试处理?
这也为您提供了一种 mock 无法提供的覆盖范围:如果您使用的第三方 API 很顽皮并引入了某种破坏性变更,您的 E2E 测试将捕捉到它。这是持续 运行 您的 E2E 套件的一个很好的理由;不仅仅是在部署期间。
此类测试的下一级别是 chaos engineering,您不仅要测试您的生产系统,还要有目的地引入故障(是的,引入产品)以确保您的服务能够真正处理压力。
And what to do with access tokens, not all services are public and even public services can fail with rate limit.
您的暂存环境应该为外部服务配置单独的沙箱帐户。我不确定你所说的 "not all services are public" 是什么意思,但只是努力让你的登台环境(或测试用户)尽可能与真正的产品用户相同。对于不支持多个访问令牌的服务,您可以发挥创意并尝试在他们的系统中清楚地描述您的测试数据。
速率限制可能很烦人,但如果您已经接近到足以让您的测试超出限制,那么无论如何您都应该采取一种策略来解决这个问题(与服务协商,获得多个帐户,. ..).
运行 当服务关闭或网络延迟触发某些测试超时时,您针对第 3 方服务的测试可能会导致测试缓慢且不稳定。更不用说您 运行 触发 API 速率限制的风险,具体取决于您使用的第 3 方服务。理想情况下,您的测试应该是确定性的,而不是随机失败,并且不需要条件逻辑来处理特定测试用例中的错误。如果您希望需要处理错误,那么应该有一个特定的测试用例来覆盖每个构建中 运行 的那些错误,而不是等待来自第 3 方的非确定性故障。
人们会提出的一个论点是,如果第 3 方 API 由于某种原因中断,您的测试应该通知您。不过,一般来说,大多数主要的第 3 方 API 都非常稳定,不太可能做出重大更改。即使它确实发生了,这种发现 API 损坏的方式也是一种尴尬和令人困惑的方式,而且很可能,您的测试不会是您首先听到它的地方。您的客户和您的生产错误跟踪器更有可能通知您。如果您想跟踪这些服务何时更改或关闭,进行某种定期生产检查来验证它是有意义的。
至于如何围绕这些情况编写测试,那就有点棘手了。 Ruby 中有 VCR in Ruby which work well for stubbing out your language's internet connections and allowing you to stub out, record, and customize responses (there's a list of similar implementations in other languages further down in their readme). That doesn't work for when your browser connects to those resources in automated end-to-end tests, though. There are tools that proxy your browser's web connection such as Puffing Billy 等工具,但设置过程非常复杂,包括管理安全证书。当某些东西运行不正常时,这看起来非常脆弱且难以调试。
编写确定性和可维护的测试的最佳选择可能是在测试模式下伪造服务。 thoughtbot has a pretty decent video on this and here's a high-level article from CircleCI。本质上,您在测试模式下换入一个适配器,代表您的第 3 方服务集成。也许您可以在本地计算机上做的是,可以通过环境变量选择性地使用真实服务或适配器,以验证测试 运行 是否与两者相同。您还可以针对真实情况设置 运行 的每日构建,以便它可以验证测试是否仍然正常工作,而不会给您更频繁的构建引入很多不稳定因素。不过,我 运行 遇到的一个问题是,即使我在第 3 方服务上设置了一个测试帐户,结果也会随着时间的推移而改变,因为我为了测试新功能而添加或修改了信息,例如添加新的存储库、修改问题等。需要额外考虑将您的测试帐户维护为所有测试的一组固定装置。
我遇到的另一个可能有用的工具是 ngrok-tunnel(又是 Ruby)之类的工具。这仅在您需要第三方服务联系您的应用程序的情况下才有意义,因为他们无法通过网络向 localhost:3000
发送请求。如果您配置了某种网络挂钩,像这样的服务可以使测试更加简单。