단위 테스트 대신 수락 및 통합 테스트를 사용하는 것으로 충분합니까?


62

이 질문에 대한 짧은 소개. 나는 지금 TDD와 요즘 BDD를 1 년 이상 사용했다. 테스트를보다 효율적으로 작성하기 위해 조롱과 같은 기술을 사용합니다. 최근에 나는 작은 돈 관리 프로그램을 작성하기위한 개인 프로젝트를 시작했다. 레거시 코드가 없었기 때문에 TDD로 시작하기에 완벽한 프로젝트였습니다. 불행히도 나는 TDD의 기쁨을 그다지 경험하지 못했습니다. 그것은 심지어 프로젝트를 포기했을 정도로 재미를 망쳐 버렸습니다.

문제는 무엇 이었습니까? 글쎄, 나는 테스트 / 요구 사항이 프로그램의 디자인을 발전 시키도록 TDD와 같은 접근법을 사용했다. 문제는 쓰기 / 리 팩터 테스트와 관련하여 개발 시간의 절반 이상이 문제였습니다. 결국 많은 테스트에 리팩토링하고 작성해야하므로 더 이상 기능을 구현하고 싶지 않았습니다.

직장에서 많은 레거시 코드가 있습니다. 여기에서는 점점 더 많은 통합 및 승인 테스트와 더 적은 단위 테스트를 작성합니다. 버그는 대부분 승인 및 통합 테스트에 의해 감지되므로 이는 나쁜 접근 방법이 아닙니다.

내 생각은 결국 단위 테스트보다 더 많은 통합 및 승인 테스트를 작성할 수 있다는 것입니다. 내가 버그를 감지했다고 말했듯이 단위 테스트는 통합 / 수락 테스트보다 낫지 않습니다. 단위 테스트도 설계에 좋습니다. 나는 그것들을 많이 쓰는 데 사용 되었기 때문에 내 수업은 항상 테스트 할 수 있도록 설계되었습니다. 또한 테스트 / 요구 사항이 설계를 안내하도록하는 접근 방식은 대부분의 경우 더 나은 설계로 이어집니다. 단위 테스트의 마지막 장점은 더 빠릅니다. 나는 단위 테스트만큼 빠르다는 것을 알기에 충분한 통합 테스트를 작성했습니다.

내가 알아 낸 웹을 통해보고 된 후 언급 한 광산과 매우 유사한 아이디어가 있다는 것을 여기거기는 . 이 아이디어에 대해 어떻게 생각하십니까?

편집하다

디자인이 좋은 예에 대한 질문에 대답했지만 다음 요구 사항에 대해 큰 리팩터링이 필요했습니다.

처음에는 특정 명령을 실행하기위한 몇 가지 요구 사항이있었습니다. 확장 가능한 명령 파서를 작성했습니다.이 명령은 일종의 명령 프롬프트에서 명령을 구문 분석하고 모델에서 올바른 명령 프롬프트를 호출했습니다. 결과는 뷰 모델 클래스로 표시되었습니다. 첫 번째 디자인

여기에는 아무런 문제가 없었습니다. 모든 클래스는 서로 독립적이었고 새 명령을 쉽게 추가하고 새 데이터를 표시 할 수있었습니다.

다음 요구 사항은 모든 명령에 자체 뷰 표현이 있어야한다는 것입니다. 명령 결과의 미리보기입니다. 새로운 요구 사항에 맞는 더 나은 디자인을 달성하기 위해 프로그램을 재 설계했습니다. 두 번째 디자인

이제는 모든 명령에 자체 뷰 모델이 있으므로 자체 미리보기가 있기 때문에 좋았습니다.

문제는 명령 구문 분석기가 명령의 토큰 기반 구문 분석을 사용하도록 변경되었으며 명령 실행 기능에서 제거되었다는 것입니다. 모든 명령에는 자체 뷰 모델이 있으며 데이터 뷰 모델은 표시해야 할 데이터를 알고있는 것보다 현재 명령 뷰 모델 만 알고 있습니다.

이 시점에서 내가 알고 싶은 것은 새로운 디자인이 기존 요구 사항을 위반하지 않는 경우입니다. 합격 시험을 변경할 필요가 없었습니다. 거의 모든 단위 테스트를 리팩토링하거나 삭제해야했는데, 이는 엄청난 작업이었습니다.

여기서 보여 드리고 싶은 것은 개발 과정에서 자주 발생하는 일반적인 상황입니다. 기존 디자인이나 새로운 디자인에는 아무런 문제가 없었으며 요구 사항에 따라 자연스럽게 바뀌 었습니다. 어떻게 이해했는지, 이것이 TDD의 장점 중 하나는 디자인이 발전한다는 것입니다.

결론

