단위 테스트 안티 패턴 카탈로그


203

안티 패턴 : 실제 안티 패턴을 간단한 나쁜 습관, 나쁜 습관 또는 나쁜 생각과 공식적으로 구별하기 위해서는 적어도 두 가지 핵심 요소가 있어야합니다.

  • 처음에는 유익한 것처럼 보이지만 궁극적으로는 유익한 결과보다 더 나쁜 결과를 초래하는 일부 반복 된 행동 패턴, 과정 또는 구조
  • 명확하게 문서화되고 실제 실무에서 입증되고 반복 가능한 리팩토링 솔루션.

"와일드에서"한 번 너무 많이 본 TDD 반 패턴에 투표하십시오.
James Carr의 블로그 게시물testdrivendevelopment yahoogroup 관련 토론

당신이 '이름이없는'것을 찾았다면 .. 안티 패턴 당 하나의 게시물로 투표를 통해 무언가를 계산하십시오.

나의 가장 큰 관심은 가까운 장래에 도시락 회의에서 그들을 토론 할 수 있도록 상위 N 개 부분 집합을 찾는 것입니다.


Aaron, 당신은이 모든 것 위에있는 것 같습니다.
Gishu

1
이것은 꽤 잘오고있다.. 고마워 n gals. 계속오고 .. 가장 유익한 SO 게시물 중 하나 IMHO
Gishu

2
+1이 스레드를 좋아합니다 !!! 그리고 이것들 대부분은 너무 사실적이고 우세합니다!
Chii

좋은 스레드, 왜이 커뮤니티 위키입니까 ???
Quibblesome

2
Coz 그것은 일종의 여론 조사입니다-당신은 담당자를 수확하고 싶지 않을 것입니다. coz는 가장 일반적인 유형의 안티 패턴을 게시했습니다.)
Gishu

답변:


70

2 급 시민 – 테스트 코드는 프로덕션 코드만큼 리팩터링되지 않아 중복 코드가 많이 포함되어있어 테스트를 유지하기가 어렵습니다.


67

무료 승차 / 피기 백 -제임스 카 (James Carr), 팀 오 팅거 (Tim Ottinger) 다른 / 특별한 특징 / 기능
을 테스트하기위한 새로운 테스트 케이스 방법을 작성하는 대신 , 새로운 주장 (및 해당 조치, 즉 AAA의 Act step)이 기존 테스트 케이스를 따라 진행됩니다. .


15
네, 제가 가장 좋아하는 것입니다. 나는 항상 그것을한다. 아 .. 잠깐만 ..이게 나쁜 일 이라고 했잖아 :-)
guidoism

1
이것이 안티 패턴인지 확실하지 않습니다. 모든 불변은 true가능한 모든 뮤 테이터 호출 이후에 있어야합니다 . 따라서 모든 불변 true이 테스트하는 뮤 테이터와 입력 데이터의 모든 조합 이후 인지 확인하고 싶을 것 입니다. 그러나 중복을 줄이고 현재 테스트 실패를 유발 하지 않는 모든 변수 를 확인 해야 합니다 . 그래서 당신은 그것들을 모두 검증 기능 에 넣고 모든 테스트에서 그것을 사용합니다. 코드가 변경되고 다른 불변이 추가됩니다. 물론 함수에도 넣었습니다. 그러나 그것은 자유 라이더입니다. checkInvariants()
Raedwald

2
@Raedwald-시간이 지남에 따라 테스트 이름이 더 이상 테스트 대상과 일치하지 않습니다. 또한 꼬임 테스트로 인해 스 래싱이 발생합니다. 고장이 정확한 고장 원인을 지적하지는 않습니다. 예를 들어,이 테스트의 정식 예제는 모든 정렬 단계의 불투명 한 수퍼 세트와 같은 것을 읽습니다 >> Act >> Assert A >> 더 행동하십시오 >> Assert B >> 더 행동하십시오 >> Assert C. 이제 A와 C가 이상이라면 고장난 경우 두 번의 테스트 실패가 표시됩니다. 위의 테스트에서는 하나만 볼 수 있습니다. 그런 다음 A를 수정하고 다음 실행에서 C가 손상되었다고 알려줍니다. 이제 5-6 개의 별개의 테스트가 서로 융합
되었다고

