단위 테스트를 어떻게 단위 테스트합니까? [닫은]


89

MVCStoreFront 앱에서 Rob Connerys 웹 캐스트를보고 있었는데, 그가 다음과 같은 가장 평범한 것조차도 단위 테스트하고 있다는 것을 알았습니다.

public Decimal DiscountPrice
{
   get
   {
       return this.Price - this.Discount;
   }
}

다음과 같은 테스트가있을 것입니다.

[TestMethod]
public void Test_DiscountPrice
{
    Product p = new Product();
    p.Price = 100;
    p.Discount = 20;
    Assert.IsEqual(p.DiscountPrice,80);
}

나는 모두 단위 테스트에 관심이 있지만, 가끔 이런 형태의 테스트 우선 개발이 정말로 유익한 지 궁금합니다. 예를 들어 실제 프로세스에서는 코드 위에 3-4 개의 레이어가 있습니다 (비즈니스 요청, 요구 사항 문서, 아키텍처 문서) , 여기서 실제 정의 된 비즈니스 규칙 (할인 가격은 가격-할인)이 잘못 정의 될 수 있습니다.

그럴 경우 단위 테스트는 아무 의미가 없습니다.

또한 단위 테스트는 또 다른 실패 지점입니다.

[TestMethod]
public void Test_DiscountPrice
{
    Product p = new Product();
    p.Price = 100;
    p.Discount = 20;
    Assert.IsEqual(p.DiscountPrice,90);
}

이제 테스트에 결함이 있습니다. 분명히 간단한 테스트에서는 큰 문제가 아니지만 복잡한 비즈니스 규칙을 테스트했다고 가정 해 보겠습니다. 여기서 우리는 무엇을 얻습니까?

유지 관리 개발자가 유지 관리하는 응용 프로그램의 수명으로 2 년을 앞 당깁니다. 이제 비즈니스가 규칙을 변경하고 테스트가 다시 중단되고 일부 신인 개발자가 테스트를 잘못 수정합니다. 이제 또 다른 실패 지점이 있습니다.

내가 볼 수있는 것은 실제 수익률이없는 더 많은 실패 지점입니다. 할인 가격이 잘못된 경우 테스트 팀은 여전히 ​​문제를 찾을 수 있습니다. 단위 테스트가 작업을 어떻게 저장 했습니까?

내가 여기서 무엇을 놓치고 있습니까? 지금까지 TDD를 유용하게 받아들이는 데 어려움을 겪고 있으므로 TDD를 사랑하도록 가르쳐주세요. 나도 원한다. 왜냐하면 나도 진보적이기를 원하기 때문이다. 그러나 그것은 나에게 말이되지 않는다.

편집 : 몇 사람이 테스트가 사양을 시행하는 데 도움이된다고 계속 언급했습니다. 스펙도 틀렸다는 것은 내 경험 이었지만, 스펙을 작성해서는 안되는 사람들이 스펙을 작성하는 조직에서 일할 운명이 아닐 수도 있습니다.


5
대부분의 경우 단위 테스트 사양이며 문서이기도합니다!
Steven A. Lowe

32
... 그리고 단위 테스트의 단위 테스트를 단위 테스트 ...하지만 unit ^ 4 테스트와 unit ^ 5 테스트는 어떨까요 ... aaaaaaaaahhhhhhhhh!
dacracot

14
어떤 종류의 테스트로도 잘못된 사양에서 벗어날 수는 없습니다.
Bill the Lizard

4
다른 사람이 한 손으로 박수 치는 소리를 들었습니까?
gnovice 2009-06-02

9
적절한 인용구는 "그냥 아래로 내려가는 거북이 일뿐"이라고 생각합니다.
Quinn Taylor

답변:


63

첫째, 테스트는 보안과 같습니다. 100 % 확신 할 수는 없지만 각 계층은 남아있는 문제를보다 쉽게 ​​해결할 수있는 프레임 워크와 더 많은 신뢰를 추가합니다.

둘째, 테스트를 자체적으로 테스트 할 수있는 서브 루틴으로 나눌 수 있습니다. 20 개의 유사한 테스트가있을 때 (테스트 된) 서브 루틴을 만든다는 것은 메인 테스트가 더 정확할 가능성이있는 서브 루틴의 간단한 호출 20 개라는 것을 의미합니다.

셋째, 일부는 TDD 가이 문제를 해결 한다고 주장 할 것 입니다. 즉, 20 개의 테스트를 작성하고 통과하면 실제로 어떤 것을 테스트하고 있다는 확신이 없습니다. 그러나 처음에 작성한 각 테스트가 실패한 다음 수정했다면 실제로 코드를 테스트하고 있다는 확신이 훨씬 더 커집니다. IMHO이 앞뒤로 가치가있는 것보다 더 많은 시간이 걸리지 만 귀하의 우려를 해결하려는 과정입니다.


