【问题标题】:Deciding whether a test is a Unit or Integration test确定测试是单元测试还是集成测试
【发布时间】:2014-05-23 01:48:51
【问题描述】:

所以我正在尝试决定如何为我的 python 项目规划和组织一个测试套件,但是我对单元测试何时不再是单元测试有疑问,我很想从社区获得一些反馈.

如果我理解正确:

  • 单元测试测试你的代码的最小部分,如果一个函数/方法只做一个并且只有一个简单的事情,即使它有几个用例.
  • 集成测试测试在相同上下文、环境等下执行的两个或多个代码单元(但尝试将其保持在每个集成测试的最小单元)运行良好一起,而不仅仅是他们自己。

我的疑惑是:假设我有一个简单的函数,它执行一个HTTP请求并返回这个请求的内容,不管是HTML,JSON等,没关系,事实是这个函数非常非常简单但从外部来源请求信息,例如:

import requests

def my_function(arg):
    # do something very simple with `arg`, like removing spaces or the simplest thing you can imagine
    return requests.get('http://www.google.com/' + arg).content

现在这是一个非常愚蠢的例子,但我的疑问是:

鉴于此函数是从外部来源请求信息,当您为它编写测试时,您是否仍可以将此类测试视为单元测试

更新my_function() 的测试将排除对外部源的调用,因此它不依赖于 network/db/filesystem/etc,因此它是隔离的。但是,正在测试的函数在运行时依赖于外部资源,例如在生产环境中。

提前致谢!! :)

P.S.:当然,也许我没有理解 100% 的单元和集成测试的目的,所以,如果我弄错了,请指出在哪里,我会很感激的。

【问题讨论】:

    标签: python unit-testing testing integration-testing


    【解决方案1】:

    根据您的更新:

    my_function() 的测试将排除对外部源的调用 所以它不依赖于 network/db/filesystem/etc 所以它是 孤立。但是,正在测试的功能取决于 在运行时(例如在生产中)使用外部资源。

    只要在您的测试过程中排除了外部依赖项,那么是的,您可以将其称为单元测试。它是基于被测单元在您的测试套件中的行为方式而不是该单元在生产中的行为方式的单元测试。

    根据您的原始问题:

    鉴于此函数正在从外部请求信息 来源,当你为它写一个测试时,你还能考虑这样的测试吗 单元测试?

    不,任何涉及或依赖于被测单元外部事物的代码测试都是集成测试。这包括任何 Web、文件系统和数据库请求的存在。

    如果您的代码不是 100% 与其依赖项隔离,并且在没有其他组件的情况下不能 100% 重现,那么它就是一个集成测试。

    要对您的示例代码进行正确的单元测试,您需要模拟对 google.com 的调用。

    使用调用 google.com 的代码,如果 google 出现故障或您失去与 Internet 的连接,您的测试将失败(即测试不是 100% 隔离的)。如果 google 的行为发生变化,您的测试也会失败(即测试不是 100% 可重现的)。

    【讨论】:

    • 嘿@mezoid 谢谢你的回答。对不起,我解释得不够好。该函数依赖于外部源,但测试肯定会消除该依赖。我会更新我的问题:)
    • @Gerard 没问题。我已根据您更新的问题更新了我的答案。
    【解决方案2】:

    我不认为这是一个集成测试,因为它没有使用您应用程序的不同部分。该函数只做一件事,可以调用unit对其进行测试。

    另一方面,此特定功能具有外部依赖性,您不希望在测试中依赖于网络。这就是mocking 真正有帮助的地方。

    换句话说,隔离函数并对其进行unit 测试。

    另外,进行集成测试,使用更高级的方法并测试调用my_function() 的应用程序部分。

    【讨论】:

    • 我原以为任何对具有未模拟的外部依赖项的代码的测试都是集成测试..
    • @mezoid 我明白你的意思,但这里的“线”真的很粗。我在这里说的是您需要隔离my_function() 以确保这些是单元测试。而且,为my_function() 调用者进行的测试将被称为集成。谢谢!
    • 是的。我明白你在说什么。
    • 大家好,感谢您提供的信息,很抱歉我缺少信息。当然,我会使用模拟库和类似库来剔除外部资源。我会更新我的问题:) 抱歉
    • @Gerard 很好,但我提供的答案仍然相关。看看吧。
    【解决方案3】:

    您的代码是否被单独测试并不是您的测试是否是单元测试的区别标准。例如,您将(除非在极少数情况下)不存根标准库函数,如 sin(x)。但是,如果您不存根 sin(x),这不会使您的测试成为集成测试。

    什么时候测试是集成测试?如果您的测试目标是在集成级别上查找错误,那么测试就是集成测试。这意味着,通过集成测试,您想了解两个(或更多)组件之间的交互是否基于双方(所有)方面的相同假设。

    然而,模拟是一种正交技术,可以与几乎所有类型的测试结合使用。 (然而,在集成测试中,您不能模拟您想要测试的交互的合作伙伴 - 但您可以模拟其他组件。

    由于嘲弄通常会引起一些努力,因此它必须带来好处,例如:

    • 显着加快您的测试速度
    • 虽然某些软件部分还没有准备好或有问题,但正在测试
    • 测试难以在集成软件中设置的异常情况
    • 摆脱时间或随机性等不确定性行为
    • ...

    但是,如果模拟不能解决实际问题,您最好直接使用依赖组件。

    【讨论】:

      猜你喜欢
      • 2021-12-19
      • 2014-09-01
      • 1970-01-01
      • 2013-07-13
      • 2011-05-15
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 2019-02-02
      相关资源
      最近更新 更多