我前段时间写了一个测试,测试我在代码和第三方 API 之间编写的集成。测试确保集成正常工作并且我们得到预期的结果。
今天正式构建失败,因为测试在尝试连接到第三方 API 时收到 500 错误。
测试这样的情况有意义吗?
我前段时间写了一个测试,测试我在代码和第三方 API 之间编写的集成。测试确保集成正常工作并且我们得到预期的结果。
今天正式构建失败,因为测试在尝试连接到第三方 API 时收到 500 错误。
测试这样的情况有意义吗?
在我看来,如果第 3 方(数据库、网络服务等)不可用,集成测试失败是可以的。如果您不想测试集成本身而只是简单的功能,您可以模拟 API 的结果并针对它们进行测试。在那种情况下,您的测试不再取决于第 3 方的可用性。
我通常根据第 3 方的可用性使用“集成”之类的组属性标记单元测试,并将它们从持续集成过程中排除。相反,我让它们在夜间构建中运行。集成测试的时间成本通常很高,而持续集成的重点是提供快速反馈。
不,当第三方服务关闭时,您的测试套件失败是没有帮助的。但是您确实想全面测试您与服务的集成。以下策略对我来说效果很好:
将第三方服务隔离在一个模块中(假设是一个类,但是您的语言模块化很好)除了封装与服务的连接之外,它还尽可能少地做。在类上编写方法,以便可以区分错误是服务的错误和错误是您的错误。例如,给服务中断异常一个通用的超类。
编写服务类的单元测试,以便
如果发生服务关闭错误,则测试通过但记录错误。
如果发生任何其他错误,则照常失败。
编写这些测试,以便它们针对实时服务运行。这些测试的数量应该很少,因此它们不应该为测试套件运行时造成问题。
从所有其他测试(包括集成测试)中存根或模拟服务类。(这里的“集成测试”是指测试您自己代码的所有层的测试,而不是它们是否与第三方服务交互。)
在集成测试中存根或模拟服务类时,不要存根或模拟服务类的公共 API,而是存根或模拟一些较低级别,可能是服务类的内部方法或您使用的库连接到服务。这可以防止调用服务类时出现集成错误。在单元测试中,像对任何类一样存根或模拟服务类的公共 API。
正如 Martin Buberl 所建议的那样,在服务类没有被存根或模拟出来的情况下,对集成测试进行单独的测试运行可能会有所帮助。老实说,这在我参与的多个项目中已经讨论过,但我认为从来没有做过。当第三方服务失败时,我们总是先从生产错误(由监控或客户支持报告)中发现它,然后再从测试中发现它。