통합 테스트가 이미있는 경우 단위 테스트가 필요합니까?


47

이미 내 프로그램에 대한 통합 테스트를 받았고 모두 통과 한 경우 제대로 작동한다고 생각합니다. 그렇다면 단위 테스트를 작성 / 추가해야하는 이유는 무엇입니까? 어쨌든 통합 테스트를 작성해야하므로 통합 테스트에서 다루지 않는 부분에 대해서만 단위 테스트를 작성하려고합니다.

통합 테스트에 대한 단위 테스트의 이점은

  • 작고 빠른 실행 (그러나 무언가를 테스트하기 위해 새 유닛을 추가하는 것은 이미 통합 테스트를 통해 테스트되었으므로 전체 테스트 슈트의 실행이 점점 길어짐
  • 한 가지만 테스트하기 때문에 버그를 쉽게 찾을 수 있습니다 (그러나 통합 테스트가 실패했을 때 각 개별 부분을 확인하기 위해 쓰기 단위 테스트를 시작할 수 있습니다)
  • 통합 테스트에서 발견되지 않은 버그를 찾으십시오. 예를 들어 마스킹 / 오프셋 버그. (그러나 내 통합 테스트가 모두 통과되면 숨겨진 프로그램이 존재하더라도 프로그램이 작동한다는 의미입니다. 따라서 향후 통합 테스트를 중단하거나 성능 문제를 일으키지 않는 한 이러한 버그 찾기 / 수정은 우선 순위가 높지 않습니다)

그리고 우리는 항상 적은 코드를 작성하려고하지만, 단위 테스트를 작성하려면 더 많은 코드가 필요합니다 (주로 모의 객체 설정). 단위 테스트와 통합 테스트의 차이점은 단위 테스트에서 모의 ​​객체를 사용하고 통합 테스트에서 실제 객체를 사용한다는 것입니다. 중복이 많고 테스트에서도 코드 동작을 변경하기 위해 오버 헤드가 추가되기 때문에 중복 코드가 마음에 들지 않습니다 (리 팩터 도구가 항상 작동하는 것은 아닙니다).


호기심으로 인해 통합 테스트의 커버리지는 어느 정도입니까? 또한 복잡한 로직이있는 경우 통합 테스트에서 로직 테스트의 일부 또는 전부와 비즈니스 또는 랜덤에 중요한 부분을 포괄합니까?
civan

이 질문은 모호해 보입니다. 인터랙 터 ( github.com/collectiveidea/interactor ) 를 호출하는 Rails 컨트롤러 메소드가 있다고 가정 해 봅시다 . 컨트롤러 메소드에 대한 통합 테스트를 작성하기로 결정했습니다 (컨트롤러가 없으면 API 엔드 포인트가 작동한다는 것을 신뢰할 수 없기 때문에). 여기에는 최소한 두 가지 질문이 있습니다. (1) 컨트롤러 방법에 대한 단위 테스트도 작성해야합니다 (즉, 통합 테스트와 동일한 동작을 테스트하는 단위 테스트를 작성해야 함) 및 (2) 단위 테스트도 작성해야합니다 내 인터랙 터를 위해? 특정 비즈니스 상황에서이 두 가지 질문에 다르게 대답합니다.
다니엘

답변:


33

단위 테스트에 대한 좋은 주장을 제시했습니다. 그래서 당신은 자신에게 물어 " 내가 부정적인 것들의 비용보다 중요한 긍정적 인 인수 값을 볼 수 있습니까? " 나는 확실히 수행하십시오 :

  • 작고 빠른 것은 단위 테스트의 좋은 측면이지만, 가장 중요한 것은 아닙니다.
  • 더 찾기 쉬운 버그는 매우 가치가 있습니다. 전문 소프트웨어 개발에 대한 많은 연구 결과에 따르면 버그의 비용은 시간이 지남에 따라 가파르게 상승하고 소프트웨어 제공 파이프 라인을 따라 내려갑니다.
  • 마스크 벌레 찾기는 가치가 있습니다. 특정 구성 요소의 모든 동작이 확인되었음을 알고 있으면 이전에 사용하지 않은 방식으로 자신있게 사용할 수 있습니다. 유일한 검증이 통합 테스트를 통한 것이라면 현재 사용이 올바르게 작동 한다는 것만 알 수 있습니다.
  • 실제 상황에서 조롱은 비용이 많이 들고, 조롱을 유지하는 것은 두 배입니다. 실제로 "흥미로운"객체 또는 인터페이스를 조롱 할 때, 모의 객체가 실제 객체를 올바르게 모델링하는지 확인하는 테스트가 필요할 수도 있습니다!

저의 책에서 전문가들은 단점보다 더 중요합니다.


2
실제 사례에서 조롱하지 않습니까? 모의가받는 메시지에 대한 기대치를 설정하고 반환 할 메시지를 지정합니다.
Dogweather

10
@Dogweather Mocks는 처음 만들 때 잘 작동합니다. 시간이 지남에 따라 실제 객체가 변경되면 모의 객체도 함께 변경되어야합니다. 10 년 동안 6,000 건의 단위 테스트를 거쳤지만 "성공적인"테스트가 실제로 성공했다는 것은 매우 어렵습니다.
로스 패터슨

1
게다가 "10 년과 6,000 개의 단위 테스트"는 과장된 것이 아니라 개인적인 경험의 숫자입니다.
로스 패터슨

3
2004 년 또는 2005 년에 자동화 된 개발자 테스트 (단위 및 통합, 대부분 후자)를 작성하기 시작했으며 Java 용 고급 조롱 라이브러리를 개발했습니다. 나는 여러 통합 테스트합니다 (DB, 또는 네트워크 변경의 변화 같은) 같은 이유로 파괴, 그리고 가끔 재사용 가능한 구성 요소에 대한 "낮은 수준"통합 테스트를 작성하지만, 여전히, 내가 많이 선호 보았다 여러 번 이 통합 테스트. 대부분 조롱을 통한 고립 된 단위 테스트는 그만한 가치가 없습니다. 통합 테스트를 돕기 위해 조롱 만 적용합니다.
Rogério

마지막 글 머리 기호는 주장하는 내용과 모순되는 것 같습니다. 이 글에서 불필요한 모의 작성을 반대하는 사례를 작성했습니다. 이는 이미 통합 테스트에 포함 된 부품에 대한 단위 테스트 작성에 대한 논거입니다. 그러나 당신의 주장은 이미 통합 테스트에 의해 다루어 진 부분에 대한 단위 테스트를 작성하는 것을 선호합니다. 여기 @RossPatterson의 의도를 명확히 해 주시겠습니까?
다니엘

8

기존 통합 테스트 사례를 다시 구현할 때 단위 테스트로 많은 가치를 얻지 못합니다.

일반적으로 테스트 할 기능이 밀접하게 결합되어 격리 된 테스트 단위 (= 단위 테스트)가 어렵거나 비싸거나 불가능할 수 있기 때문에 통합 테스트는 비 tdd 레거시 응용 프로그램에 대해 작성하기가 훨씬 쉽습니다.

> Then what are the reasons to write/add unit tests?

내 생각에 테스트 중심 개발은 실제 코드 전에 단위 테스트를 작성하는 경우 가장 효과적 입니다. 이런 식으로 테스트를 수행하는 코드는 쉽게 테스트 할 수있는 최소한의 외부 참조로 명확하게 분리됩니다.

만약 유닛 테스트없이 코드가 이미 존재한다면, 쉬운 테스트를 위해 코드가 작성되지 않았기 때문에 나중에 유닛 테스트를 작성하는 것은 많은 추가 작업입니다.

TDD를 수행하면 자동으로 코드를 쉽게 테스트 할 수 있습니다.


2
내가없는 레거시 응용 프로그램을 가지고 있고 특정 부분 unit-tests에 포함시키고 싶다면 unit-tests먼저 integration tests레거시 코드를 작성하는 것이 더 낫다고 생각하십니까 ? 일단 작성된 후에는 타이트한 커플 링을 분리하고 테스트 할 수있는 인터페이스로 함수를 작성할 수 있습니까? 당신이했기 때문에 integration-test이미 작성, 당신은 다음 코드의 새 버전이 여전히 원하는 작품으로 것으로, 리팩토링의 각 단계에서 확인할 수 있습니까?
alpha_989

2
@ alpha_989, 이것은 매우 많은 IMHO이며 다른 아이디어를들을 수 있지만 레거시 코드의 단위 테스트보다 통합 테스트를 선호합니다. 두 경우 모두, 모든 종류의 테스트를 추가하기 전에 메소드가 올바르게 작동하는지 확인해야하지만 통합 테스트는 메소드의 전반적인 기대가 개별 코드 요소와 반대로 작동하는지 확인합니다.
Britt Wescott

5

통합 테스트는 여러 구성 요소가 예상대로 함께 작동하는지 확인해야합니다. 개별 구성 요소의 논리가 정확한지 여부는 단위 테스트로 확인해야합니다.
대부분의 메소드에는 몇 가지 가능한 실행 경로가 있습니다. if-then-else, 예상치 못한 또는 잘못된 값을 가진 입력 변수 등을 생각하십시오. 일반적으로 개발자는 행복한 경로, 잘못되지 않는 정상 경로에 대해서만 생각하는 경향이 있습니다. 그러나 다른 경로와 관련하여 두 가지 옵션이 있습니다. 최종 사용자가 UI에서 수행하는 작업을 통해 해당 경로를 탐색하고 응용 프로그램이 충돌하지 않기를 희망하거나 주장하는 단위 테스트를 작성할 수 있습니다 다른 경로의 행동과 필요한 경우 조치를 취하십시오.


4

귀하의 질문에서 지적한 이유 중 일부는 실제로 중요하며 자체적으로 단위 테스트를 선호하지만 YMMV를 선호 할 수 있습니다. 예를 들어, 통합 테스트 스위트를 얼마나 자주 실행합니까? 통합 테스트에 대한 나의 경험은 조만간 느리게 변경 될 때마다 변경을 할 때마다 실행되지 않으며 버그 삽입과 감지 사이의 시간이 증가한다는 것입니다.

또한, 당신이 저지르는 큰 실수는

Find bug that may not be caught in integration test. e.g. masking/offsetting bugs.

중요하지 않다. 사용자가 버그를 찾을 것으로 기대하십니까? 통합 테스트에서 얻은 커버리지를 신뢰하는 것은 위험하다고 생각합니다. 커버리지를 쉽게 얻을 수는 있지만 실제로는 거의 테스트하지 않습니다.

통합 테스트에 대한 표준 참조는 JBrains의 게시물이라고 생각합니다.

http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1

아직 읽지 않은 경우를 대비하여

마지막으로, IMO는 설계에 대한 단위 테스트에서 얻을 수있는 피드백이 매우 중요합니다. 직감으로 디자인을 판단하고 통합 테스트에 의존하는 것도 실수 일 수 있습니다.


나는 그 기사를 실제로 얻지 못한다. 따라서 많은 코드 경로가 있으며 통합 테스트로 모든 것을 다룰 수는 없습니다. 단위가 무의미하지 않은 경우를 제외하고는 단위 테스트에도 동일하게 적용됩니다.
Casey

이는 많은 단위 테스트와 피할 수없는 통합 테스트를 작성해야하는 코드 커버리지를 수정하는 것에 대한 논쟁과 비슷합니다.
Casey

1

코드를 수정하거나 리팩토링해야한다면 단위 테스트가 필수적입니다. 단위 테스트는 코드 작성시 버그를 보여줄뿐만 아니라 더 많은 코드가 작성 될 때 새 버그가 나타나는시기를 보여주기 위해 존재합니다.

그렇습니다. 통합 및 단위 테스트를 먼저 작성하는 것이 훨씬 좋지만 나중에 작성하더라도이를 테스트하는 데 많은 가치가 있습니다.


3
나는 당신이 사건을했다고 생각하지 않습니다. 통합 테스트는 또한 코드의 버그를 드러 낼 것이며, 실제로 단위 테스트가하지 않는 버그를 잡을 수 있습니다.
Casey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.