2
악마 옹호자 역할을하기 위해 추가 레이어를 더 많은 가능한 실패 지점으로 봅니다. 실제 업무에서 저는 고도로 분산 된 SOA 엔터프라이즈를 통해 많은 팀과 함께 일합니다. 각 팀은 계층이 실패하면 프로젝트를 위험에 빠뜨릴 수 있습니다.
FlySwat

2
이것이 모의 객체를 사용하여 각 레이어를 개별적으로 테스트하는 이유입니다.
Toon Krijthe

10
좋아, 그래서 내 테스트는 IMockedComplexObject를 사용하여 통과하지만 실제로 ComplexObject를 실제로 사용하면 실패합니다. 다시는 아무것도 얻지 못했습니다.
FlySwat

16
@Jonathan-아니요, ComplexObject의 인터페이스로 개발하고 해당 인터페이스에 대해 적절하게 테스트했다고 가정하면 코드가 작동한다는 확신을 얻었습니다. 최악의 경우, ComplexObject에 대한 이해가 예상했던 것과 다르다는 것을 알게되었습니다.
tvanfosson

9
@FlySwat : IMockedComplexObject에 대한 귀하의 의견에 대한 응답으로 Cwash의 다른 답변을 인용합니다. "테스트하려는 것을 조롱하는 것이 아니라 테스트하려는 것이 아닌 것을 조롱합니다."
Brian

39

테스트가 잘못되면 프로덕션 코드가 손상 될 가능성이 없습니다. 적어도 검사가 전혀없는 것보다 나쁘지는 않습니다. 따라서 이것은 "실패 지점"이 아닙니다. 제품이 실제로 작동하기 위해 테스트가 정확할 필요는 없습니다. 작동하는 것으로 승인되기 전에 정확해야 할 수 있지만 손상된 테스트를 수정하는 프로세스는 구현 코드를 위험에 빠뜨리지 않습니다.

테스트, 심지어 이와 같은 사소한 테스트도 코드가 수행해야하는 작업을 2 차 의견으로 생각할 수 있습니다. 한 의견은 테스트이고 다른 의견은 구현입니다. 그들이 동의하지 않는다면, 당신은 문제가 있다는 것을 알게되고 당신은 더 가까이 봅니다.

미래의 누군가가 처음부터 동일한 인터페이스를 구현하려는 경우에도 유용합니다. 할인의 의미를 알기 위해 첫 번째 구현을 읽을 필요는 없으며 테스트는 인터페이스에 대한 서면 설명에 대한 명확한 백업 역할을합니다.

즉, 당신은 시간을 거래하고 있습니다. 이 사소한 테스트를 건너 뛰고 절약 한 시간을 사용하여 작성할 수있는 다른 테스트가 있다면 더 가치가있을 수 있습니다. 실제로 테스트 설정과 응용 프로그램의 특성에 따라 다릅니다. 할인이 앱에 중요하다면 어쨌든 기능 테스트에서이 방법의 버그를 잡을 것입니다. 모든 단위 테스트는 앱이 통합 될 때까지 기다리지 않고 오류 위치가 명확하지 않을 때까지 기다리지 않고이 단위를 테스트하는 지점에서 오류를 포착 할 있도록합니다.

그건 그렇고, 개인적으로 나는 테스트 케이스의 가격으로 100을 사용하지 않을 것입니다. 그 이유는 미래의 누군가가 할인이 백분율이라고 생각할 수 있기 때문입니다. 이와 같은 사소한 테스트의 한 가지 목적은 사양을 읽을 때 실수가 수정되었는지 확인하는 것입니다.

[편집에 관하여 : 잘못된 사양이 실패의 지점 인 것은 불가피하다고 생각합니다. 앱이 무엇을해야하는지 모르는 경우 앱이 작동하지 않을 가능성이 있습니다. 그러나 사양을 반영하기 위해 테스트를 작성한다고해서이 문제가 확대되는 것은 아니며 단순히 해결하지 못할뿐입니다. 따라서 새로운 실패 지점을 추가하는 것이 아니라 와플 문서 대신 코드에서 기존 오류를 나타내는 것입니다 .]


4
잘못된 테스트는 손상된 코드를 야생으로 만들 것입니다. 그것이 실패가 도입되는 곳입니다. 그것은 잘못된 자신감을 제공합니다.
FlySwat

9
사실이지만 테스트가 없으면 코드가 깨질 수도 있습니다. 실수는 코드가 단위 테스트를 통과하면 정확해야한다고 생각하는 것입니다. 저는 경력 초기에이 문제를 치료했습니다. 따라서 부서진 단위 테스트는 부서진 코드를 야생으로 내보내는 것이 아니라 통합 테스트로만 내보내는 것입니다.
Steve Jessop

