我目前正在学习单元测试和集成测试,据我所知,单元测试用于测试特定类的逻辑,而集成测试则用于检查多个类和库的配合。
但是它是否仅用于测试多个类以及它们是否按预期方式协同工作,还是在集成测试中访问数据库是否还有效?如果是这样,如果由于服务器端错误而无法建立连接怎么办,尽管代码本身可以按预期工作,但测试不会失败吗?我怎么知道在这种测试中可以使用什么?
我不了解的第二件事是它们的设置方式。在我看来,单元测试有一种很常见的形式,例如:
public class classTest {
@BeforeEach
public void setUp(){
}
@Test
public void testCase(){
}
}
但是如何编写集成测试?是否通常以相同的方式进行操作,只是包括更多的类和外部因素,还是有另一种方式使用?
答案 0 :(得分:1)
作为集成测试的一部分,访问数据库是有效的,因为集成测试应该显示功能是否正常工作。
如果某功能由于与服务器端错误的连接失败而无法使用,则您可能希望测试失败以通知您该功能不起作用。集成测试无法通知您故障所在,只是功能无法正常工作。
请参见https://stackoverflow.com/a/7876055/10461045,因为这有助于阐明被广泛接受的差异。
答案 1 :(得分:1)
在集成测试中使用数据库(或与您正在使用的服务的外部连接)不仅有效,而且应该这样做。但是,不要过分依赖集成测试。对您拥有的每个逻辑元素进行单元测试,并为某些流程设置集成测试。
集成测试可以用相同的方式编写,除了(如上所述)它们包含更多的方法等。实际上,上面显示的代码片段是集成测试的常见入门。
您可以在这里阅读有关测试的更多信息:https://softwareengineering.stackexchange.com/questions/301479/are-database-integration-tests-bad
答案 2 :(得分:1)
[...]在集成测试中访问数据库是否也有效? [...]我怎么知道在这种测试中可以使用什么?
单元测试和集成测试之间的区别不在于是否涉及多个组件:即使在单元测试中,如果这些依赖关系不能阻止您接触到单元,您也可以在不嘲笑所有依赖关系的情况下相处融洽测试目标(请参见https://stackoverflow.com/a/55583329/5747415)。
区分单元测试和集成测试的是测试的<目标>目标。如您所写,在单元测试中,您的重点是发现函数,方法或类的逻辑中的错误。显然,在集成测试中,目标是检测在单元测试期间找不到但可以在集成(子)系统中发现的错误。始终牢记测试目标有助于创建更好的测试,并避免集成测试和单元测试之间不必要的冗余。
集成测试的一种形式是交互测试:这里的目标是在两个或多个组件之间的交互中发现错误。 (是否可以模拟其他组件,这又取决于其他组件是否使您无法达到测试目标。)两个组件A
和B
的交互作用中的典型问题可能是:如果B
是一个库的示例:组件A
是否调用了组件B
的正确功能,组件B
是否处于A
可以访问的适当状态通过该函数(B
可能尚未初始化),A
是否以正确的顺序传递参数,参数是否包含期望形式的值,B
是否返回了结果以预期的方式和预期的格式显示?
集成测试的另一种形式是子系统测试,在该测试中,您不必关注组件之间的交互,而是查看由集成组件形成的子系统的边界。而且,目标是找到以前的测试(即单元测试和交互测试)无法找到的错误。例如,将组件集成到正确的版本中,是否可以在集成的子系统上执行所需的用例等。
虽然单元测试构成了test pyramid的底部,但是集成测试是一个适用于不同集成级别的概念,甚至可以专注于与软件集成策略正交的接口(例如,当对驱动程序及其相应的硬件设备)。
我不了解的第二件事是它们的设置方式。 [...]集成测试如何编写?
这里有一个极端的变化。对于许多集成测试,您可以只使用与单元测试相同的测试框架:这些框架中没有特定的单元测试。当然,您必须在测试用例中确保安装程序实际上将感兴趣的组件组合到了正确的版本中。而且,是否需要使用其他附加依赖项还是要对其进行嘲弄(请参见上文)。
另一种典型方案是使用类似系统测试的设置在完全集成的系统中执行集成测试。通常这样做是出于方便,只是为了避免为不同的集成测试创建不同的特殊设置的麻烦:完全集成的系统只是将它们全部组合在一起。当然,这也有缺点,因为以这种方式执行所有集成测试通常是不可能的,或者至少是不切实际的。而且,以这种方式进行集成测试时,集成测试和系统测试之间的界限变得模糊。在这种情况下保持专注意味着您确实必须对不同的测试目标有很好的了解。
也有混合形式,但是在这里无法描述它们。仅举一个例子,就有可能借助LD_PRELOAD
(What is the LD_PRELOAD trick?)模拟某些共享库。