集成测试和单元测试有什么区别? [英] What is the difference between integration and unit tests?

查看:133
本文介绍了集成测试和单元测试有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道单元测试和集成测试的所谓教科书定义.我很好奇的是什么时候编写单元测试了……我将编写它们以覆盖尽可能多的类集.

I know the so-called textbook definition of unit tests and integration tests. What I am curious about is when it is time to write unit tests... I will write them to cover as many sets of classes as possible.

例如,如果我有一个Word类,我将为Word类编写一些单元测试.然后,我开始编写我的Sentence类,当它需要与Word类进行交互时,我通常会编写单元测试,以便它们至少在SentenceWord中对它们进行测试.他们互动的地方.

For example, if I have a Word class, I will write some unit tests for the Word class. Then, I begin writing my Sentence class, and when it needs to interact with the Word class, I will often write my unit tests such that they test both Sentence and Word... at least in the places where they interact.

由于这些测试现在可以测试这两个类的集成,所以这些测试从本质上成为集成测试了吗?还是只是跨越两个类的单元测试?

通常,由于行数不确定,我很少实际编写集成测试...或者我使用成品来查看所有部件在实际的集成测试中是否正常工作,即使它们是手动的并且很少重复超出每个单独功能的范围?

In general, because of this uncertain line, I will rarely actually write integration tests... or is my using the finished product to see if all the pieces work properly the actual integration tests, even though they are manual and rarely repeated beyond the scope of each individual feature?

我误解了集成测试,还是集成测试和单元测试之间的区别真的很小?

Am I misunderstanding integration tests, or is there really just very little difference between integration and unit tests?

推荐答案

对我来说,主要区别在于集成测试可以揭示某个功能是否正常运行或已损坏,因为它们强调了代码在接近现实的情况下.他们调用一种或多种软件方法或功能,并测试它们是否按预期运行.

The key difference, to me, is that integration tests reveal if a feature is working or is broken, since they stress the code in a scenario close to reality. They invoke one or more software methods or features and test if they act as expected.

相反,单元测试测试单个方法依赖于(通常是错误的)假设,即软件的其余部分正确运行,因为它明确地模拟了每个依赖关系.

On the opposite, a Unit test testing a single method relies on the (often wrong) assumption that the rest of the software is correctly working, because it explicitly mocks every dependency.

因此,当对实现某些功能的方法的单元测试为绿色时,它表示该功能正在工作.

Hence, when a unit test for a method implementing some feature is green, it does not mean the feature is working.

假设您在某处有这样的方法:

Say you have a method somewhere like this:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  Log.TrackTheFactYouDidYourJob();
  return someResults;
}

DoSomething对您的客户非常重要:这是一项功能,唯一重要的事情.这就是为什么您通常编写一个声明它的Cucumber规范的原因:您希望验证通信该功能是否正常工作.

DoSomething is very important to your customer: it's a feature, the only thing that matters. That's why you usually write a Cucumber specification asserting it: you wish to verify and communicate the feature is working or not.

Feature: To be able to do something
  In order to do something
  As someone
  I want the system to do this thing

Scenario: A sample one
  Given this situation
  When I do something
  Then what I get is what I was expecting for

毫无疑问:如果测试通过,则可以断言您正在提供有效的功能.这就是您所说的业务价值.

No doubt: if the test passes, you can assert you are delivering a working feature. This is what you can call Business Value.

如果要为DoSomething编写单元测试,则应假装(使用一些模拟)其余的类和方法都在工作(即:该方法所使用的所有依赖项都在正确地工作),并且断言您的方法有效.

If you want to write a unit test for DoSomething you should pretend (using some mocks) that the rest of the classes and methods are working (that is: that, all dependencies the method is using are correctly working) and assert your method is working.

在实践中,您可以执行以下操作:

In practice, you do something like:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  FakeAlwaysWorkingLog.TrackTheFactYouDidYourJob(); // Using a mock Log
  return someResults;
}

您可以使用依赖注入,某种工厂方法或任何Mock框架或仅扩展受测类来实现此目的.

You can do this with Dependency Injection, or some Factory Method or any Mock Framework or just extending the class under test.