모든 답변과 토론에 감사드립니다. 이 토론을 요약하면 다음 프로젝트에서 테스트 할 접근법을 생각했습니다.

  • 우선 항상 항상했던 것처럼 구현하기 전에 모든 테스트를 작성합니다.
  • 요구 사항에 대해서는 처음에 전체 프로그램을 테스트하는 승인 테스트를 작성합니다. 그런 다음 요구 사항을 구현해야하는 구성 요소에 대한 통합 테스트를 작성합니다. 이 요구 사항을 구현하기 위해 다른 구성 요소와 밀접하게 작동하는 구성 요소가 있으면 두 구성 요소를 함께 테스트하는 통합 테스트도 작성합니다. 마지막으로 알고리즘이나 순열이 높은 다른 클래스 (예 : 직렬 변환기)를 작성 해야하는 경우이 특정 클래스에 대한 단위 테스트를 작성합니다. 다른 모든 클래스는 테스트되지 않고 단위 테스트가 수행됩니다.
  • 버그의 경우 프로세스를 단순화 할 수 있습니다. 일반적으로 버그는 하나 또는 두 개의 구성 요소로 인해 발생합니다. 이 경우 버그를 테스트하는 구성 요소에 대해 하나의 통합 테스트를 작성합니다. 알고리즘과 관련이 있다면 단위 테스트 만 작성합니다. 버그가 발생하는 구성 요소를 찾기가 쉽지 않으면 버그를 찾기 위해 승인 테스트를 작성합니다. 이는 예외입니다.


이 질문들은 왜 시험을 치르는 지에 대한 문제를 더 다루는 것 같습니다. 단위 테스트 대신 기능 테스트를 작성하는 것이 더 나은 방법인지 논의하고 싶습니다.
Yggdrasil

내 독서 당, 중복 질문에 대한 답변은 주로 단위 테스트가 더 합리적 일 때에 관한 것입니다
gnat

첫 번째 링크 자체는 복제본입니다. 당신은 의미 생각한다 programmers.stackexchange.com/questions/66480/...
로비 디

Robbie Dee의 링크에서 답변은 왜 테스트해야하는지에 대한 것입니다.
Yggdrasil

답변:


37

오렌지와 사과를 비교하고 있습니다.

통합 테스트, 승인 테스트, 단위 테스트, 행동 테스트-모두 테스트이며 코드를 개선하는 데 도움이되지만 상당히 다릅니다.

나는 내 의견으로 각기 다른 테스트를 살펴보고 왜 당신이 모든 테스트를 혼합해야 하는지를 설명 할 것입니다.

통합 테스트 :

예를 들어, 웹 서비스 요청을 시뮬레이션하고 결과가 다시 나타나는지 확인하는 등 시스템의 여러 구성 요소가 올바르게 통합되는지 테스트하십시오. 나는 일반적으로 실제 정적 데이터와 모의 의존성을 사용하여 일관성있게 확인할 수 있도록합니다.

합격 시험 :

승인 테스트는 비즈니스 사용 사례와 직접적으로 관련되어야합니다. 규모가 크거나 ( "거래가 올바르게 제출되었습니다") 작거나 ( "필터가 목록을 성공적으로 필터링 함") 중요하지 않습니다. 중요한 것은 특정 사용자 요구 사항과 명시 적으로 연결되어야한다는 것입니다. 나는 테스트 중심 개발에 초점을 맞추고 싶습니다. 개발자 및 qa에 대한 사용자 스토리에 대한 테스트에 대한 훌륭한 참조 매뉴얼이 있음을 의미하기 때문입니다.

단위 테스트 :

개별 사용자 스토리를 자체적으로 구성하거나 구성하지 않을 수있는 작은 개별 기능 단위의 경우 (예 : 특정 웹 페이지에 액세스 할 때 모든 고객을 검색한다고 말하는 사용자 스토리는 승인 테스트 일 수 있음) 페이지 및 응답 확인)에도 여러 단위 테스트가 포함될 수 있습니다 (보안 권한이 확인되었는지 확인하고 데이터베이스 연결 쿼리를 올바르게 확인하는지, 결과 수를 제한하는 코드가 올바르게 실행되는지 확인하십시오)-모두 "단위 테스트"입니다. 그것은 완전한 합격 시험이 아닙니다.

행동 테스트 :

특정 입력의 경우 애플리케이션의 흐름을 정의하십시오. 예를 들어, "연결을 설정할 수없는 경우 시스템이 연결을 재 시도하는지 확인하십시오." 다시 말하지만 이것은 완전한 합격 테스트는 아니지만 여전히 유용한 것을 확인할 수 있습니다.

이것들은 모두 작문 시험 경험을 통해 제 생각에 있습니다. 나는 교과서 접근법에 중점을 두는 것이 아니라 테스트 가치를 부여하는 것에 중점을 둡니다.