1
"테스트 이름은 더 이상 테스트 대상과 일치하지 않습니다"테스트가 원래 존재했던 사후 조건에 대해 이름이 지정된 경우에만 해당됩니다. method-name, 설정 상태 및 입력 데이터 (메소드 인수) 조합의 이름을 지정하면 문제가 없습니다.
Raedwald

"실패는 실패의 정확한 원인을 나타내지 않습니다" 어설 션 실패 는 실패 의 원인 을 나타냅니다 . 이를 위해서는 구현 세부 사항 (회귀 실패 디버깅, 일부 TDD 작업의 개발 상태에 대한 지식)을 자세히 조사해야합니다.
Raedwald

64

행복한 길

테스트는 경계와 예외를 테스트하지 않고 올바른 경로 (예상 결과)를 유지합니다.

JUnit 반 패턴


원인 : 시간 제약이나 과장된 게으른 과장. 리팩터링 솔루션 : 오 탐지를 제거하기 위해 더 많은 테스트를 작성하는 데 시간을 투자하십시오. 후자의 원인은 채찍이 필요합니다. :)
Spoike

59

지역의 영웅

실행하기 위해 작성된 개발 환경에 특정한 것에 의존하는 테스트 케이스. 결과는 개발 상자에서 테스트를 통과했지만 다른 곳에서 실행하려고하면 실패합니다.

숨겨진 의존성

로컬 히어로와 밀접한 관련이 있으며, 테스트를 실행하기 전에 일부 기존 데이터를 채워야하는 단위 테스트입니다. 해당 데이터가 채워지지 않은 경우 테스트가 실패하고 개발자에게 원하는 것이 무엇인지 또는 왜… 어떻게 사용했는지에 대한 정보를 찾기 위해 몇 에이커의 코드를 파고 들게 할 수 있습니다.


안타깝게도 특정 프로덕션 시스템에서 지속적으로 동기화되지 않는 다양한 .ini 파일에 의존하는 고대 .dll을 사용하여 너무 많은 시간을 슬프게 보았습니다.이 dll을 담당하는 세 명의 개발자와의 광범위한 협의없이 컴퓨터에서 현존하는 것은 아닙니다. 한숨.


WOMPC 개발자 약어의 좋은 예입니다. "내 PC에서 작동!" (일반적으로 다시 떨어져 테스터를 얻을 수있다.)
요리스 Timmermans

58

체인 갱

특정 순서로 실행해야하는 몇 가지 테스트, 즉 한 테스트는 시스템의 글로벌 상태 (전역 변수, 데이터베이스의 데이터)를 변경하고 다음 테스트는 이에 따라 달라집니다.

당신은 종종 데이터베이스 테스트에서 이것을 볼 수 있습니다. teardown()테스트 는에서 롤백하는 대신 데이터베이스에 변경 사항을 커밋합니다. 또 다른 일반적인 원인은 전역 상태에 대한 변경 사항이 테스트에 실패한 경우 정리할 수있는 try / finally 블록에 포함되지 않기 때문입니다.


이건 그냥 불쾌한 일입니다 .. 테스트는 독립적 인 개념이어야합니다. 그러나 나는 여러 곳에서 읽었습니다. '인기 TDD'가 엉망인 것 같습니다
Gishu

56

조롱
때로는 조롱이 좋고 편리 할 수 ​​있습니다. 그러나 때때로 개발자는 테스트를 거치지 않은 것을 조롱하려는 노력으로 자신을 잃을 수 있습니다. 이 경우, 단위 테스트에는 테스트 대상 시스템이 전혀 테스트되지 않은 모의, 스터브 및 / 또는 가짜가 너무 많이 포함되어 있으며 모의에서 반환 된 데이터가 테스트 대상입니다.

출처 : James Carr의 게시물.


2
나는 이것의 원인이 테스트중인 클래스가 너무 많은 의존성을 가지고 있다고 믿습니다. 리팩토링 된 대안은 격리 될 수있는 코드를 추출하는 것입니다.
Spoike

@ 스푸 이크; 실제로 클래스의 역할에 의존하는 계층 구조 인 경우 일부 레이어는 다른 레이어보다 더 많은 종속성을 갖는 경향이 있습니다.
krosenvold

최근 존경받는 블로그에서 모의 ​​저장소에서 모의 ​​엔티티 설정을 생성하는 것을 보았습니다. WTF? 먼저 실체를 인스턴스화하는 것이 어떻습니까? 내 자신의 구현이 NotImplementedExceptions를 던지는 모의 인터페이스로 인해 화상을 입었습니다.
Thomas Eyde