假设Log.DoSomething()中存在错误. 幸运的是,Gherkin规范会找到它,并且您的端到端测试将失败.

Suppose there's a bug in Log.DoSomething(). Fortunately, the Gherkin spec will find it and your end-to-end tests will fail.

该功能不起作用,是因为Log损坏了,不是因为[Do your job with someInput]没有完成其工作.而且,[Do your job with someInput]是该方法的唯一责任.

The feature won't work, because Log is broken, not because [Do your job with someInput] is not doing its job. And, by the way, [Do your job with someInput] is the sole responsibility for that method.

另外,假设Log在100个其他类的100个其他方法中的100个其他功能中使用.

Also, suppose Log is used in 100 other features, in 100 other methods of 100 other classes.

是的,有100个功能将失败.但是,幸运的是,100个端到端测试也失败了,并揭示了问题所在.而且,是的:他们说的是事实.

Yep, 100 features will fail. But, fortunately, 100 end-to-end tests are failing as well and revealing the problem. And, yes: they are telling the truth.

这是非常有用的信息:我知道我的产品坏了.这也非常令人困惑:它无法告诉我问题出在哪里.它传达了我的症状,而不是根本原因.

It's very useful information: I know I have a broken product. It's also very confusing information: it tells me nothing about where the problem is. It communicates me the symptom, not the root cause.

但是,DoSomething的单元测试是绿色的,因为它使用的是伪造的Log,其构造是永不中断的.而且,是的:明显在撒谎.它正在传达损坏的功能正在起作用.怎么有用?

Yet, DoSomething's unit test is green, because it's using a fake Log, built to never break. And, yes: it's clearly lying. It's communicating a broken feature is working. How can it be useful?

(如果DoSomething()的单元测试失败,请确保:[Do your job with someInput]有一些错误.)

(If DoSomething()'s unit test fails, be sure: [Do your job with someInput] has some bugs.)

假设这是一个类损坏的系统:

Suppose this is a system with a broken class:

一个错误将破坏多个功能,并且多个集成测试将失败.

A single bug will break several features, and several integration tests will fail.

另一方面,相同的错误只会破坏一个单元测试.

On the other hand, the same bug will break just one unit test.

现在,比较这两种情况.

Now, compare the two scenarios.

同一错误只会破坏一个单元测试.

The same bug will break just one unit test.

  • 使用破损的Log的所有功能都是红色的
  • 您所有的单元测试都是绿色的,只有Log的单元测试是红色的
  • All your features using the broken Log are red
  • All your unit tests are green, only the unit test for Log is red

实际上,使用断开功能的所有模块的单元测试都是绿色的,因为通过使用模拟,它们删除了相关性.换句话说,它们运行在理想的,完全虚构的世界中.这是隔离错误并查找错误的唯一方法.单元测试意味着模拟.如果您不是在嘲笑,那么您就不是单元测试.

Actually, unit tests for all modules using a broken feature are green because, by using mocks, they removed dependencies. In other words, they run in an ideal, completely fictional world. And this is the only way to isolate bugs and seek them. Unit testing means mocking. If you aren't mocking, you aren't unit testing.

集成测试表明什么无效.但是在猜测问题可能出在哪里时,它们没有用.

Integration tests tell what's not working. But they are of no use in guessing where the problem could be.

单元测试是唯一告诉您错误的确切位置的测试.要绘制此信息,他们必须在模拟的环境中运行该方法,在该环境中所有其他依赖项都应正常工作.

Unit tests are the sole tests that tell you where exactly the bug is. To draw this information, they must run the method in a mocked environment, where all other dependencies are supposed to correctly work.

这就是为什么我认为您的句子或者仅仅是跨越2个类的单元测试"的原因.单元测试不得跨越2个类.

That's why I think that your sentence "Or is it just a unit test that spans 2 classes" is somehow displaced. A unit test should never span 2 classes.

此回复基本上是我在这里写的内容的摘要:

This reply is basically a summary of what I wrote here: Unit tests lie, that's why I love them.

这篇关于集成测试和单元测试有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