당신의 정의에서 나는 의미하는 것이 단위 테스트보다 더 많은 행동 테스트 (?)를 작성하는 것이라고 가정합니다. 나를위한 단위 테스트는 모든 의존성을 조롱 한 단일 클래스를 테스트하는 테스트입니다. 단위 테스트가 가장 유용한 경우가 있습니다. 예를 들어 복잡한 알고리즘을 작성할 때입니다. 그런 다음 알고리즘의 예상 출력과 함께 많은 예제가 있습니다. 실제로 동작 테스트보다 빠르기 때문에 단위 수준에서 테스트하고 싶습니다. 나는 행동 수준으로 쉽게 테스트 할 수있는 클래스를 통과하는 경로가 손으로 가득한 단위 레벨에서 클래스 테스트의 가치를 보지 못합니다.
Yggdrasil

14
개인적으로 수용 테스트가 가장 중요하다고 생각합니다. 통신, 신뢰성 및 오류 사례와 같은 것을 테스트 할 때는 동작 테스트가 중요하고 작은 복잡한 기능을 테스트 할 때는 단위 테스트가 중요합니다 (알고리즘이 이에 대한 좋은 예입니다)
Michael

나는 당신의 용어에 너무 확고하지 않습니다. 우리는 프로그래밍 스위트를 프로그래밍합니다. 거기에서 나는 그래픽 편집기를 책임진다. 내 테스트는 나머지 스위트의 모의 서비스와 모의 UI로 편집기를 테스트합니다. 어떤 종류의 시험입니까?
Yggdrasil

1
테스트 대상에 따라 비즈니스 기능을 테스트합니까 (허용 테스트)? 통합을 테스트하고 있습니까 (통합 테스트)? 버튼을 클릭 할 때 발생하는 동작을 테스트하고 있습니까 (동작 테스트)? 알고리즘을 테스트하고 있습니까 (단위 테스트)?
Michael

4
"나는 교과서 접근 방식에 중점을 두는 것이 아니라 테스트 가치를 제공하는 것에 중점을 둡니다"오, 사실입니다! 항상 물어보아야 할 첫 번째 질문 은 "이 작업을 통해 어떤 문제를 해결합니까?"입니다. 그리고 다른 프로젝트는 다른 문제를 해결해야 할 수도 있습니다!
Laurent Bourgault-Roy 2016

40

TL; DR : 귀하의 요구를 충족시키는 한, 그렇습니다.

저는 수년간 ATDD (Acceptance Test Driven Development) 개발을 해왔습니다. 매우 성공할 수 있습니다. 알아 두어야 할 것이 몇 가지 있습니다.

  • 단위 테스트는 실제로 IOC 시행에 도움이됩니다. 단위 테스트가 없으면 개발자는 잘 작성된 코드의 요구 사항을 충족하는지 확인해야합니다 (단위 테스트가 잘 작성된 코드를 구동하는 한).
  • 실제로 조롱되는 리소스를 실제로 사용하는 경우 속도가 느려지고 오류가 발생할 수 있습니다.
  • 단위 테스트와 마찬가지로 테스트에서 특정 문제를 찾아 내지 않습니다. 테스트 실패를 해결하려면 추가 조사를 수행해야합니다.

이제 장점

  • 훨씬 더 나은 테스트 범위, 통합 지점을 다룹니다.
  • 시스템 전체가 소프트웨어 개발의 핵심 인 수용 기준을 충족하는지 확인합니다.
  • 큰 리 팩터를 훨씬 쉽고 빠르며 저렴하게 만듭니다.

항상 그렇듯이 분석을 수행하고이 관행이 귀하의 상황에 적합한 지 파악하는 것은 귀하의 책임입니다. 많은 사람들과 달리 나는 이상적인 정답이 있다고 생각하지 않습니다. 요구 사항과 요구 사항에 따라 다릅니다.


8
훌륭한 지적입니다. 비행 색상으로 "통과"할 때 따뜻한 만족감을 얻기 위해 테스트에 대해 약간의 공간 사관이되고 수백 건의 사례를 작성하는 것은 너무 쉽습니다. 간단히 말해 : 소프트웨어가 사용자 관점에서 수행해야 할 작업을 수행하지 않으면 가장 중요한 첫 번째 테스트에 실패한 것입니다.
Robbie Dee

특정 문제를 정확히 찾아 낼 수있는 좋은 방법입니다. 요구 사항이 크면 전체 시스템을 테스트하는 승인 테스트를 작성하고 요구 사항을 달성하기 위해 시스템의 특정 구성 요소의 하위 작업을 테스트하는 테스트를 작성합니다. 이를 통해 대부분의 경우 결함이있는 구성 요소를 찾아 낼 수 있습니다.
Yggdrasil

