[unit-testing] 통합과 단위 테스트의 차이점은 무엇입니까?

단위 테스트 및 통합 테스트의 소위 교과서 정의를 알고 있습니다. 궁금한 점은 단위 테스트를 쓸 시간이되었을 때입니다. 가능한 많은 클래스 세트를 다루기 위해 작성합니다.

예를 들어 Word수업 이 있으면 수업에 대한 단위 테스트를 작성합니다 Word. 그 후, 나는 나의 쓰기 시작 Sentence클래스를, 그리고이 상호 작용해야하는 경우 Word클래스, 나는 종종 내 장치들이 모두 테스트하도록 테스트 기록합니다 SentenceWord곳에 그들이 상호 작용 적어도 곳에서 ….

이 테스트는 이제이 두 클래스의 통합을 테스트하기 때문에 통합 테스트가 되었습니까? 아니면 두 클래스에 걸친 단위 테스트입니까?

일반적으로이 불확실한 선 때문에 실제로 통합 테스트를 작성하는 경우는 거의 없습니다. 또는 완성 된 제품을 사용하여 모든 조각이 수동이고 범위를 넘어서 거의 반복되지 않더라도 실제 통합 테스트가 제대로 작동하는지 확인합니다. 각 개별 기능의

통합 테스트를 오해하고 있습니까? 아니면 통합 테스트와 단위 테스트 사이에 거의 차이가 있습니까?



답변

나에게 중요한 차이점은 통합 테스트 에서 기능이 작동하거나 깨 졌는지 여부를 밝혀내는 것입니다. 실제와 가까운 시나리오에서 코드에 스트레스를주기 때문입니다. 하나 이상의 소프트웨어 메소드 또는 기능을 호출하고 예상대로 작동하는지 테스트합니다.

반대로 단일 방법을 테스트 하는 단위 테스트 는 모든 종속성을 명시 적으로 조롱하기 때문에 나머지 소프트웨어가 올바르게 작동한다고 가정합니다 (종종 잘못된 가정).

따라서 일부 기능을 구현하는 방법에 대한 단위 테스트가 녹색 인 경우 기능이 작동하고있는 것은 아닙니다 .

다음과 같은 방법이 있다고 가정 해보십시오.

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

DoSomething고객에게 매우 중요합니다. 기능 만 중요합니다. 그렇기 때문에 일반적으로 Cucumber 사양을 작성 하여 기능이 작동 하는지 여부확인 하고 전달 하려고합니다 .

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

의심 할 여지없이 : 테스트에 통과하면 작업 기능을 제공한다고 주장 할 수 있습니다. 이것이 바로 비즈니스 가치 라고 부릅니다 .

단위 테스트를 작성 DoSomething하려면 나머지 클래스와 메소드가 작동하는 것 (즉, 메소드가 사용하는 모든 종속성이 올바르게 작동 함)을 척하고 (모의를 사용하여) 메소드가 작동하고 있다고 주장해야합니다.

실제로 다음과 같은 작업을 수행합니다.

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

Dependency Injection, Factory Method 또는 Mock Framework를 사용하거나 테스트중인 클래스를 확장 하여이 작업을 수행 할 수 있습니다.

에 버그가 있다고 가정합니다 Log.DoSomething(). 운 좋게도 Gherkin 사양에서이를 찾아 내고 종단 간 테스트에 실패합니다.

기능이 작동하지 않습니다. 기능이 작동 Log하지 않기 때문 [Do your job with someInput]이 아닙니다. 그리고 [Do your job with someInput]그 방법에 대한 책임은 전적으로 귀하에게 있습니다.

또한 Log100 개의 다른 기능, 100 개의 다른 클래스의 100 개의 다른 메소드에서 사용 된다고 가정하십시오 .

그러나 100 가지 기능이 실패합니다. 그러나 다행스럽게도 100 개의 엔드 투 엔드 테스트가 실패하고 문제가 드러났습니다. 그리고 그렇습니다 : 그들은 진실을 말하고 있습니다.

매우 유용한 정보입니다. 깨진 제품이 있다는 것을 알고 있습니다. 또한 매우 혼란스러운 정보입니다. 문제가 어디에 있는지 전혀 알려주지 않습니다. 근본 원인이 아니라 증상을 알려줍니다.

그러나 DoSomething단위 테스트는 Log절대로 깨지지 않는 가짜를 사용하기 때문에 녹색 입니다. 그리고 그렇습니다 : 그것은 분명히 거짓말 입니다. 고장난 기능이 작동 중임을 알리고 있습니다. 어떻게 유용 할 수 있습니까?

