Unit testing 集成测试-可以正确完成吗?

Unit testing 集成测试-可以正确完成吗?,unit-testing,Unit Testing,在过去的两年里,我在一些项目中使用了TDD作为开发风格,但我总是停留在同一个问题上:如何测试我程序各个部分的集成 我目前正在做的是为每个类编写一个测试用例(这是我的经验法则:“单元”是一个类,每个类都有一个或多个测试用例)。我试图通过使用mock和stub来解决依赖关系,这非常有效,因为每个类都可以独立测试。在一些编码之后,所有重要的类都会被测试。然后,我使用IoC容器将它们“连接”在一起。我被困在这里:如何测试布线是否成功,以及对象是否以我想要的方式交互 例如:考虑一个web应用程序。有一个控

在过去的两年里,我在一些项目中使用了TDD作为开发风格,但我总是停留在同一个问题上:如何测试我程序各个部分的集成

我目前正在做的是为每个类编写一个测试用例(这是我的经验法则:“单元”是一个类,每个类都有一个或多个测试用例)。我试图通过使用mock和stub来解决依赖关系,这非常有效,因为每个类都可以独立测试。在一些编码之后,所有重要的类都会被测试。然后,我使用IoC容器将它们“连接”在一起。我被困在这里:如何测试布线是否成功,以及对象是否以我想要的方式交互

例如:考虑一个web应用程序。有一个控制器类,它接受一个ID数组,使用存储库根据这些ID获取记录,然后迭代记录并将它们作为字符串写入输出文件

简单来说,有三个类:
Controller
Repository
OutfileWriter
。每一个都是单独测试的


为了测试“真正的”应用程序,我将做什么:使用数据库中的一些ID发出http请求(手动或自动),然后查看文件系统中是否写入了该文件。当然,这个过程可以自动化,但仍然是:这不会重复测试逻辑吗?这就是所谓的“集成测试”吗?在我最近读到的一本关于单元测试的书中,我觉得集成测试更像是一种反模式?

您所描述的实际上是集成测试(或多或少)。不,它不是反模式,而是软件开发生命周期的必要部分


任何合理复杂的程序都不只是其各部分的总和。因此,无论单元测试做得多么好,您仍然不知道整个系统是否能按预期工作

原因有几个方面:

  • 单元测试是在一个孤立的环境中执行的,因此它们不能说明程序的各个部分在现实生活中是如何协同工作的
  • “单元测试帽”很容易限制一个人的观点,因此有一整类的因素开发人员根本不认为是需要测试的东西*
  • <> LI>即使是这样,也有一些在单元测试中无法合理测试的事情。例如,您如何测试应用程序服务器在高负载下是否生存,或者如果DB连接在请求的中间下降了?
*我刚刚从Luke Hohmann的《超越软件架构》(Beyond Software Architecture)一书中读到一个例子:在一个应用程序中,通过创建和维护实际机器中硬件组件ID的“快照”,应用了强大的反盗版防御,开发人员通过单元测试很好地覆盖了代码。然后,QA通过在没有网卡的机器上试用,在10分钟内使应用程序崩溃。事实证明,由于开发人员在MAC上工作,他们理所当然地认为机器有一个网卡,其MAC地址可以合并到快照中

为了测试 “真实”应用程序:使http 请求(手动或自动) 使用数据库中的一些ID和 然后查看文件系统,如果 文件已写入。当然是这个 该过程可以自动化,但仍然: 这不是重复了测试逻辑吗

也许您是重复的代码,但您并没有重复工作。单元测试和集成测试有两个不同的目的,通常SDLC需要这两个目的。如果可能,将用于单元/集成测试的代码分解到公共库中。我还将尝试为您的单元/集成测试b/c创建单独的项目 单元测试应该单独运行(快速且无依赖性)。您的集成测试将更加脆弱且经常中断,因此您可能会有不同的策略来运行/维护这些测试

这就是所谓的“整合”吗 测试“


是的,的确如此。

IMO,我没有相关文献支持我,但我们各种测试形式之间的关键区别在于范围

  • 单元测试是测试功能的独立部分[通常是一个方法或有状态类]
  • 集成测试是测试两个或多个相关部分的交互[通常是服务和使用者,甚至是数据库连接,或与其他远程服务的连接]
  • 系统集成测试是对系统进行端到端的测试[集成测试的一个特例]
如果您熟悉单元测试,那么没有完美或“魔弹”测试也就不足为奇了。集成和系统集成测试非常类似于单元测试,因为每个测试集都是一组测试集,用于验证某种行为

对于每个测试,设置范围,然后指定输入和预期输出。然后执行测试,并将实际值评估为预期值

在实践中,您可能对系统的工作方式有很好的了解,因此编写典型的正向和负向路径测试将是自然而然的事。然而,对于任何足够复杂的应用程序,期望所有可能场景的总覆盖率是不合理的

不幸的是,这意味着在质量保证[QA]、预生产[PP]和生产[Prod]周期中将出现意外情况。此时,您在dev中复制这些场景的尝试应该作为自动化测试进入您的集成和系统集成套件

希望这有帮助,:)



ps:pet peeve#1:管理者或开发人员称集成和系统集成测试为“单元测试”,仅仅是因为nUnit或MsTest用于自动化它

在集成测试中,就像在单元测试中一样,您需要验证发生了什么
Class OutFilevalidator {
    function isCorrect(fName, dataList) {
       // open file read data and
       // validation logic
}