2
"단위 테스트는 IOC를 시행하는 데 도움이됩니다"?!? 나는 당신이 IoC 대신에 DI를 의미한다고 확신하지만, 어쨌든 누군가 DI 사용 을 강요 하고자하는 이유는 무엇입니까? 개인적으로, 나는 DI가 실제로 비 객체 (프로 시저 스타일 프로그래밍)로 이어진다는 것을 알았습니다.
Rogério

통합 테스트 만 수행한다는 주장과 통합 및 유닛 테스트를 모두 수행하는 (IMO 최고) 옵션에 대한 정보를 제공 할 수 있습니까? 귀하의 답변은 훌륭하지만 이러한 것들을 상호 배타적이라고 생각하는 것 같습니다.
starmandeluxe

@starmandeluxe 그들은 실제로 상호 배타적이지 않습니다. 오히려 테스트에서 도출하고자하는 가치에 대한 문제입니다. 값이 단위 테스트 작성의 개발 / 지원 비용을 초과 한 위치에서 단위 테스트를 수행합니다. 전의. 나는 금융 애플리케이션에서 복리이자 함수를 확실히 단위 테스트 할 것입니다.
dietbuddha

18

글쎄, 나는 테스트 / 요구 사항이 프로그램의 디자인을 발전 시키도록 TDD와 같은 접근법을 사용했다. 문제는 쓰기 / 리 팩터 테스트와 관련하여 개발 시간의 절반 이상이

단위 테스트는 사용되는 구성 요소의 공용 인터페이스가 너무 자주 변경되지 않을 때 가장 잘 작동합니다. 즉, 구성 요소가 이미 잘 설계되어있는 경우 (예 : SOLID 원칙에 따름)를 의미합니다.

따라서 좋은 디자인이 구성 요소에 대한 많은 단위 테스트를 "던지기"에서 "진화"한다고 믿는 것은 잘못된 것입니다. TDD는 훌륭한 디자인을위한 "교사"가 아니며, 디자인의 특정 측면이 좋은지 (특히 테스트 가능성) 확인하는 데 도움이 될 수 있습니다.

요구 사항이 변경되고 구성 요소의 내부를 변경해야 할 경우 단위 테스트의 90 %가 중단되므로 매우 자주 리팩터링해야합니다.

그래서 내 충고는 : 당신이 만든 구성 요소의 디자인과 개방 / 폐쇄 원칙에 따라 더 구성 요소를 만드는 방법에 대해 생각하십시오. 후자의 개념은 구성 요소의 기능을 나중에 변경하지 않고도 확장 할 수 있도록하는 것입니다 (따라서 단위 테스트에 사용되는 구성 요소의 API를 손상시키지 않음). 이러한 구성 요소는 단위 테스트 테스트로 다룰 수 있으며 경험 한 바에 따라 경험 한대로 고통스럽지 않아야합니다.

이러한 설계를 즉시 제시 할 수없는 경우 승인 및 통합 테스트가 더 나은 시작일 수 있습니다.

편집 : 때로는 구성 요소 디자인이 좋지만 단위 테스트 디자인에 문제가 발생할 수 있습니다 . 간단한 예 : 클래스 X의 "MyMethod"메소드를 테스트하고 작성하려고합니다.

    var x= new X();
    Assert.AreEqual("expected value 1" x.MyMethod("value 1"));
    Assert.AreEqual("expected value 2" x.MyMethod("value 2"));
    // ...
    Assert.AreEqual("expected value 500" x.MyMethod("value 500"));

(값에 어떤 종류의 의미가 있다고 가정).

또한 프로덕션 코드에는에 대한 호출이 하나만 있다고 가정하십시오 X.MyMethod. 이제 새로운 요구 사항의 경우 "MyMethod"메서드에는 추가 매개 변수 (예 :와 같은 context)가 필요하므로 생략 할 수 없습니다. 단위 테스트가 없으면 한 곳에서 호출 코드를 리팩터링해야합니다. 단위 테스트를 통해 500 곳을 리팩토링해야합니다.

그러나 여기서의 원인은 단위 테스트 자체가 아니라 "X.MyMethod"에 대한 동일한 호출이 "DRY (Do n't Repeat Yourself)"원칙을 엄격하게 따르지 않고 반복해서 반복된다는 사실입니다. 여기서는 테스트 데이터와 관련 예상 값을 목록에 넣고 루프에서 "MyMethod"에 대한 호출을 실행합니다 (또는 테스트 도구가 "데이터 드라이브 테스트"를 지원하는 경우 해당 기능을 사용함). 메소드 서명이 1로 변경 될 때 단위 테스트에서 변경되는 위치 수 (500과 반대)