40

사일런트 캐처 -켈리?
실제로 예외가 발생하더라도 개발자가 의도 한 것과 다른 경우에도 예외가 발생하면 통과하는 테스트입니다.
또한보십시오 : 비밀 캐처

[Test]
[ExpectedException(typeof(Exception))]
public void ItShouldThrowDivideByZeroException()
{
   // some code that throws another exception yet passes the test
}

그것은 까다 롭고 위험합니다 (즉, 코드가 실행될 때마다 항상 폭발하는 코드를 테스트했다고 생각하게 만듭니다). 그렇기 때문에 예외 클래스와 메시지 내에서 고유 한 것에 대해 구체적으로 설명하려고합니다.
Joshua Cheek

34

Inspector
100 % 코드 커버리지를 달성하기 위해 캡슐화를 위반하는 유닛 테스트이지만 리팩토링 시도가 기존 테스트를 중단하고 변경 사항이 유닛에 반영 될 수 있도록 객체에서 발생하는 일에 대해 너무 많이 알고 있습니다. 테스트.


'내가 어떻게 ... 그들이 공개하지 않고 내 멤버 변수를 테스트 할 단지 단위 테스트?'


2
원인 : 화이트 박스 테스트에 대한 불신 한 의존. Pex on .NET과 같은 이러한 종류의 테스트를 생성하는 도구가 있습니다. 리팩토링 솔루션 : 대신 동작을 테스트하고 경계 값을 실제로 확인해야하는 경우 자동화 된 도구가 나머지를 생성하도록하십시오.
Spoike

1
Moq가 등장하기 전에 모의 필기를 위해 모의 프레임 워크를 포기해야했습니다. 테스트를 실제 구현에 연결하는 것이 너무 쉬워서 리팩토링을 불가능하게 만들었습니다. Moq가 아닌 다른 점을 말할 수는 없지만 이런 종류의 실수는 거의하지 않습니다.
Thomas Eyde

34

과도한 설정 -James Carr
테스트를 시작하기 위해 대규모 설정이 필요한 테스트입니다. 때로는 수백 줄의 코드를 사용하여 한 번의 테스트를 위해 환경을 준비하고 여러 개체가 관련되어 있으므로 모든 설정의 "노이즈"로 인해 테스트 대상을 실제로 확인하기가 어려울 수 있습니다. (Src : James Carr의 포스트 )


과도한 테스트 설정은 일반적으로 a) 잘못 구성된 코드 또는 b) 조롱이 불충분하다는 것을 이해합니다.
Topher Hunt

모든 상황이 다를 수 있습니다. 커플 링이 높을 수 있습니다. 그러나 일반적으로 시나리오의 각 공동 작업자를 지정 (모의 기대)하는 과잉 사양의 경우가 있습니다. 이렇게하면 테스트가 구현에 결합되어 부서지기 쉽습니다. 공동 작업자에 대한 호출이 테스트에 대한 부수적 인 세부 사항 인 경우 테스트에 포함되지 않아야합니다. 또한 테스트를 짧고 읽기 쉽게 유지하는 데 도움이됩니다.
Gishu

32

항문 프로브

Java의 setAccessible (true)을 사용하여 개인 필드를 읽 거나 보호 된 필드 / 메서드에 액세스하도록 클래스를 확장하거나 액세스하려면 특정 패키지에 테스트를 배치해야하는 등 미친, 불법 또는 건강에 해로운 방법을 사용해야 하는 테스트 글로벌 필드 / 메소드 패키지.

이 패턴이 표시되면 테스트중인 클래스가 너무 많은 데이터 숨기기를 사용합니다.

이것과 The Inspector의 차이점은 테스트중인 클래스가 테스트해야 할 것조차 숨기려고한다는 것입니다. 따라서 목표는 100 % 테스트 범위를 달성하는 것이 아니라 어떤 것도 테스트 할 수있는 것입니다. 개인 필드, run()인수가없고 getter가없는 메소드 만있는 클래스를 생각해보십시오 . 규칙을 어 기지 않고이를 테스트 할 방법이 없습니다.


Michael Borgwardt의 코멘트 : 이것은 실제로 테스트 반 패턴이 아니며, 테스트중인 코드의 결함을 다루는 실용주의입니다. 물론 이러한 결함을 수정하는 것이 좋지만 타사 라이브러리의 경우에는 불가능할 수 있습니다.