7
또한 잘못된 테스트라도 구현과 다른 실수를 포함하는 한 손상된 코드를 포착 할 수 있습니다. 그것이 바로 테스트가 반드시 정확할 필요는 없으며 관심 분야에 관심을 끌기 위해 존재한다는 점입니다.
Steve Jessop

2
매우 흥미로운 대답입니다.
Peter

22

내가 볼 수있는 것은 실제 수익률이없는 더 많은 실패 지점입니다. 할인 가격이 잘못된 경우 테스트 팀은 여전히 ​​문제를 찾을 수 있습니다. 단위 테스트가 작업을 어떻게 저장 했습니까?

단위 테스트는 실제로 작업을 저장하는 것이 아니라 버그를 찾고 예방하는 데 도움이됩니다. 그건 일하지만, 작품의 오른쪽 종류입니다. 가장 낮은 수준의 세분화 수준에서 코드를 생각 하고 주어진 입력 세트에 대해 예상 조건에서 작동 함을 입증하는 테스트 케이스를 작성 합니다. 변수를 분리하므로 버그가 나타날 때 올바른 위치를 찾아서 시간 을 절약 할 수 있습니다. 그건 절약 당신이 도로 아래로 변경해야 할 때 다시하고 다시 사용할 수 있도록 테스트의 제품군을.

저는 개인적으로 대부분의 방법론이 화물 컬트 소프트웨어 엔지니어링 에서 제거 된 많은 단계가 아니라고 생각합니다 . TDD가 포함되어 있지만 단위 테스트의 이점을 얻기 위해 엄격한 TDD를 고수 할 필요는 없습니다. 좋은 부품은 유지하고 거의 이익이없는 부품은 버리십시오.

마지막으로, " 단위 테스트를 어떻게 단위 테스트합니까? " 라는 제목의 질문에 대한 대답 은 그럴 필요가 없다는 것입니다. 각 단위 테스트는 매우 간단해야합니다. 특정 입력이있는 메서드를 호출하고 예상 출력과 비교합니다. 메서드 사양이 변경되면 해당 메서드에 대한 일부 단위 테스트도 변경해야 할 것으로 예상 할 수 있습니다. 이것이 바로 낮은 수준의 단위 테스트를 수행하는 이유 중 하나이므로 일부 단위 테스트 만 변경하면됩니다. 요구 사항의 한 가지 변경 사항에 대해 여러 가지 방법에 대한 테스트가 변경되는 경우 충분히 세분화 된 수준에서 테스트하지 못할 수 있습니다.


"특정 입력으로 메서드를 호출하고 예상 출력과 비교합니다." 그러나 출력이 XML 문서와 같은 복잡한 유형이면 어떻게 될까요? 그냥 "=="할 수 없습니다. 특정 코드 비교를 작성해야합니다. 그러면 비교 방법이 버그가있을 수 있습니다.?
andy

@andy : 비교 방법을 별도로 테스트해야합니다. 철저히 테스트 한 후에는 다른 테스트에서 작동하도록 신뢰할 수 있습니다.
Bill the Lizard

멋지다, 빌 고마워. 저는 새로운 곳에서 일하기 시작했고, 단위 테스트는 처음입니다. 원칙적으로 작동한다고 생각합니다. 우리는 정말 유용한 곳에서 Cruise Control을 사용하고 있습니다.하지만 대규모 테스트 세트가 레거시 코드와 같은 운명을 겪는 것 같습니다 ... 확실하지 않습니다 ....
andy

11

단위 테스트는 단위 (방법)가 원하는대로 수행 할 수 있도록합니다. 테스트를 먼저 작성하면 코드를 작성 하기 전에 예상 한 내용을 생각하게 됩니다. 하기 전에 생각하는 것은 항상 좋은 생각입니다.

단위 테스트는 비즈니스 규칙을 반영해야합니다. 물론 코드에 오류가있을 수 있지만 먼저 테스트를 작성하면 코드가 작성되기 전에 비즈니스 규칙의 관점에서 작성할 수 있습니다. 나중에 테스트를 작성하면 코드가 코드를 구현하는 방법 을 알고 있고 의도가 정확하지 않고 구현이 올바른지 확인하려는 유혹을 받기 때문에 설명하는 오류가 발생할 가능성이 더 높다고 생각 합니다.

또한 단위 테스트는 작성해야하는 테스트 중 가장 낮은 형식 일뿐입니다. 통합 테스트 및 승인 테스트도 작성해야하며, 후자는 가능하면 시스템이 예상대로 작동하는지 확인하기 위해 고객이 작성해야합니다. 이 테스트 중에 오류가 발견되면 돌아가서 단위 테스트 (실패)를 작성하여 기능 변경 사항을 테스트하여 올바르게 작동하도록 한 다음 코드를 변경하여 테스트를 통과하십시오. 이제 버그 수정을 캡처하는 회귀 테스트가 있습니다.

