什么有资格作为单元测试,什么有资格作为功能/集成测试?



我有点困惑单元测试和集成/功能测试的限制是什么?这些之间有明确的界限吗?

让我从一个场景开始。。。。

如果我有一组执行进程的类。每个流程都包含一些任务。

ProcessA {
var a = do TaskA;
var c = do TaskC;
var b = do TaskB;
}
ProcessB {
var c = do TaskC;
var d = do TaskD;
}
ProcessC {
var a = do TaskA;
var d = do TaskD;
}

如果我们采用上面的设计,那么我可以编写单元测试来测试每个任务,以确保它们做了它们应该做的事情。我对此很酷。

我的问题是,我想为所有进程编写单元测试,或者我认为它们将是单元测试。我希望确保任务的顺序正确,并且业务规则在流程本身中是正确的。

单元测试的定义是单元测试出一小块代码。我试图测试的是一个更大的"ProcessA"、"ProcessB"代码。在这些测试中,我仍然将与数据存储&服务。这仍然被认为是单元测试还是集成/功能测试?

更新

根据所有的评论,我想应该问的问题是,如果所有的外部依赖项都在"ProcessA"、"ProcessB"等类中被嘲笑,那么这些类的单元测试会被视为单元测试还是集成测试?

谢谢你对我的耐心。。。。

当您说I want to make sure that the tasks are in the proper order, and the business rules are correct within the process itself.时,您就不再谈论单元测试,而是开始谈论集成测试。

即使您正在与数据存储和服务脱钩,您也在测试业务规则。如果您的组织与我的组织类似,那么业务规则可以(而且经常)发生变化。正是这种不稳定的特性使它成为一个集成测试。

我使用的基本规则是"单元测试是模块化的,独立于的代码,不依赖于外部数据源。而集成测试是需要使用外部数据源的测试,无论是模拟的还是生产的。">

单元测试的艺术,第二版列出了具有以下定义的集成测试:

我认为集成测试是任何不快速、不一致的测试,并且使用被测单元的一个或多个实际依赖项。例如,如果测试使用真实的系统时间、真实的文件系统或真实的数据库,那么它就进入了集成测试的领域。

和以下单元测试(强调挖掘):

单元测试是一段自动代码,它调用被测试的工作单元,然后检查关于该单元的单个最终结果的一些假设单元测试几乎总是使用单元测试框架编写的。它写起来很容易,运行速度也很快。它值得信赖、可读且可维护。只要生产代码没有改变,它的结果是一致的。

基于上述同一本书。单元测试:

  • Is an automated piece of code that invokes a different method and then checks some assumptions on the logical behaviour of that method or class.
    • 如果您可以将ProcessA/B/C减少为可以相互独立测试的小块,那么这是正确的
  • can be executed repeatedly by anyone on the development team.
    • 如果您的团队中有人需要值或备忘单来确定测试是否通过,则这不是单元测试

现在根据您的编辑而定。集成测试和单元测试可能会重叠,许多其他开发人员可能对如何标记测试有不同的想法。

您的问题的答案是为您和您的开发团队确定最佳实践。如果一致认为这是一个单元测试,那么就这样考虑吧。

单元和集成测试应该帮助过程,而不是阻碍它。请不要让语义妨碍它。

抛开工具等…单元测试只是测试一段特定的代码,通常由程序员执行。

功能和集成通常由QA团队执行:

功能测试是测试代码是否完成了预期任务。

集成测试是关于测试代码以及测量代码如何与系统的其他模块/部分交互。

我认为单元测试是只测试一个类(一个单元)的测试,而集成测试测试多个类/程序集和/或外部数据源的集成。功能测试应明确测试暴露给用户的功能(可能是内部用户、开发团队之外的用户等)

编辑:为复合类实现单元测试的唯一方法是使用依赖项注入。这意味着您应该定义一个接口(可能不止一个),例如:

interface ITask
{
Perform();
}

并将其注入您的Process类:

class ProcessC
{
ITask taskA;
ITask taskD;
ProcessA(ITask taskA, ITask taskD)
{
this.taskA = taskA;
this.taskD = taskD;
}
void Run() //change to your real methods
{
taskA.Perform(); //capture results
taskD.Perform();
}
}

现在可以模拟注入的接口ITask(使用模拟框架),这样就可以将进程的行为与任务的行为隔离开来。

相关内容

最新更新