Aaron Digulla : 동의합니다. 어쩌면이 항목은 "JUnit HOWTO"위키에 더 적합하지만 반 패턴은 아닙니다. 코멘트?


인스펙터와 같지 않습니까?
Gishu

1
흠 ..이 줄 '테스트중인 클래스는 테스트해야 할 것조차 숨기려고합니다'는 클래스와 테스트 사이의 힘의 투쟁을 나타냅니다. 그것이 테스트되어야한다면 .. 어떻게 든 공개적으로 접근 할 수 있어야한다. 클래스 행동 / 인터페이스를 통해. 이것은 어떻게 든 캡슐화 위반 냄새
Gishu

2
npellow : Maven2를위한 플러그인이 있습니까?
Aaron Digulla

1
이것은 실제로 테스트 반 패턴이 아니며 테스트되는 코드의 결함을 처리하는 실용주의입니다. 물론 이러한 결함을 수정하는 것이 좋지만 타사 라이브러리의 경우에는 불가능할 수 있습니다.
Michael Borgwardt

1
IDK는 일종의 부작용이 있어야합니다. 부작용을 테스트했습니다. 타사 API 테스트에 대한 의미를 모르는 경우 테스트 할 수있는 코드를 자신의 코드로 포장 한 다음 타사 API에 대해 해당 코드를 통합 테스트해야한다고 주장합니다. 타사 코드를 단위 테스트하지 않습니다.
Joshua Cheek

26

이름없는 시험 -Nick Pellow

버그 추적기에서 특정 버그를 재현하기 위해 추가되는 테스트로 저자는 자신의 이름을 보증하지 않는다고 생각합니다. 기존의 부족한 테스트를 강화하는 대신 testForBUG123이라는 새로운 테스트가 생성됩니다.

2 년 후 해당 테스트가 실패하면 먼저 버그 추적기에서 BUG-123을 찾아 테스트의 의도를 파악해야합니다.


7
그렇습니다. "TestMethod"라는 테스트보다 약간 더 도움이되는 것
NikolaiDante

8
버그 트래커가 변경되지 않고 이전 트래커와 이슈 식별자를
잃어 버리지

25

느린 찌르기

엄청나게 느린 단위 테스트. 개발자가 일을 시작하면 화장실에 갈 시간, 연기를 피우거나 더 나쁜 날, 시험이 끝나기 전에 시험을 시작합니다. (Src : James Carr의 포스트 )

일명 자주 수행되지 않는 테스트


일부 테스트는 본질적으로 느리게 실행됩니다. 다른 것만 큼 자주 실행하지 않기로 결정한 경우 최소한 CI 서버에서 가능한 한 자주 실행되도록하십시오.
Chris Vest

이것은 명백한 질문이지만 이것을 해결하는 가장 일반적인 방법은 무엇입니까?
Topher Hunt

처음에는 유익한 것 같습니다.
Kev

1
@TopherHunt 일반적으로 테스트는 값 비싼 의존성 (예 : 파일 시스템, 데이터베이스)이 있기 때문에 속도가 느립니다. 트릭은 문제가 나타날 때까지 종속성을 분석 한 다음 종속성을 콜 스택 위로 올리는 것입니다. github.com/JoshCheek/fast_tests
Joshua Cheek

20

나비

현재 날짜가 포함 된 구조와 같이 항상 변경되는 데이터가 포함 된 무언가를 테스트해야하며 결과를 고정 된 값으로 축소 할 방법이 없습니다. 추악한 부분은이 값에 전혀 신경 쓰지 않는다는 것입니다. 값을 추가하지 않고 테스트를 더 복잡하게 만듭니다.

날개의 박쥐는 세계 반대편에 허리케인을 일으킬 수 있습니다. -에드워드 로렌츠, 나비 효과


반 패턴은 무엇입니까? 이와 같은 테스트는 어떤 모양입니까? 수정이 있습니까? System.DateTime.Now더 단순하거나 결정론적인 단위 테스트를 수행하는 것 외에 테스트와 같은 종속성을 제거 할 수있는 논쟁의 여지가 있습니까?
Merlyn Morgan-Graham