[편집하다]

내가 TDD를하면서 발견 한 또 다른 것. 기본적으로 좋은 디자인을 거의 강제합니다. 이는 고도로 결합 된 설계가 분리 된 상태에서 단위 테스트가 거의 불가능하기 때문입니다. TDD를 사용하여 인터페이스, 제어 반전 및 종속성 주입 (디자인을 개선하고 커플 링을 줄이는 모든 패턴)을 사용하는 것이 테스트 가능한 코드에 정말 중요하다는 것을 알아내는 데 오래 걸리지 않습니다.


아마도 이것이 내 문제가있는 곳일 것입니다. 결과를 시각화 할 수있는 것보다 훨씬 쉽게 비즈니스 규칙에 대한 알고리즘을 시각화 할 수 있으므로 코드 자체를 구현하는 데 문제가 없지만 규칙이 중복 된 것으로 조롱하는 것을 볼 수 있습니다. 아마 내가 생각하는 방식 일 수도 있습니다.
FlySwat

이것이 바로 단위 테스트에서하는 일입니다. 알고리즘을 조각으로 나누고 각 조각을 확인하십시오. 일반적으로 단위 테스트에서 기대치를 이미 작성했기 때문에 코드가 자체적으로 작성됩니다.
tvanfosson

모의는 테스트 공간에서 과부하 된 용어입니다. 테스트하려는 것을 조롱하는 것이 아니라 테스트하려고하지 않는 것을 조롱합니다 ... 비즈니스 규칙에 대한 테스트를 작성할 때이를 호출하는 코드를 생성합니다. 그것은 전혀 조롱하지 않습니다. .
cwash 2009-06-03

@cwash-귀하의 의견이 내 답변에 어떻게 적용되는지 잘 모르겠습니다. 조롱에 대해서는 언급하지 않았고 ... 당신의 관찰에 동의합니다.
tvanfosson

@tvanfosson-마지막 코멘트는 @FlySwat에 대한 응답이었습니다. "... 규칙을 중복으로 조롱합니다." 지정하는 것을 잊어 버려 죄송합니다.
cwash

10

테스트는 어떻게 테스트 합니까? 돌연변이 테스트 는 제가 개인적으로 놀랍도록 좋은 효과를 내기 위해 사용한 귀중한 기술입니다. 자세한 내용과 더 많은 학술 참조에 대한 링크는 링크 된 기사를 읽으십시오. 그러나 일반적으로 소스 코드를 수정하여 (예 : "x + = 1"을 "x-= 1"로 변경) "테스트를 테스트"한 다음 테스트를 다시 실행하여 하나 이상의 테스트가 실패하는지 확인합니다. 테스트 실패를 유발하지 않는 돌연변이는 나중에 조사 할 수 있도록 플래그가 지정됩니다.

포괄적 인 테스트 세트로 100 % 라인 및 브랜치 커버리지를 가질 수있는 방법에 놀랄 것입니다.하지만 테스트에 대한 불만없이 소스의 라인을 근본적으로 변경하거나 주석 처리 할 수 ​​있습니다. 종종 이것은 모든 경계 사례를 다루기 위해 올바른 입력으로 테스트하지 않는 것으로 귀결되며 때로는 더 미묘하지만 모든 경우에서 얼마나 많이 나왔는지에 감명을 받았습니다.


1
내가 아직 들어 보지 못한 +1 흥미로운 개념
Wim Coenen

9

TDD (Test-Driven Development)를 적용 할 때 실패한 테스트로 시작됩니다 . 불필요 해 보일 수있는이 단계는 실제로 단위 테스트가 무언가를 테스트하고 있는지 확인하기 위해 여기에 있습니다. 실제로 테스트가 실패하지 않으면 아무 가치도없고 더 나쁜 것은 아무것도 증명하지 못하는 긍정적 인 결과에 의존하게되므로 잘못된 확신으로 이어집니다.

이 과정을 엄격히 따를 때, 모든``장치 ''는 단위 테스트가 만드는 안전망에 의해 보호됩니다.

Assert.IsEqual(p.DiscountPrice,90);

테스트가 그 방향으로 발전 할 이유가 없습니다. 아니면 당신의 추론에서 무언가를 놓치고 있습니다. 가격이 100이고 할인이 20 일 때 할인 가격은 80이됩니다. 이것은 불변과 같습니다.

이제 소프트웨어가 백분율을 기준으로 다른 종류의 할인을 지원해야한다고 상상해보십시오. 아마도 구입 한 볼륨에 따라 Product :: DiscountPrice () 메서드가 더 복잡해질 수 있습니다. 그리고 이러한 변경 사항을 도입하면 처음에 가졌던 단순한 할인 규칙이 깨질 수 있습니다. 그런 다음 회귀를 즉시 감지하는이 테스트의 값을 볼 수 있습니다.