실제 상황에서는 상황이 더 복잡 할 수 있지만 단위 테스트에서 변경 될 수 있는지 알 수없는 구성 요소 API를 사용하는 경우 수를 줄이십시오. 해당 API 호출을 최소한으로합니다.


"이것은 구성 요소가 이미 잘 설계 할 때, 의미한다.": 당신과 함께 동의하지만, 당신은 코드를 작성하기 전에 테스트를 작성하는 경우 어떻게 구성 요소가 이미 설계 할 수 있으며, 코드 입니다 디자인은? 적어도 이것이 내가 TDD를 이해 한 방법입니다.
Giorgio

2
@Giorgio : 실제로 테스트를 먼저 작성하더라도 나중에 중요하지 않습니다. 디자인은 구성 요소의 책임, 공용 인터페이스, 종속성 (직접 또는 주입), 런타임 또는 컴파일 시간 동작, 변경 가능성, 이름, 데이터 흐름, 제어 흐름, 계층 등에 대한 결정을 내리는 것을 의미합니다. 디자인은 또한 일부 결정을 최신 시점으로 연기하는 것을 의미합니다. 단위 테스트는 설계가 정상인지 간접적으로 보여줄 수 있습니다. 요구 사항이 변경 될 때 많은 설계를 나중에 리팩토링해야한다면 아마 그렇지 않았습니다.
Doc Brown

@Giorgio : 예를 들어 설명 할 수 있습니다. "MyMethod"메소드와 2 개의 매개 변수가있는 컴포넌트 X가 있다고 가정하십시오. TDD를 사용하면 X x= new X(); AssertTrue(x.MyMethod(12,"abc"))실제로 메소드를 구현하기 전에 작성 합니다. 선행 디자인을 사용하여 먼저 class X{ public bool MyMethod(int p, string q){/*...*/}}작성하고 나중에 테스트를 작성할 수 있습니다 . 두 경우 모두 동일한 설계 결정을 내 렸습니다. 결정이 좋거나 나빴다면 TDD가 알려주지 않을 것입니다.
Doc Brown

1
나는 당신에게 동의한다 : 나는 TDD가 자동으로 좋은 디자인을 만들 것이라는 가정하에 맹목적으로 적용되는 것을 볼 때 약간 회의적이다. 또한 디자인이 아직 명확하지 않은 경우 TDD가 방해가되는 경우가 있습니다. 수행중인 작업에 대한 개요를보기 전에 세부 사항을 테스트해야합니다. 따라서 내가 올바르게 이해하면 동의합니다. 나는 (1) 단위 테스트가 디자인을 검증하는 데 도움이되지만 디자인은 별도의 활동이며 (2) 테스트를 작성하기 전에 아이디어를 구성해야하고 TDD가 속도를 늦출 수 있기 때문에 TDD가 항상 최상의 솔루션은 아니라고 생각합니다. 이.
Giorgio

1
곧, 단위 테스트는 구성 요소의 내부 설계에 결함을 보여줄 수 있습니다. 인터페이스, 사전 및 사후 조건을 미리 알고 있어야합니다. 그렇지 않으면 단위 테스트를 작성할 수 없습니다. 따라서 단위 테스트를 작성하기 전에 구성 요소의 설계를 수행해야합니다. 이것이 수행되는 방법 (하위 레벨 설계, 상세 설계 또는 내부 설계 또는 호출하고자하는 것)은 단위 테스트가 작성된 후 발생할 수 있습니다.
Maarten Bodewes 2016 년

9

물론입니다.

이걸 고려하세요:

  • 단위 테스트는 작은 코드를 실행하는 작고 대상이 지정된 테스트입니다. 적절한 코드 범위를 달성하기 위해 많은 것을 작성하여 모든 (또는 어색한 비트의 대부분)을 테스트합니다.
  • 통합 테스트는 코드의 넓은 표면을 시험하는 광범위하고 광범위한 테스트입니다. 적절한 코드 범위를 달성하기 위해 그중 몇 가지를 작성하여 모든 (또는 어색한 비트의 대부분)을 테스트합니다.

전반적인 차이점을 참조하십시오 ....

이 문제는 코드 적용 범위 중 하나입니다. 통합 / 수락 테스트를 사용하여 모든 코드를 완전히 테스트 할 수 있다면 문제는 없습니다. 코드가 테스트되었습니다. 그것이 목표입니다.

모든 TDD 기반 프로젝트는 모든 단위가 실제로 제대로 작동하는지 확인하기 위해 통합 테스트가 필요하기 때문에 혼합해야 할 수도 있습니다 (100 % 통과 된 단위 테스트 코드베이스가 반드시 작동하지는 않습니다. 당신이 그들을 모두 모을 때!)