1
Java toString()에서 메소드를 겹쳐 쓰지 않는 오브젝트 를 호출 하는 것이 예입니다 . 메모리 주소에 따라 객체의 ID가 표시됩니다. 또는 toString()개체의 기본 키를 포함하며 테스트를 실행할 때마다 변경됩니다. 이를 수정하는 세 가지 방법이 있습니다. 1. 테스트중인 코드 변경, 2. regexp를 사용하여 테스트 결과의 가변 부분 제거 또는 강력한 도구를 사용하여 시스템 서비스를 덮어 써서 예측 가능한 결과를 리턴합니다.
Aaron Digulla

이 안티 패턴의 기본 원인은 테스트중인 코드가 테스트하는 데 많은 노력을 기울이지 않기 때문입니다. 따라서 개발자의 변덕은 다른 곳에서 문제를 일으키는 나비의 날개입니다.
Aaron Digulla

19

깜박임 테스트 (출처 : Romilly Cocking)

특정 시간이 아닌 때때로 실패하는 테스트이며 일반적으로 테스트 내의 경쟁 ​​조건으로 인한 것입니다. 일반적으로 JMS와 같이 비동기적인 것을 테스트 할 때 발생합니다.

아마도 ' 대기 및 참조 '안티 패턴 및 ' 슬리퍼 '안티 패턴으로 설정된 슈퍼 일 것 입니다.

빌드가 실패했습니다. 빌드를 다시 실행하십시오. -익명 개발자


@Stuart-이것이 "Car Stalled-Try Now!" videosift.com/video/... 라고도 할 수있는이 패턴은 그냥 "! 지금 시도", 또는 -는 "Flakey 테스트"
npellow

1
한 번은 적절한 배포를 보장하는 PRGN에 대한 테스트를 작성했습니다. 때때로 무작위로 실패합니다. 그림을 이동. :-)
Chris Vest

1
이것은 좋은 시험이 아닌가? 테스트가 실패하면 문제의 원인을 추적해야합니다. 9p에서 자정 사이에 실패한 테스트에 대해 누군가와 싸웠습니다. 그는 무작위 / 간헐적이라고 말했다. 결국 시간대를 다루는 버그로 추적되었습니다. 그림을 이동.
Trenton

@Christian Vest Hansen : 시드 할 수 없었습니까?
Andrew Grimm

@trenton 개발자가 무시하지 않고 추적하도록 귀찮게 할 수 있는지를 테스트하는 것은 좋은 시험일뿐입니다.
윌 셰퍼드

19

기다려 봐

일부 설정 코드를 실행 한 다음 테스트중인 코드가 예상대로 작동하는지 확인하려면 특정 시간 동안 '대기'해야합니다. Thread.sleep () 또는 이와 동등한 것을 사용하는 testMethod는 "Wait and See"테스트입니다.

일반적으로 테스트에서 전자 메일, http 요청 또는 파일을 디스크에 쓰는 등 시스템 외부의 이벤트를 생성하는 코드를 테스트하는 경우이 메시지가 표시 될 수 있습니다.

느린 테스트 또는 과부하 된 CI 서버에서 실행될 때 실패하므로 로컬 테스트 일 수도 있습니다 .

Wait and See 안티 패턴을 The Sleeper 와 혼동해서는 안됩니다 .


흠 .. 이런 식으로 사용합니다. 멀티 스레드 코드를 어떻게 테스트 할 수 있습니까?
Gishu

@Gishu, 당신은 정말로 동시에 실행되는 여러 스레드를 단위 테스트하고 싶습니까? run () 메소드가 단독으로 수행하는 모든 것을 단위 테스트하려고합니다. 이를 수행하는 쉬운 방법은 단위 테스트에서 start () 대신 run ()을 호출하는 것입니다.
npellow

@Gishu는 CountDownLatches, Semaphores, Conditions 등을 사용하여 스레드가 다음 레벨로 이동할 수있을 때 서로에게 알리도록합니다.
Chris Vest

예 : madcoderspeak.blogspot.com/2008/11/… Brew 버튼 evt. 관찰자는 간격을두고 폴링하고 변경된 이벤트를 발생시킵니다.이 경우 테스트 스레드가 종료되기 전에 폴링 스레드가 실행될 수 있도록 지연을 추가합니다.
Gishu

만화 링크가 끊어진 것 같습니다.
앤드류 그림

17

부적절하게 공유 된 픽스쳐 -Tim Ottinger
테스트 픽스처의 몇몇 테스트 케이스는 설정 / 해체를 사용하지 않거나 필요로하지 않습니다. 새로운 테스트 픽스처를 생성하는 개발자 관성 덕분에 ... 파일에 하나 이상의 테스트 케이스를 추가하기가 쉬움