Red-Green-Refactor-TDD 프로세스의 본질을 기억하기위한 것입니다.

빨간색 은 테스트가 실패 할 때 JUnit 빨간색 막대를 나타냅니다.

녹색 은 모든 테스트가 통과 할 때 JUnit 진행률 표시 줄의 색상입니다.

녹색 상태에서 리팩터링 : 중복을 제거하고 가독성을 향상시킵니다.


이제 "코드 위의 3-4 레이어"에 대한 귀하의 요점을 다루기 위해 이는 개발 프로세스가 민첩 할 때가 아니라 전통적인 (폭포와 같은) 프로세스에서 사실입니다. 그리고 애자일은 TDD가 시작되는 세상입니다. TDD는 eXtreme Programming 의 초석입니다 .

애자일은 벽에 얽매이지 않는 요구 사항 문서가 아닌 직접적인 커뮤니케이션에 관한 것입니다.


8

나는 모두 단위 테스트에 관심이 있지만 때때로 이러한 형태의 테스트 우선 개발이 정말 유익한 지 궁금합니다.

이와 같은 작고 사소한 테스트는 코드베이스의 "탄광의 카나리아"가 될 수 있으며 너무 늦기 전에 위험을 경고합니다. 사소한 테스트는 상호 작용을 올바르게 수행하는 데 도움이되므로 계속 유지하는 데 유용합니다.

예를 들어, 익숙하지 않은 API를 사용하는 방법을 조사하기 위해 마련된 사소한 테스트를 생각해보십시오. 해당 테스트가 API를 "실제로"사용하는 코드에서 수행하는 작업과 관련이있는 경우 해당 테스트를 계속 유지하는 것이 유용합니다. API가 새 버전을 출시하고 업그레이드해야하는 경우. 이제 API가 회귀를 포착하는 데 사용할 수있는 실행 가능한 형식으로 기록되는 방식에 대한 가정이 있습니다.

... [I] 실제 프로세스에서는 코드 (비즈니스 요청, 요구 사항 문서, 아키텍처 문서) 위에 3-4 개의 레이어가 있으며, 여기서 실제 정의 된 비즈니스 규칙 (할인 가격은 가격-할인)이 잘못 정의 될 수 있습니다. 그럴 경우 단위 테스트는 아무 의미가 없습니다.

테스트를 작성하지 않고 수년 동안 코딩을 해왔다면 가치가 있다는 것이 즉시 분명하지 않을 수 있습니다. 그러나 가장 좋은 작업 방법이 "일찍 릴리스, 자주 릴리스"또는 "민첩한"방식으로 신속하고 지속적으로 배포 할 수있는 능력을 원하는 경우 테스트는 확실히 의미가 있습니다. 이를 수행하는 유일한 방법은 테스트를 통해 코드에 대한 모든 변경 사항을 합법화하는 것입니다. 테스트가 아무리 작더라도 일단 그린 테스트 스위트가 있으면 이론적으로 배포 할 수 있습니다. "지속적 생산"및 "영구 베타"를 참조하십시오.

이러한 사고 방식을 갖기 위해 "먼저 테스트"할 필요는 없지만 일반적으로 그 목표에 도달하는 가장 효율적인 방법입니다. TDD를 수행 할 때 2 ~ 3 분의 작은 Red Green 리 팩터주기에 자신을 고정합니다. 어느 시점에서도 멈추고 떠날 수 없으며 디버깅하고 다시 조립하는 데 한 시간이 걸리는 완전한 혼란을 겪을 수 없습니다.

또한 단위 테스트는 또 다른 실패 지점입니다 ...

성공적인 테스트는 시스템의 오류를 보여주는 테스트입니다. 실패한 테스트는 테스트 논리 또는 시스템 논리의 오류를 경고합니다. 테스트의 목표는 코드를 깨뜨 리거나 하나의 시나리오가 작동 함을 증명하는 것입니다.

당신이있는 거 쓰기 테스트는 경우 코드, 당신은 순서대로 테스트가 진정으로 작동하는지 볼 수 있기 때문에 "나쁜"입니다 테스트를 작성하는 위험을 실행, 당신은 그것을 모두 파손 및 작업을 볼 필요가있다. 코드 다음에 테스트를 작성할 때 이는 "함정을 풀고"코드에 버그를 도입하여 테스트 실패를 확인해야 함을 의미합니다. 대부분의 개발자는 이에 대해 불안 할뿐만 아니라 시간 낭비라고 주장합니다.

여기서 우리는 무엇을 얻습니까?