( DoSomething()의 단위 테스트에 실패하면 [Do your job with someInput]몇 가지 버그가 있습니다.)

이것이 클래스가 깨진 시스템이라고 가정하십시오.
클래스가 깨진 시스템

하나의 버그로 여러 기능이 중단되고 여러 통합 테스트가 실패합니다.

단일 버그로 인해 여러 기능이 중단되고 여러 통합 테스트가 실패합니다

반면에 동일한 버그는 단 하나의 단위 테스트 만 중단합니다.

동일한 버그로 단 하나의 단위 테스트 만 중단됩니다.

이제 두 시나리오를 비교하십시오.

동일한 버그로 단 하나의 단위 테스트 만 중단됩니다.

  • 깨진 Log부분을 사용하는 모든 기능 은 빨간색
  • 모든 단위 테스트는 녹색이고 단위 테스트 Log는 빨간색입니다

실제로는 기능을 사용하지 않는 모든 모듈에 대한 단위 테스트는 녹색입니다. 모의를 사용하면 종속성이 제거 되었기 때문입니다. 다시 말해, 그들은 이상적인 가상의 세계에서 실행됩니다. 그리고 이것이 버그를 격리하고 찾는 유일한 방법입니다. 단위 테스트는 조롱을 의미합니다. 조롱하지 않으면 단위 테스트가 아닙니다.

차이점

통합 테스트는 작동하지 않는 것을 알려줍니다 . 그러나 문제의 위치추측하는 데 아무런 소용이 없습니다 .

단위 테스트는 버그의 정확한 위치 를 알려주는 유일한 테스트입니다 . 이 정보를 얻으려면 다른 모든 종속 항목이 올바르게 작동하는 모의 환경에서 메소드를 실행해야합니다.

그렇기 때문에 당신의 문장이 “아니면 2 개의 수업에 걸친 단위 테스트 일뿐”이라는 말이 어떻게 바뀌 었는지 생각합니다. 단위 테스트는 2 개의 클래스에 걸쳐서는 ​​안됩니다.

이 답변은 기본적으로 여기에 쓴 내용에 대한 요약입니다. 단위 테스트는 거짓말 입니다.


답변

단위 테스트를 작성할 때 테스트중인 코드의 범위를 현재 모의 종속성으로 작성하는 클래스로 제한합니다. Sentence 클래스를 작성 중이고 Sentence가 Word에 종속 된 경우 모의 Word를 사용합니다. Word를 조롱함으로써 해당 인터페이스에만 집중하고 Word 인터페이스와 상호 작용할 때 내 Sentence 클래스의 다양한 동작을 테스트 할 수 있습니다. 이 방법으로 나는 문장의 행동과 구현만을 테스트하고 동시에 Word의 구현을 테스트하지는 않습니다.

Word의 인터페이스를 기반으로 Word와 상호 작용할 때 문장이 올바르게 작동하는지 확인하기 위해 단위 테스트를 작성한 후에는 상호 작용에 대한 내 가정이 올바른지 확인하기 위해 통합 테스트를 작성합니다. 이를 위해 실제 객체를 제공하고 문장과 단어를 모두 사용하는 기능을 수행하는 테스트를 작성합니다.


답변

내 10 비트 : D

나는 항상 단위 테스트개별 구성 요소 의 테스트 라고 들었 습니다. 이제는 대부분의 구성 요소가 더 작은 부품으로 만들어지기 때문에 많은 수준을 유지하는 경향이 있습니다. 나를 위해, 단위 는 시스템의 기능적인 부분입니다. 따라서 가치있는 무언가를 제공해야합니다 (즉, 문자열 구문 분석 방법이 아니라 HtmlSanitizer ).

통합 테스트 는 다음 단계로, 하나 이상의 구성 요소를 가져 와서 제대로 작동하는지 확인합니다. 그런 다음 구성 요소가 개별적으로 작동 하는 방식대해 걱정할 필요가 있지만 HtmlEditControl에 html을 입력 하면 어떻게 든 마법의 유효 여부를 마법으로 알고 있습니다.

그것의 진짜 움직일 수있는 선 .. 차라리 코드가 완전히 멈추게하는 것에 더 집중하고 싶다 ^ _ ^


답변

단위 테스트는 모의를 사용합니다.