1
또한 테스트중인 수업이 너무 많은 일을하려고 할 수도 있습니다.
Mike Two

16

거인

테스트중인 개체를 올바르게 테스트하고 있지만 수천 줄에 걸쳐 있고 많은 테스트 사례를 포함 할 수있는 단위 테스트입니다. 테스트중인 시스템이 God Object (James Carr의 게시물) 임을 나타내는 지표 일 수 있습니다 .

이것에 대한 확실한 신호는 몇 줄 이상의 코드에 걸친 테스트입니다. 종종 테스트는 너무 복잡하여 자체 또는 비정상적인 동작의 버그를 포함하기 시작합니다.


15

GUI가 깜빡 일 때 믿습니다.
'실제 사용자처럼'GUI를 통해 앱을 테스트하는 건강하지 못한 수정 / 강박 관념

GUI를 통한 비즈니스 규칙 테스트는 끔찍한 형태의 커플 링입니다. GUI를 통해 수천 개의 테스트를 작성한 다음 GUI를 변경하면 수천 개의 테스트가 중단됩니다.
오히려 GUI를 통해 GUI만을 테스트하고, 테스트를 실행할 때 GUI를 실제 시스템 대신 더미 시스템에 연결하십시오. GUI가 포함되지 않은 API를 통해 비즈니스 규칙을 테스트하십시오. -밥 마틴

"보는 것이 믿는다는 것을 이해해야하지만, 믿는 것이 보는 것을 알고 있어야합니다." - 데니스 웨이 틀리


1
깜박이는 GUI가 잘못되었다고 생각하면 GUI를 시작한 jUnit 테스트를 작성하고 계속하기 위해 사용자 상호 작용이 필요한 사람을 보았습니다. 나머지 테스트 스위트를 중단했습니다. 테스트 자동화를 위해 너무 많은!
Spoike

동의하지 않습니다. GUI 테스트는 어렵지만 오류의 원인이기도합니다. 테스트하지 않으면 게으르다.
Ray

3
여기서 중요한 것은 GUI를 테스트하지 말고 GUI를 통해서만 테스트해서는 안된다는 것입니다. GUI없이 'headless'테스트를 수행 할 수 있습니다. GUI를 가능한 한 얇게 유지하십시오. MVP를 사용하면 전혀 테스트하지 않아도됩니다. 항상 얇은 GUI 계층에서 버그가 발생하는 것을 발견하면 테스트로 덮으십시오. GUI '배선'오류는 일반적으로 해결하기가 더 쉽습니다 ...
Gishu

@Spoike : 안내 된 수동 테스트도 나쁘지 않으며 jUnit (또는 다른 단위 테스트 프레임 워크)을 사용하여 단위 테스트가 아닌 자동 테스트를 수행하지도 않습니다. 동일한 프로젝트에 배치하거나 단위 테스트처럼 취급해서는 안됩니다 (예 : 지속적으로 또는 모든 빌드 후).
Merlyn Morgan-Graham

1
@ MerlynMorgan-Graham 동의합니다. GUI를 테스트해서는 안된다는 의미는 아닙니다. 안내 된 수동 테스트와 자동 테스트를 혼합해도 괜찮다는 팀원들의 확신은 저를 방해했습니다. 나는 나중에 TDD에 익숙하지 않은 모든 사람들이 그것을 사용하지 못하게하는 훌륭한 방법이라는 것을 알았습니다. TDD 프로세스를 따르고 싶다면 기능 테스트 (휘발성)와 단위 테스트 (안정되어 있어야 함)를 혼합하는 것이 좋지 않습니다.
Spoike

14

슬리퍼, 일명 베수 비우스 -닉 펠로우

미래의 특정 시간과 날짜에 실패 할 예정인 테스트. Date 또는 Calendar 객체를 사용하는 코드를 테스트 할 때 잘못된 범위 검사로 인해 종종 발생합니다. 때로는 자정과 같이 매우 특정한 시간에 실행하면 테스트가 실패 할 수 있습니다.

'잠자는 자'는 ' 대기 및 참조 '안티 패턴 과 혼동되어서는 안됩니다 .

이 코드는 2000 년 오래 전에 교체 되어 1960 년에 많은 개발자들이