이런 식으로 일을하면 확실히 이점이 있습니다. Michael Feathers는 "레거시 코드"를 "테스트되지 않은 코드"로 정의합니다. 이 접근 방식을 사용하면 코드베이스에 대한 모든 변경 사항을 합법화합니다. 테스트를 사용하지 않는 것보다 더 엄격하지만, 대규모 코드베이스를 유지하는 경우 그 자체로 가치가 있습니다.

Feathers와 관련하여 확인해야 할 두 가지 훌륭한 리소스가 있습니다.

이 두 가지 모두 이러한 유형의 관행과 원칙을 "그린 필드"가 아닌 프로젝트에 적용하는 방법을 설명합니다. 밀접하게 결합 된 구성 요소, 고정 된 종속성 및 반드시 제어 할 수없는 항목에 대한 테스트를 작성하는 기술을 제공합니다. "이음새"를 찾고 그 주위를 테스트하는 것이 전부입니다.

[I] 할인 가격이 잘못된 경우에도 테스트 팀은 문제를 발견 할 것입니다. 단위 테스트로 작업을 어떻게 저장 했나요?

이런 습관은 투자와 같습니다. 반품은 즉시 이루어지지 않습니다. 시간이 지남에 따라 축적됩니다. 테스트를하지 않는 것에 대한 대안은 본질적으로 회귀를 포착하거나 통합 오류에 대한 두려움없이 코드를 도입하거나 설계 결정을 주도 할 수없는 빚을지고 있습니다. 아름다움은 코드베이스에 도입 된 모든 변경 사항을 합법화한다는 것입니다.

내가 여기서 무엇을 놓치고 있습니까? 지금까지 TDD를 유용하게 받아들이는 데 어려움을 겪고 있으므로 TDD를 사랑하도록 가르쳐주세요. 나도 원한다. 왜냐하면 나도 진보적이기를 원하기 때문이다. 그러나 그것은 나에게 말이되지 않는다.

나는 그것을 전문적인 책임으로 본다. 노력하는 것이 이상적입니다. 그러나 따라 가기가 매우 어렵고 지루합니다. 그것에 관심이 있고 테스트되지 않은 코드를 생성해서는 안된다고 생각한다면, 좋은 테스트 습관을 배울 의지력을 찾을 수있을 것입니다. 내가 지금 많이하는 한 가지는 (다른 사람들과 마찬가지로) 테스트없이 코드를 작성하고 그것을 버리는 규율을 갖는 시간입니다. 이것은 낭비적인 것처럼 보일 수 있지만 실제로는 아닙니다. 그 운동으로 회사의 물리적 재료가 드는 것과는 다릅니다. 문제를 이해하고 더 높은 품질과 테스트 가능한 방식으로 코드를 작성하는 데 도움이되었습니다.

내 조언은 궁극적으로 당신이 정말로 그것을 잘하고 싶은 욕망이 없다면 전혀하지 말라는 것입니다. 유지되지 않거나 잘 수행되지 않는 불량한 테스트는 테스트가없는 것보다 더 나쁠 수 있습니다. 혼자서 배우는 것은 어렵고 아마 좋아하지 않을 것입니다.하지만 그렇게하고 싶은 욕구가 없거나 충분한 가치를 볼 수 없다면 배우는 것은 거의 불가능할 것입니다. 시간 투자를 보증합니다.

두 사람은 테스트가 사양을 적용하는 데 도움이된다고 계속 언급했습니다. 사양도 틀렸다는 것은 제 경험이었습니다.

개발자의 키보드는 고무가 도로와 만나는 곳입니다. 사양이 잘못되어 깃발을 올리지 않으면 비난받을 가능성이 높습니다. 또는 적어도 코드가 있습니다. 테스트와 관련된 규율과 엄격함은 준수하기 어렵습니다. 전혀 쉽지 않습니다. 연습, 많은 학습 및 많은 실수가 필요합니다. 그러나 결국 그것은 갚습니다. 빠르게 진행되고 빠르게 변화하는 프로젝트에서는 속도가 느려지더라도 밤에 잠을 잘 수있는 유일한 방법입니다.

여기서 고려해야 할 또 다른 사항은 테스트와 근본적으로 동일한 기술이 과거에 작동하는 것으로 입증되었다는 것입니다. "클린 룸"과 "계약 별 설계"는 모두 동일한 유형의 "메타"코드 구조를 생성하는 경향이 있습니다. 테스트는 다른 지점에서 수행하고 적용합니다. 이러한 기술 중 어느 것도 은색 총알이 아니며 엄격함으로 인해 출시 시간 측면에서 제공 할 수있는 기능의 범위에서 궁극적으로 비용이 발생합니다. 그러나 그것은 그것이 무엇에 관한 것이 아닙니다. 당신이 제공하는 것을 유지할 수 있다는 것입니다. 그리고 그것은 대부분의 프로젝트에서 매우 중요합니다.