당신이 말하는 것은 실제로 시스템의 전체 통합을 테스트하는 통합 테스트입니다. 그러나 단위 테스트를 수행 할 때는 실제로 각 단위를 개별적으로 테스트해야합니다. 다른 모든 것은 조롱해야합니다. 그래서 당신의 경우 Sentence는 사용하는 경우 클래스, Word클래스를 다음 Word클래스는 조롱한다. 이런 식으로 Sentence수업 기능 만 테스트합니다 .


답변

통합 테스트에 대해 생각하기 시작하면 논리적 계층이 아닌 물리적 계층 간의 교차점에 대해 더 많이 이야기하고 있다고 생각합니다.

예를 들어, 테스트 자체가 컨텐츠 생성과 관련이있는 경우 단위 테스트입니다. 테스트가 디스크에 쓰는 것 자체와 관련이있는 경우 여전히 단위 테스트이지만 파일의 I / O와 컨텐츠를 모두 테스트하면, 그런 다음 자신에게 통합 테스트가 있습니다. 서비스 내에서 함수의 출력을 테스트 할 때는 단위 테스트이지만, 일단 서비스를 호출하고 함수 결과가 동일한 지 확인하면 통합 테스트입니다.

기술적으로 당신은 단 하나의 클래스를 단위 테스트 할 수 없습니다. 수업이 다른 여러 수업으로 구성되어 있다면 어떻습니까? 이것이 자동으로 통합 테스트가됩니까? 나는 그렇게 생각하지 않습니다.


답변

단일 책임 디자인, 흑백을 사용합니다. 하나 이상의 책임, 통합 테스트.

오리 테스트 (외모, cks, 울음, 오리)에 의해 하나 이상의 새로운 물체가있는 단위 테스트입니다.

mvc에 들어가서 테스트하면 컨트롤러에 모델 단위와 뷰 단위가 모두 포함되므로 컨트롤러 테스트는 항상 통합됩니다. 해당 모델의 로직을 테스트하기 위해 단위 테스트를 호출합니다.


답변

테스트의 본질

모듈 X 의 단위 테스트 는 모듈 X에서만 문제를 예상하고 확인하는 테스트입니다.

많은 모듈 의 통합 테스트 는 모듈 간의 협력으로 발생하는 문제를 예상 하여 단위 테스트만으로는 이러한 문제를 찾기가 어렵습니다.

다음과 같은 용어로 테스트의 성격을 생각하십시오.

  • 위험 감소 : 이것이 바로 테스트입니다. 단위 테스트와 통합 테스트조합 만으로 전체 위험을 줄일 수 있습니다. 한편 단위 테스트는 본질적으로 모듈 간의 적절한 상호 작용을 테스트 할 수 없으며 통합 테스트는 사소한 모듈의 기능 만 수행 할 수 있기 때문입니다. 작은 정도로.
  • 테스트 작성 노력 : 통합 테스트는 스텁 / 가짜 / 모의를 작성할 필요가 없기 때문에 노력을 절약 할 수 있습니다. 그러나 스텁 / 가짜 / 모의를 구현 (및 유지 관리) 할 때 단위 테스트도 노력을 아끼지 않고 테스트 설정을 구성하는 것보다 쉽습니다.
  • 테스트 실행 지연 : 무거운 작업 (예 : DB 또는 원격 서버와 같은 외부 시스템에 대한 액세스)과 관련된 통합 테스트는 느립니다. 즉, 단위 테스트를 훨씬 더 자주 실행할 수 있기 때문에 어떤 변화가있을 경우 디버깅 노력이 줄어 듭니다. 테스트 중심 개발 (TDD)을 사용하는 경우 특히 중요합니다.
  • 디버깅 노력 : 통합 테스트가 실패하지만 단위 테스트가 수행되지 않으면 문제 포함될 있는 코드가 너무 많기 때문에 이는 매우 불편할 있습니다. 이전에 몇 줄만 변경 한 경우 큰 문제는 아니지만 통합 테스트가 느리게 실행되면 짧은 간격으로 실행 하지 않았을 수 있습니다.

통합 테스트는 여전히 일부 종속 항목을 스텁 / 가짜 / 모의 할 수 있습니다 . 이것은 단위 테스트와 시스템 테스트 (가장 포괄적 인 통합 테스트, 모든 시스템 테스트) 사이에 충분한 중간 근거를 제공합니다.

두 가지를 모두 사용하는 실용적인 접근 방식

실용적인 접근 방식은 다음과 같습니다. 합리적으로 가능한 한 통합 테스트에 유연하게 의존하고 너무 위험하거나 불편한 단위 테스트를 사용하십시오. 이러한 사고 방식은 단위 테스트와 통합 테스트의 일부 독단적 차별보다 더 유용 할 수 있습니다.