나는 이것을 휴면 화산이라고 부릅니다.) .. 나는 당신이 무슨 말을하는지 알고 있습니다. 테스트를 중단합니다. 예를 들어 설명해 주시면됩니다.
Gishu

@Gishu-+1. 나는 똑같은 생각을하고 있었지만 둘 사이를 결정할 수 없었습니다. 나는이 좀 더 명확하게 제목을 업데이트)
npellow

11

죽은 나무

스텁이 작성되었지만 실제로 작성되지 않은 테스트입니다.

프로덕션 코드에서 실제로 이것을 보았습니다.

class TD_SomeClass {
  public void testAdd() {
    assertEquals(1+1, 2);
  }
}

나는 그것에 대해 어떻게 생각해야할지조차 모른다.


8
:)-프로세스 준수 백도어라고도합니다.
기후

1
우리는 최근에 반복적으로 리팩토링 된 테스트 및 테스트 대상 방법에서 이에 대한 예를 보았습니다. 몇 번의 반복 후에 테스트는 테스트 대상 메소드에 대한 호출이되었습니다. 그리고 메소드가 이제 void를 리턴했기 때문에 어설 션 할 어설 션이 없습니다. 따라서 기본적으로 테스트는 메소드가 예외를 throw하지 않았는지 확인하는 것입니다. 실제로 유용하거나 올바르게 수행했는지는 중요하지 않습니다. 코드를 검토 한 결과 "그래서 우리는 여기서 무엇을 테스트하고 있습니까?"
Marvo

11

오늘 이것에 조금 들었습니다.

습식 바닥 :
이 테스트는 어딘가에 지속되는 데이터를 생성하지만 완료되면 테스트가 정리되지 않습니다. 이로 인해 후속 테스트 실행 시 테스트 (동일한 테스트 또는 다른 테스트)가 실패 합니다.

우리의 경우, 테스트는 처음으로 테스트를 실행 한 사용자의 권한으로 "temp"디렉토리에 파일을 두었습니다. 다른 사용자가 동일한 머신에서 테스트를 시도한 경우 : 붐. James Carr 사이트에 대한 의견에서 Joakim Ohlrogge는 이것을 "느슨한 노동자"라고 언급했으며 "Generous Leftovers"에 대한 영감의 일부였습니다. 나는 내 이름이 더 좋다 (모욕이 적고 친숙하다).


젖은 바닥을 피하기 위해 junit의 임시 폴더 규칙을 사용할 수 있습니다.
DaveFar

이런 종류의 연속 통합 안티 패턴과 관련이 있습니다. CI에서 모든 개발자는 자신의 작업 공간과 리소스를 가져야하며 빌드 머신도 자체 환경이어야합니다. 그런 다음 권한 문제와 같은 것을 피하십시오 (또는 프로덕션 환경에서만 나타날 수 있도록 숨길 수도 있습니다)
Marvo

11

뻐꾸기 -프랭크 카버
( Frank Carver) 다른 여러 테스트 케이스에 앉아 테스트 케이스의 다른 테스트와 동일한 (잠재적으로 긴) 설정 프로세스를 즐기지 만 설정에서 아티팩트의 일부 또는 전부를 버리는 단위 테스트 그리고 자신을 만듭니다.
고급 증상 : 부적절한 공유 비품


10

The Secret Catcher -Frank Carver
어설 션이 없기 때문에 언뜻보기에 테스트를 수행하지 않는 것으로 보이는 테스트입니다. 그러나 "악마는 세부 사항에 있습니다."테스트는 실제로 예외를 처리하고 테스트 프레임 워크가 예외를 캡처하여 사용자에게 실패로보고 할 것을 기대하고 있습니다.

[Test]
public void ShouldNotThrow()
{
   DoSomethingThatShouldNotThrowAnException();
}

2
이것은 내 의견으로는 사실, 특히 회귀 테스트로서 유효한 테스트가 될 수 있습니다.
Ilja Preuß

죄송하지만 다시 Silent catcher와 혼동을 겪었습니다. 단위 테스트는 '이것이 작동해야합니다'라고 말하는 것이 아니라 테스트 대상에 대해 분명하게 진술해야합니다. 국가)
Gishu

1
이런 종류의 테스트에서는 적어도 예외를 잡아서 변수에 할당합니다. 그런 다음 null이 아니라고 주장합니다.
Thomas Eyde