문제는 실제로 테스트의 용이성, 오류 디버깅 및 수정에 달려 있습니다. 어떤 사람들은 단위 테스트가 매우 훌륭하다는 것을 알고 있으며 작고 단순하며 실패를 쉽게 볼 수 있지만 단점은 단위 테스트 도구에 맞게 코드를 재구성하여 매우 많이 작성해야한다는 단점이 있습니다. 통합 테스트는 많은 코드를 다루기 위해 작성하기가 더 어려우므로 오류를 디버깅하기 위해 로깅과 같은 기술을 사용해야 할 수도 있습니다 (그러나 어쨌든이 작업을 수행해야한다고 말하면 단위 테스트 실패는 불가능합니다) 현장에있을 때!).

어느 쪽이든, 당신은 여전히 ​​테스트 된 코드를 얻습니다. 어떤 메커니즘이 더 적합한 지 결정하면됩니다. (나는 약간의 혼합으로 가고 복잡한 알고리즘을 단위 테스트하고 나머지는 통합 테스트한다).


7
사실이 아닙니다 ... 통합 테스트를 통해 버그가있는 두 가지 구성 요소를 가질 수 있지만 통합 테스트에서 버그가 사라집니다. 최종 사용자가 이러한 구성 요소 중 하나만 사용하는 방식으로 사용하기 전까지는 중요하지 않습니다.
Michael Shaw

1
코드 커버리지! = 테스트 됨-서로 상쇄하는 버그 외에도 생각하지 못한 시나리오는 어떻습니까? 통합 테스트는 올바른 경로 테스트에 적합하지만 상황이 좋지 않을 때 적절한 통합 테스트는 거의 볼 수 없습니다.
Michael

4
@ 프톨레마이오스 2 개의 버그가있는 구성 요소가 서로를 상쇄하는 희귀 성은 서로 간섭하는 2 개의 작동 구성 요소보다 훨씬 낮습니다.
gbjbaanb

2
@Michael은 테스트에 충분한 노력을 기울이지 않았으므로 테스트가 훨씬 상세해야하기 때문에 우수한 통합 테스트를 수행하는 것이 더 어렵다고 말했습니다. 단위 테스트에서와 마찬가지로 통합 테스트에서 잘못된 데이터를 제공 할 수 있습니다. 통합 테스트! = 행복한 길. 코드를 최대한 많이 사용하는 것이 중요하므로, 코드가 얼마나 많이 사용되었는지를 보여주는 코드 적용 도구가 있습니다.
gbjbaanb

1
@Michael Cucumber 또는 SpecFlow와 같은 도구를 올바르게 사용하면 단위 테스트만큼 빠른 예외 및 극한 상황도 테스트하는 통합 테스트를 만들 수 있습니다. 그러나 한 클래스가 많은 순열을해야한다면이 클래스에 대한 단위 테스트 작성을 선호합니다. 그러나 이것은 소수의 경로 만있는 클래스를 갖는 것보다 덜 자주 발생합니다.
Yggdrasil

2

나는 그것이 끔찍한 생각이라고 생각합니다.

승인 테스트와 통합 테스트는 코드의 더 넓은 부분을 터치하여 특정 대상을 테스트하므로 시간이 지남에 따라 더 많은 리팩토링 이 필요합니다 . 게다가 코드의 넓은 섹션을 다루기 때문에 검색 범위가 넓어 근본 원인을 추적하는 데 소요되는 시간이 늘어납니다.

아니요, UI가 90 % 인 이상한 앱이나 단위 테스트에 어색한 것이 없다면 일반적으로 더 많은 단위 테스트를 작성해야합니다. 당신이 겪고있는 고통은 단위 테스트가 아니라 테스트 첫 개발을하는 것입니다. 일반적으로 대부분의 필기 시험에서 1/3의 시간 만 투자해야합니다. 결국, 그들은 당신을 섬기기 위해 거기에 있습니다.


2
내가 TDD에 대해 듣는 주요 쇠고기는 자연 개발 흐름을 방해하고 처음부터 방어 프로그래밍을 시행한다는 것입니다. 프로그래머가 이미 시간 압력을 받고 있다면 코드를 자르고 나중에 다듬기를 원할 것입니다. 물론, 버그가있는 코드로 임의의 기한을 맞추는 것은 잘못된 경제입니다.
Robbie Dee

2
사실, 특히 "나중에 연마"하는 일은 결코 일어나지 않는 것처럼 보입니다. 개발자가 "나갈 필요가 있고 나중에 나아갈 것"이라고 강요하는 모든 검토는 우리가 알고있을 때 일어날 것입니다. 부채 = 내 의견으로는 파산 개발자.
Michael

