【问题标题】:What are integration tests containing and how to set them up集成测试包含什么以及如何设置它们
【发布时间】:2019-05-13 15:11:20
【问题描述】:

我目前正在学习单元测试和集成测试,据我了解,单元测试用于测试特定类的逻辑,集成测试用于检查多个类和库的协作。

但它是否仅用于测试多个类以及它们是否按预期协同工作,还是在集成测试中访问数据库也有效?如果是这样,如果由于服务器端错误而无法建立连接怎么办,尽管代码本身会按预期工作,但测试是否会失败?我怎么知道在这种测试中使用什么是有效的?

我不明白的第二件事是它们是如何设置的。单元测试在我看来有一种很常见的形式,比如:

public class  classTest {

    @BeforeEach
    public void setUp(){
    }

    @Test
    public void testCase(){
    }
}

但是如何编写集成测试?是否通常以相同的方式完成,只是包括更多的类和外部因素,还是有其他方法用于此?

【问题讨论】:

    标签: java unit-testing testing integration-testing


    【解决方案1】:

    [...] 在集成测试中访问数据库是否也有效? [...] 我怎么知道在这种测试中使用什么是有效的?

    单元测试和集成测试之间的区别不在于是否涉及多个组件:即使在单元测试中,如果这些依赖项不会阻止您到达您的单元,您也可以在不模拟所有依赖项的情况下相处- 测试目标(参见@​​987654321@)。

    单元测试和集成测试的区别在于测试的目标。正如您所写,在单元测试中,您的重点是查找函数、方法或类的逻辑中的错误。显然,在集成测试中,目标是检测在单元测试期间无法找到但可以在集成(子)系统中找到的错误。始终牢记测试目标有助于创建更好的测试并避免集成测试和单元测试之间不必要的冗余。

    集成测试的一种形式是交互测试:这里的目标是在两个或多个组件之间的交互中发现错误。 (可以模拟或不模拟附加组件 - 这再次取决于附加组件是否会阻止您达到测试目标。)AB 两个组件交互中的典型问题可能是,例如 @987654326 @ 是一个库:组件A 是否调用了组件B 的正确函数,组件B 是否处于适当的状态,A 可以通过该函数访问(B 可能尚未初始化), A 是否以正确的顺序传递参数,参数是否包含预期形式的值,B 是否以预期的方式和预期的格式返回结果?

    集成测试的另一种风格是子系统测试,您不关注组件之间的交互,而是查看集成组件形成的子系统的边界。同样,目标是找到以前的测试(即单元测试和交互测试)无法找到的错误。例如,组件是否集成在正确的版本中,是否可以在集成子系统上执行所需的用例等。

    虽然单元测试构成test pyramid 的底部,但集成测试是一个适用于不同集成级别的概念,甚至可以关注与软件集成策略正交的接口(例如,在对驱动程序进行交互测试时)及其对应的硬件设备)。

    我不明白的第二件事是它们是如何设置的。 [...] 集成测试是如何编写的?

    这里有一个极端的变化。对于许多集成测试,您可以只使用用于单元测试的相同测试框架:这些框架中没有特定的单元测试。当然,在测试用例中,您必须确保设置实际上将感兴趣的组件组合到正确的版本中。并且,需要决定是否仅使用或模拟其他依赖项(见上文)。

    另一个典型场景是在完全集成的系统中执行集成测试,使用类似系统测试的设置。这通常是出于方便的目的,只是为了避免为不同的集成测试创建不同的特殊设置的麻烦:完全集成的系统只是将它们全部组合在一起。当然,这也有缺点,因为以这种方式按需要执行所有集成测试通常是不可能的,或者至少是不切实际的。而且,当以这种方式进行集成测试时,集成测试和系统测试之间的界限变得模糊。在这种情况下保持专注意味着您必须对不同的测试目标有一个很好的了解。

    也有混合形式,但这里描述的太多了。仅举一个例子,可以在 LD_PRELOAD (What is the LD_PRELOAD trick?) 的帮助下模拟一些共享库。

    【讨论】:

    • 感谢您的广泛回答!这绝对有助于更好地理解它。但是我仍然在实施以及如何设置它方面遇到困难。如果我有例如客户端和服务器代码并且我想测试注册代码,我会通过将测试用户插入数据库来测试它吗?还是我模拟一个数据库,只检查客户端是否会通过它的类正确地将数据传递给数据库?我想我缺乏想象这是如何工作的
    • 所有这些都是可能的,但哪种方案最好取决于您要查找的错误。例如,模拟数据库是有意义的,除非您还想在代码与数据库的交互方式中找到可能的错误(例如 SQL 命令中的错误)。如果您想讨论这个问题,我已邀请您到聊天室。
    • 好吧,这绝对是有道理的。谢谢,我确实对该主题及其用法有疑问,所以我一定会回来!
    【解决方案2】:

    作为集成测试的一部分访问数据库是有效的,因为集成测试应该显示功能是否正常工作。

    如果某项功能由于与服务器端错误的连接失败而无法工作,您可能希望测试失败以通知您该功能无法工作。集成测试不会告诉您问题出在哪里,只是某个功能无法正常工作。

    请参阅https://stackoverflow.com/a/7876055/10461045,因为这有助于阐明广泛接受的差异。

    【讨论】:

    • 那么是否也可以进行集成测试,只检查与数据库的连接是否正确建立,或者这不是经过测试的东西吗?
    【解决方案3】:

    在集成测试中使用数据库(或与您正在使用的服务的外部连接)不仅有效,而且应该这样做。但是,不要过度依赖集成测试。对您拥有的每个逻辑元素进行单元测试,并为某些流程设置集成测试。

    集成测试可以用相同的方式编写,除了(如您提到的)它们包含更多方法等。事实上,您上面显示的代码 sn-p 是集成测试的常见开始编写。

    您可以在此处阅读有关测试的更多信息:https://softwareengineering.stackexchange.com/questions/301479/are-database-integration-tests-bad

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 2016-08-18
      相关资源
      最近更新 更多