4
일부 프레임 워크 Assert.DoesNotThrow(SomeDelegateType act)에는 이와 같은 경우에 특별히 사용할 수 있는 스타일 어설 션이 있습니다. 생성자가 null이 아닌 것을 반환 할 때 성공하지만 생성자가 throw하면 실패하는 테스트 사례보다 덜 중요합니다. 생성자는 null을 반환하지 않습니다. (참고 : 생성자가 null이 아닌 값을 반환하도록 보장 된 언어에만 적용됨)
Merlyn Morgan-Graham

10

환경 파괴자

환경 변수 / 포트를 사용하고 설정하여 다양한 '요구 사항'에 대한 '단위'테스트가 환경에 쏟아지기 시작합니다. 이 두 가지 테스트를 동시에 실행하면 '사용할 수없는 포트'예외 등이 발생합니다.

이러한 테스트는 간헐적이며 개발자가 '다시 실행'과 같은 말을하게합니다.

내가 본 한 가지 해결책은 사용할 포트 번호를 무작위로 선택하는 것입니다. 이렇게하면 충돌 가능성이 줄어들지 만 문제는 명확하게 해결되지 않습니다. 따라서 가능하면 항상 공유 할 수없는 리소스를 할당하지 않도록 코드를 조롱하십시오.


@gcrain .. 테스트는 결정 론적이어야합니다. IMO의 더 나은 접근 방법은 테스트 전과 후에 올바르게 사용할 수 있도록 테스트 및 정리에 '팀에서 잘 알려진'포트를 사용하는 것입니다.
Gishu

1
@gishu-문제는이 포트 사용을 처리 할 setup () 및 teardown () 메소드가 없다는 것이 아닙니다. 문제는 예를 들어 CI 서버를 실행하고 여러 버전의 테스트를 동시에 실행하여 동일한 하드 코딩 된 테스트 포트 번호를 사용하려고 시도하는 것입니다
gcrain

10

튜링 테스트

값 비싼 툴에 의해 자동으로 생성 된 테스트 케이스는 너무 많은 데이터 흐름 분석을 사용하여 테스트중인 클래스에서 수집 한 많은 어설 션이 있습니다. 개발자는 코드가 잘 테스트되었다는 잘못된 확신을 가지고 고품질 테스트를 설계하고 유지해야 할 책임이 없습니다. 기계가 테스트를 작성할 수 있다면 손가락을 잡아 당겨 앱 자체를 작성할 수없는 이유는 무엇입니까?

멍청 아 안녕 -세계에서 가장 똑똑한 컴퓨터 (구 Amiga 만화에서 새로운 견습생까지).


10

마흔 발 극 테스트

테스트하려는 클래스에 너무 가까워지는 것을 두려워하는이 테스트는 수많은 추상화 계층과 수천 개의 코드 라인으로 구분 된 거리에서 작동합니다. 따라서 그들은 매우 취하기 쉽고 관심있는 클래스를 오가는 서사시 여행에서 발생하는 모든 종류의 부작용에 취약합니다.


9

도펠 갱거

무언가를 테스트하려면 테스트 할 코드의 일부를 이름과 패키지가 같은 새 클래스로 복사해야하며 클래스 패스 매직이나 커스텀 클래스 로더를 사용하여 먼저 표시되도록해야합니다 (그래서 사본이 선택됩니다) 쪽으로).

이 패턴은 테스트에서 제어 할 수없는 건강에 해로운 양의 숨겨진 종속성을 나타냅니다.

나는 그의 얼굴을 보았습니다 ... 내 얼굴! 거울 같았지만 혈액이 얼어 붙었습니다.


7

Mother Hen -Frank Carver
실제 테스트 사례보다 훨씬 많은 공통 설정입니다. 예를 들어, 테스트가 무언가의 존재 유무를 주장 할 때 분명히 중요하고 고유 한 값으로 채워진 모든 종류의 복잡한 데이터 구조를 작성합니다.
고급 증상 : 부적절한 공유 비품

나는 그것이 무엇을하는지 모른다 ... 어쨌든 그것을 위해 그것을 추가하고있다. -익명 개발자


7

모두 테스트

나는 이것이 지금까지 언급되지 않았다고 믿을 수는 없지만 테스트가 단일 책임 원칙을 위반해서는 안됩니다 .

나는 여러 번이 문제를 겪어 왔고,이 규칙을 어기는 테스트는 정의상 유지하기에는 악몽이다.


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