3
대답은 나에게 의미가 있습니다. 왜 그렇게 많은 마이너스가 있는지 모르겠습니다. Mike Cohn의 말을 인용하자면 : "단위 테스트는 견고한 테스트 자동화 전략의 기초가되어야 하고 피라미드 의 가장 큰 부분 을 나타냅니다 . 자동화 된 단위 테스트는 프로그래머에게 특정 데이터를 제공하기 때문에 훌륭합니다. 버그가 있습니다. line 47 " mountaingoatsoftware.com/blog/…
guillaume31

4
@ guillaume31 어떤 사람이 한 번 자신이 좋다고 말했다고해서 좋은 것은 아닙니다. 내 경험상 버그는 새로운 요구 사항으로 변경 되었기 때문에 단위 테스트로 감지되지 않습니다. 또한 대부분의 버그는 통합 버그입니다. 따라서 통합 테스트를 통해 대부분을 탐지합니다.
Yggdrasil

2
@Yggdrasil Martin Fowler도 인용 할 수 있습니다. "고수준 테스트에서 오류가 발생하면 기능 코드에 버그가있는 것뿐만 아니라 단위 테스트가 누락 된 것입니다." martinfowler.com/bliki/TestPyramid.html 어쨌든 통합 테스트만으로도 효과가 있다면 괜찮습니다. 필자의 경험은 필요하지만 단위 테스트보다 속도가 느리고 오류 메시지가 덜 정확하고 기동성이 적습니다 (보다 조합적임). 또한 통합 테스트를 작성할 때 객체 자체의 정확성이 아니라 사전 (mis?)로 생각한 시나리오에 대한 추론을 통해 미래에 대한 증거가 적습니다.
guillaume31

2

TDD의 "승리"는 일단 테스트가 작성되면 자동화 될 수 있다는 것입니다. 단점은 개발 시간의 상당한 부분을 소비 할 수 있다는 것입니다. 이것이 실제로 전체 프로세스 속도를 늦출 지 여부는 바보입니다. 선행 테스트를 통해 개발주기가 끝날 때 수정해야 할 오류 수가 줄어든다는 주장이 있습니다.

이것은 행동이 단위 테스트에 포함될 수 있기 때문에 BDD가 발생하는 곳이므로 프로세스는 덜 추상적이며 유형적입니다.

시간이 얼마 남지 않았다면 가능한 한 다양한 종류의 테스트를 많이해야합니다. 그러나 시간은 일반적으로 제한되어 있으며 지속적인 테스트는 비용 효율적입니다.

이 모든 것이 가장 가치있는 테스트가 프로세스의 최전방에 있어야한다는 결론으로 ​​이어집니다. 이것은 그 자체로 한 가지 유형의 테스트를 다른 유형보다 자동으로 선호하지 않습니다.

개인적인 용도로 명령 행 위젯을 작성하는 경우 주로 단위 테스트에 관심이 있습니다. 웹 서비스가 말하는 반면, 상당한 양의 통합 / 행동 테스트가 필요합니다.

대부분의 유형의 테스트는 "레이싱 라인"이라고하는 것에 중점을 두는 반면, 오늘날 비즈니스에서 요구하는 것을 테스트하는 반면, 단위 테스트는 이후 개발 단계에서 나타날 수있는 미묘한 버그를 제거하는 데 탁월합니다. 이는 쉽게 측정 할 수없는 이점이므로 간과되는 경우가 많습니다.


1
테스트를 미리 작성하고 대부분의 오류를 처리하기에 충분한 테스트를 작성합니다. 나중에 나타나는 버그에 관해서는. 요구 사항이 변경되었거나 새로운 요구 사항이 적용되었다는 소리가 들립니다. 통합 / 동작 테스트를 변경하고 추가해야합니다. 그렇다면 이전 요구 사항에 버그가 표시되면이 테스트를 통해 버그가 표시됩니다. 자동화에 관해서. 내 모든 테스트는 항상 실행됩니다.
Yggdrasil

마지막 단락에서 생각했던 예는 라이브러리가 단일 응용 프로그램에서만 독점적으로 사용되었지만이 범용 라이브러리로 만들기 위해 비즈니스 요구 사항이 있었던 곳입니다. 이 경우 라이브러리에 연결하는 모든 시스템에 대해 새로운 통합 / 동작 테스트를 작성하는 것보다 최소한 단위 테스트를 수행하는 것이 좋습니다.
Robbie Dee

2
자동화 테스트 및 단위 테스트는 완전히 직교하는 문제입니다. 모든 자존심있는 프로젝트에는 자동화 된 통합 및 기능 테스트가 있습니다. 물론 수동 장치 테스트는 종종 보이지 않지만 존재할 수 있습니다 (기본적으로 수동 장치 테스트는 일부 특정 기능을위한 테스트 유틸리티입니다).
Jan Hudec