7

단위 테스트는 이중 입력 장부 보관과 매우 유사합니다. 동일한 내용 (비즈니스 규칙)을 두 가지 완전히 다른 방식 (프로덕션 코드의 프로그래밍 된 규칙과 테스트의 단순하고 대표적인 예)으로 설명합니다. 둘 다 동일한 실수 를 할 가능성은 거의 없으므로 둘 다 서로 동의하면 틀릴 가능성이 거의 없습니다.

테스트가 노력의 가치가있는 방법은 무엇입니까? 적어도 테스트 주도 개발을 할 때 적어도 네 가지 방법으로 경험했습니다.

  • 잘 분리 된 디자인을 만드는 데 도움이됩니다. 잘 분리 된 단위 테스트 코드 만 가능합니다.
  • 완료시기를 결정하는 데 도움이됩니다. 테스트에서 필요한 동작을 지정하는 것은 실제로 필요하지 않은 기능을 빌드하지 않고 기능이 완료되는시기를 결정하는 데 도움이됩니다.
  • 리팩토링을위한 안전망을 제공하여 코드를 훨씬 더 쉽게 변경할 수 있습니다. 과
  • 디버깅 시간을 많이 절약 할 수 있습니다. 이는 엄청난 비용을 초래합니다 (전통적으로 개발자가 디버깅 시간의 최대 80 %를 소비한다고 추정했습니다).

5

대부분의 단위 테스트, 테스트 가정. 이 경우 할인 가격은 가격에서 할인을 뺀 값이어야합니다. 귀하의 가정이 잘못 되었다면 귀하의 코드도 잘못되었을 것입니다. 그리고 어리석은 실수를하면 테스트가 실패하고 바로 잡을 것입니다.

규칙이 변경되면 테스트가 실패하고 이는 좋은 것입니다. 따라서이 경우에도 테스트를 변경해야합니다.

일반적으로 테스트가 즉시 실패하면 (그리고 테스트 우선 설계를 사용하지 않는 경우) 테스트 또는 코드가 잘못된 것입니다 (또는 나쁜 하루를 보내고있는 경우 둘 다). 상식 (그리고 사양에 따라)을 사용하여 문제가되는 코드를 수정하고 테스트를 다시 실행합니다.

Jason이 말했듯이 테스트는 보안입니다. 그리고 예, 때로는 잘못된 테스트로 인해 추가 작업을 도입합니다. 그러나 대부분의 경우 시간을 크게 절약 할 수 있습니다. (그리고 시험을 통과 한 사람을 처벌 할 수있는 완벽한 기회가 있습니다 (우리는 고무 치킨에 대해 이야기하고 있습니다)).


4

가능한 모든 것을 테스트하십시오. 미터를 피트로 변환하는 것을 잊는 것과 같은 사소한 실수조차도 매우 비싼 부작용을 일으킬 수 있습니다. 테스트를 작성하고, 확인할 코드를 작성하고, 통과하고, 계속 진행하십시오. 미래의 어느 시점에서 누군가가 할인 코드를 변경할 수 있다는 것을 누가 알 수 있습니다. 테스트는 문제를 감지 할 수 있습니다.


그것은 내 생각을 다루지 않습니다. 나는 TDD의 기본적인 만트라를 이해한다 ... 나는 이익이 보이지 않는다.
FlySwat

4

단위 테스트와 프로덕션 코드가 공생 관계를 가지고 있다고 생각합니다. 간단히 말해, 하나는 다른 하나를 테스트합니다. 그리고 둘 다 개발자를 테스트합니다.


3

결함이 개발주기 동안 지속됨에 따라 결함 수정 비용이 기하 급수적으로 증가합니다. 예, 테스트 팀은 결함을 포착 할 수 있지만 (보통) 단위 테스트가 실패한 경우보다 해당 지점에서 결함을 격리하고 수정하는 데 더 많은 작업이 필요하며, 다음과 같은 경우 수정하는 동안 다른 결함을 도입하는 것이 더 쉽습니다. 실행할 단위 테스트가 없습니다.

그것은 일반적으로 사소한 예제보다 더 쉽게 볼 수 있습니다 ... 그리고 사소한 예제를 사용하면 어떻게 든 단위 테스트를 엉망으로 만들면 그것을 검토하는 사람이 테스트에서 오류 또는 코드의 오류를 잡을 것입니다. 양자 모두. (검토 중입니다. 맞습니까?) tvanfosson이 지적했듯이 단위 테스트는 SQA 계획의 일부일뿐입니다.