참으로. 상당한 시간 동안 개발 영역 외부에 존재하는 자동화 된 타사 도구를위한 번영하는 시장이 있습니다.
Robbie Dee

1

단위 테스트의 마지막 장점은 더 빠릅니다. 나는 단위 테스트만큼 빠르다는 것을 알기에 충분한 통합 테스트를 작성했습니다.

이것이 바로 "마지막 이점"이 아니라 요점입니다. 프로젝트가 점점 커질수록 통합 승인 테스트는 점점 느려지고 있습니다. 그리고 여기, 나는 당신이 그것들을 실행을 멈출 수 있도록 너무 느리다는 것을 의미합니다.

물론 단위 테스트도 느려지고 있지만 여전히 몇 배 이상 빠릅니다. 예를 들어, 이전 프로젝트 (c ++, 약 600kLOC, 4000 단위 테스트 및 200 통합 테스트)에서는 통합 테스트를 실행하는 데 약 15 분 이상이 소요되었습니다. 변경되는 부품에 대한 단위 테스트를 빌드하고 실행하려면 평균 30 초 미만이 소요됩니다. 그렇게 빨리 할 수 ​​있으면 항상하고 싶을 것입니다.

분명히하기 위해 : 통합 및 승인 테스트를 추가하지 말라고 말하지는 않지만 잘못된 방식으로 TDD / BDD를 한 것처럼 보입니다.

단위 테스트도 설계에 좋습니다.

예, 테스트 가능성을 염두에두고 디자인하면 디자인이 향상됩니다.

문제는 쓰기 / 리 팩터 테스트와 관련하여 개발 시간의 절반 이상이 문제였습니다. 결국 많은 테스트에 리팩토링하고 작성해야하므로 더 이상 기능을 구현하고 싶지 않았습니다.

요구 사항이 변경되면 코드를 변경해야합니다. 단위 테스트를 작성하지 않으면 작업을 완료하지 않았다고 말할 것입니다. 그러나 이것이 단위 테스트를 100 % 적용해야한다는 의미는 아닙니다. 이것이 목표가 아닙니다. GUI 나 파일에 접근하는 것과 같은 것들도 단위 테스트를위한 것이 아닙니다.

그 결과 코드 품질이 향상되고 또 다른 테스트 계층이 만들어집니다. 그만한 가치가 있다고 말할 것입니다.


또한 1000 번의 수락 테스트를 받았으며 모두 실행하는 데 1 주일이 걸렸습니다.


1
내 예를 보았습니까? 이것은 항상 일어났다. 요점은 새 기능을 구현할 때 새 기능을 테스트하도록 단위 테스트를 변경 / 추가하므로 단위 테스트가 중단되지 않는다는 것입니다. 대부분의 경우 환경이 조롱 되었기 때문에 단위 테스트로 감지되지 않는 변경의 부작용이 있습니다. 이로 인해 내 경험상 단위 테스트가 기존 기능을 중단했다고 말한 적이 없습니다. 항상 내 실수를 보여준 통합 및 수용 테스트였습니다.
Yggdrasil

실행 시간은. 응용 프로그램이 증가함에 따라 대부분 격리 된 구성 요소 수가 증가하고 있습니다. 그렇지 않으면 내가 잘못한 것입니다. 새 기능을 구현할 때는 대부분 제한된 수의 구성 요소에만 있습니다. 전체 응용 프로그램의 범위에서 하나 이상의 승인 테스트를 작성합니다. 느릴 수 있습니다. 또한 구성 요소 관점에서 동일한 테스트를 작성합니다. 일반적으로 구성 요소가 빠르기 때문에이 테스트는 빠릅니다. 구성 요소 테스트는 충분히 빠르기 때문에 항상 실행할 수 있습니다.
Yggdrasil

@Yggdrasil 내가 말했듯이, 단위 테스트는 모두 강력하지는 않지만 가장 빠르기 때문에 일반적으로 첫 번째 테스트 레이어입니다. 다른 테스트도 유용하며 결합해야합니다.
BЈовић

1
그것들이 더 빠르다고해서 이것이 단지 이것 때문에 또는 그것들을 쓰는 것이 일반적이기 때문에 사용되어야한다는 것을 의미하지는 않습니다. 내가 말했듯이 단위 테스트는 중단되지 않으므로 나에게 가치가 없습니다.
이그드라실

1
문제는 그들이 부서지지 않을 때 단위 테스트에서 어떤 가치가 있습니까? 항상 새로운 요구 사항에 맞게 조정해야 할 때 왜 작성해야합니까? 내가 볼 수있는 유일한 값은 순열이 높은 알고리즘 및 기타 클래스입니다. 그러나 이것들은 구성 요소 및 수용 테스트보다 적습니다.
Yggdrasil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.