어떤 의미에서 단위 테스트는 보험입니다. 그들은 당신이 모든 결함을 잡을 것이라는 보장이 없으며 때때로 당신이 그들에게 많은 자원을 소비하는 것처럼 보일 수 있지만 그들이 수정할 수있는 결함을 포착하면 훨씬 덜 소비하게 될 것입니다. 테스트가 전혀없고 모든 결함을 다운 스트림으로 수정해야하는 경우보다


3

나는 당신의 요점을 알지만 분명히 과장되어 있습니다.

당신의 주장은 기본적으로 : 테스트는 실패를 가져온다. 따라서 테스트는 시간 낭비입니다.

어떤 경우에는 사실 일 수 있지만 대다수는 아닙니다.

TDD는 다음을 가정합니다. 더 많은 테스트 = 더 적은 실패.

테스트는 실패 지점을 도입하는 것보다 포착 할 가능성더 높습니다 .


1

여기에 더 많은 자동화가 도움이 될 수 있습니다! 예, 단위 테스트를 작성하는 것은 많은 작업이 될 수 있으므로 몇 가지 도구를 사용하여 도움을 받으십시오. .Net을 사용하는 경우 Microsoft의 Pex와 같은 것을 살펴보십시오. 코드를 검사하여 자동으로 단위 테스트 제품군을 생성합니다. 코드를 통해 모든 경로를 다루려고 노력하면서 좋은 범위를 제공하는 테스트가 나옵니다.

물론, 당신의 코드를 보는 것만으로는 당신이 실제로 무엇을하려고했는지 알 수 없기 때문에 그것이 옳은지 아닌지 알 수 없습니다. 그러나 흥미로운 테스트 케이스를 생성하고이를 조사하여 예상대로 작동하는지 확인할 수 있습니다.

그런 다음 더 나아가 매개 변수화 된 단위 테스트를 작성하면 (실제로 계약이라고 생각할 수 있음) 특정 테스트 사례를 생성하고 이번에는 테스트의 주장이 실패하기 때문에 문제가 있는지 알 수 있습니다.


1

나는이 질문에 대한 좋은 답변 방법에 대해 조금 생각했고, 과학적 방법과 평행을 이루고 싶습니다. IMO, "어떻게 실험을 실험합니까?"라는 질문을 다시 표현할 수 있습니다.

실험은 물리적 우주에 대한 경험적 가정 (가설)을 확인합니다. 단위 테스트는 호출하는 코드의 상태 또는 동작에 대한 가정을 테스트합니다. 우리는 실험의 타당성에 대해 이야기 할 수 있지만 다른 많은 실험을 통해 무언가 적합하지 않다는 것을 알고 있기 때문입니다. 그것은 수렴 타당성경험적 증거를 모두 가지고 있지 않습니다 . 우리는 테스트 또는 유효성 검증 할 수있는 새로운 실험 디자인하지 않는 실험을 하지만, 우리는 디자인 수도 완전히 새로운 실험을 .

따라서 실험과 마찬가지로 단위 테스트 자체를 통과하는지 여부에 따라 단위 테스트의 유효성을 설명하지 않습니다. 다른 단위 테스트와 함께 테스트중인 시스템에 대한 가정을 설명합니다. 또한 실험과 마찬가지로 테스트 대상에서 가능한 한 많은 복잡성을 제거하려고합니다. "가능한 한 간단하지만 더 간단하지는 않습니다."

실험과는 달리 , 우리는 수렴 타당성 외에 테스트가 유효한지 확인하기위한 속임수를 가지고 있습니다. 우리는 테스트에 의해 포착되어야하는 버그를 영리하게 소개하고 테스트가 실제로 실패하는지 확인할 수 있습니다. (실제 세계에서 그렇게 할 수만 있다면이 수렴 유효성에 훨씬 덜 의존 할 것입니다!)이를 수행하는보다 효율적인 방법은 테스트를 구현하기 전에 테스트가 실패하는 것을 확인하는 것입니다 ( Red, Green, Refactor 의 빨간색 단계). ).


1

테스트를 작성할 때 올바른 패러다임을 사용해야합니다.

  1. 먼저 테스트를 작성하여 시작하십시오.
  2. 시작하지 못하도록하십시오.
  3. 통과 시키십시오.
  4. 코드를 체크인하기 전에 코드 검토 (테스트를 검토해야합니다.)

항상 확신 할 수는 없지만 전반적인 테스트를 개선합니다.


0

코드를 테스트하지 않더라도 사용자가 프로덕션 환경에서 테스트 할 것입니다. 사용자는 소프트웨어를 충돌시키고 중요하지 않은 오류를 찾는 데 매우 창의적입니다.

프로덕션에서 버그를 수정하는 것은 개발 단계에서 문제를 해결하는 것보다 훨씬 더 많은 비용이 듭니다. 부작용으로 고객의 이탈로 인해 수입을 잃게됩니다. 1 명의 화난 고객에 대해 11 명의 고객을 잃거나 얻지 못할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.