단위 테스트 안티 패턴 카탈로그
안티 패턴 : 실제 안티 패턴을 간단한 나쁜 습관, 나쁜 습관 또는 나쁜 생각과 공식적으로 구별하기 위해서는 적어도 두 가지 핵심 요소가 있어야합니다.
- 처음에는 유익한 것처럼 보이지만 궁극적으로는 유익한 결과보다 더 나쁜 결과를 초래하는 일부 반복 된 행동 패턴, 과정 또는 구조
- 명확하게 문서화되고 실제 실무에서 입증되고 반복 가능한 리팩토링 솔루션.
"야생에서"한 번 너무 많이 본 TDD 반 패턴에 투표하십시오.
James Carr의 블로그 게시물 및 testdrivendevelopment yahoogroup 관련 토론
당신이 '이름이없는'것을 찾았다면 .. 안티 패턴 당 하나의 게시물로 투표를 통해 무언가를 계산하십시오.
저의 관심은 가까운 장래에 도시락 회의에서 그들을 토론 할 수 있도록 상위 N 개 부분 집합을 찾는 것입니다.
2 급 시민 – 테스트 코드는 프로덕션 코드만큼 리팩토링되지 않아 많은 중복 코드가 포함되어있어 테스트를 유지하기가 어렵습니다.
자유 승차 / 피기 백 -제임스 카 (James Carr), 팀 오 팅거 (Tim Ottinger) 다른 / 특별한 특징 / 기능
을 테스트하기 위해 새로운 테스트 케이스 방법을 작성하는 대신 , 새로운 주장 (및 해당 조치, 즉 AAA의 Act step)이 기존 테스트 케이스를 따라 진행됩니다. .
행복한 길
테스트는 경계와 예외를 테스트하지 않고 올바른 경로 (예상 결과)를 유지합니다.
지역의 영웅
실행하기 위해 작성된 개발 환경에 특정한 것에 의존하는 테스트 케이스. 결과는 개발 상자에서 테스트를 통과했지만 다른 곳에서 실행하려고하면 실패합니다.
숨겨진 의존성
로컬 히어로와 밀접한 관련이 있으며, 테스트를 실행하기 전에 일부 기존 데이터를 채워야하는 단위 테스트입니다. 해당 데이터가 채워지지 않은 경우 테스트가 실패하고 개발자에게 원하는 것이 무엇인지 또는 왜… 어떻게 사용했는지에 대한 정보를 찾기 위해 에이커 코드를 파헤 치게됩니다.
안타깝게도 특정 프로덕션 시스템에서 지속적으로 동기화되지 않는 다양한 .ini 파일에 의존하는 고대 .dll을 사용하여 너무 많은 시간을 슬프게 보았습니다.이 dll을 담당하는 세 명의 개발자와의 광범위한 협의없이 컴퓨터에서 현존하는 것은 아닙니다. 한숨.
체인 갱
특정 순서로 실행해야하는 몇 가지 테스트, 즉 한 테스트는 시스템의 글로벌 상태 (전역 변수, 데이터베이스의 데이터)를 변경하고 다음 테스트는 이에 따라 달라집니다.
당신은 종종 데이터베이스 테스트에서 이것을 볼 수 있습니다. teardown()
테스트 는에서 롤백하는 대신 데이터베이스에 변경 사항을 커밋합니다. 또 다른 일반적인 원인은 전역 상태에 대한 변경 사항이 테스트에 실패한 경우 정리할 수있는 try / finally 블록으로 래핑되지 않기 때문입니다.
조롱
때로는 조롱이 좋고 편리 할 수 있습니다. 그러나 때때로 개발자는 테스트를 거치지 않은 것을 조롱하려는 노력으로 자신을 잃을 수 있습니다. 이 경우, 단위 테스트에는 테스트 대상 시스템이 전혀 테스트되지 않는 모의, 스터브 및 / 또는 가짜가 너무 많이 포함되어 있으며 모의에서 반환 된 데이터는 테스트 대상입니다.
출처 : James Carr의 게시물.
사일런트 캐처 -켈리?
예외가 발생하면 통과하는 테스트입니다. 실제로 발생하는 예외가 개발자가 의도 한 것과 다른 경우에도 마찬가지입니다.
또한보십시오 : 비밀 캐처
[Test]
[ExpectedException(typeof(Exception))]
public void ItShouldThrowDivideByZeroException()
{
// some code that throws another exception yet passes the test
}
Inspector
100 % 코드 적용 범위를 달성하기 위해 캡슐화를 위반하는 유닛 테스트이지만 리팩토링 시도가 기존 테스트를 중단하고 변경 사항이 유닛에 반영되도록 오브젝트에서 발생하는 일에 대해 너무 많이 알고 있습니다. 테스트.
'내가 어떻게 ... 그들이 공개하지 않고 내 멤버 변수를 테스트 할 단지 단위 테스트?'
과도한 설정 -James Carr
테스트를 시작하기 위해 대규모 설정이 필요한 테스트입니다. 때로는 수백 줄의 코드를 사용하여 한 번의 테스트를 위해 환경을 준비하는 데 여러 개체가 관련되어 있으므로 모든 설정의 "노이즈"로 인해 테스트 대상을 실제로 확인하기가 어려울 수 있습니다. (Src : James Carr의 포스트 )
항문 프로브
Java의 setAccessible (true)을 사용하여 개인 필드를 읽 거나 보호 된 필드 / 메서드에 액세스하도록 클래스를 확장하거나 액세스하려면 특정 패키지에 테스트를 배치해야하는 등 미친, 불법 또는 건강에 해로운 방법을 사용해야 하는 테스트 글로벌 필드 / 메소드 패키지.
이 패턴이 표시되면 테스트중인 클래스가 너무 많은 데이터 숨기기를 사용합니다.
이것과 The Inspector의 차이점은 테스트중인 클래스가 테스트해야 할 것조차 숨기려고한다는 것입니다. 따라서 목표는 100 % 테스트 범위를 달성하는 것이 아니라 어떤 것도 테스트 할 수있는 것입니다. 개인 필드 만 있고, run()
인수가없고, getter가없는 클래스를 생각해보십시오 . 규칙을 어 기지 않고이를 테스트 할 방법이 없습니다.
Michael Borgwardt의 코멘트 : 이것은 실제로 테스트 반 패턴이 아니며, 테스트중인 코드의 결함을 다루는 실용주의입니다. 물론 이러한 결함을 수정하는 것이 좋지만 타사 라이브러리의 경우에는 불가능할 수 있습니다.
Aaron Digulla : 동의합니다. 이 항목은 "JUnit HOWTO"위키에 더 적합하고 반 패턴은 아닙니다. 코멘트?
이름없는 시험 -Nick Pellow
버그 추적기에서 특정 버그를 재현하기 위해 추가되는 테스트로 저자는 자신의 이름을 보증하지 않는다고 생각합니다. 기존의 부족한 테스트를 강화하는 대신 testForBUG123이라는 새로운 테스트가 생성됩니다.
2 년 후 해당 테스트가 실패하면 먼저 버그 추적기에서 BUG-123을 찾아 테스트의 의도를 파악해야합니다.
느린 찌르기
A unit test that runs incredibly slow. When developers kick it off, they have time to go to the bathroom, grab a smoke, or worse, kick the test off before they go home at the end of the day. (Src: James Carr's post)
a.k.a. the tests that won't get run as frequently as they should
The Butterfly
You have to test something which contains data that changes all the time, like a structure which contains the current date, and there is no way to nail the result down to a fixed value. The ugly part is that you don't care about this value at all. It just makes your test more complicated without adding any value.
The bat of its wing can cause a hurricane on the other side of the world. -- Edward Lorenz, The Butterfly Effect
The Flickering Test (Source : Romilly Cocking)
A test which just occasionally fails, not at specific times, and is generally due to race conditions within the test. Typically occurs when testing something that is asynchronous, such as JMS.
Possibly a super set to the 'Wait and See' anti-pattern and 'The Sleeper' anti-pattern.
The build failed, oh well, just run the build again. -- Anonymous Developer
Wait and See
A test that runs some set up code and then needs to 'wait' a specific amount of time before it can 'see' if the code under test functioned as expected. A testMethod that uses Thread.sleep() or equivalent is most certainly a "Wait and See" test.
Typically, you may see this if the test is testing code which generates an event external to the system such as an email, an http request or writes a file to disk.
Such a test may also be a Local Hero since it will FAIL when run on a slower box or an overloaded CI server.
The Wait and See anti-pattern is not to be confused with The Sleeper.
Inappropriately Shared Fixture -- Tim Ottinger
Several test cases in the test fixture do not even use or need the setup / teardown. Partly due to developer inertia to create a new test fixture... easier to just add one more test case to the pile
The Giant
A unit test that, although it is validly testing the object under test, can span thousands of lines and contain many many test cases. This can be an indicator that the system under tests is a God Object (James Carr's post).
A sure sign for this one is a test that spans more than a a few lines of code. Often, the test is so complicated that it starts to contain bugs of its own or flaky behavior.
I'll believe it when I see some flashing GUIs
An unhealthy fixation/obsession with testing the app via its GUI 'just like a real user'
Testing business rules through the GUI is a terrible form of coupling. If you write thousands of tests through the GUI, and then change your GUI, thousands of tests break.
Rather, test only GUI things through the GUI, and couple the GUI to a dummy system instead of the real system, when you run those tests. Test business rules through an API that doesn't involve the GUI. -- Bob Martin
“You must understand that seeing is believing, but also know that believing is seeing.” -- Denis Waitley
The Sleeper, aka Mount Vesuvius -- Nick Pellow
A test that is destined to FAIL at some specific time and date in the future. This often is caused by incorrect bounds checking when testing code which uses a Date or Calendar object. Sometimes, the test may fail if run at a very specific time of day, such as midnight.
'The Sleeper' is not to be confused with the 'Wait And See' anti-pattern.
That code will have been replaced long before the year 2000 -- Many developers in 1960
The Dead Tree
A test which where a stub was created, but the test wasn't actually written.
I have actually seen this in our production code:
class TD_SomeClass {
public void testAdd() {
assertEquals(1+1, 2);
}
}
I don't even know what to think about that.
got bit by this today:
Wet Floor:
The test creates data that is persisted somewhere, but the test does not clean up when finished. This causes tests (the same test, or possibly other tests) to fail on subsequent test runs.
In our case, the test left a file lying around in the "temp" dir, with permissions from the user that ran the test the first time. When a different user tried to test on the same machine: boom. In the comments on James Carr's site, Joakim Ohlrogge referred to this as the "Sloppy Worker", and it was part of the inspiration for "Generous Leftovers". I like my name for it better (less insulting, more familiar).
The Cuckoo -- Frank Carver
A unit test which sits in a test case with several others, and enjoys the same (potentially lengthy) setup process as the other tests in the test case, but then discards some or all of the artifacts from the setup and creates its own.
Advanced Symptom of : Inappropriately Shared Fixture
The Secret Catcher -- Frank Carver
A test that at first glance appears to be doing no testing, due to absence of assertions. But "The devil is in the details".. the test is really relying on an exception to be thrown and expecting the testing framework to capture the exception and report it to the user as a failure.
[Test]
public void ShouldNotThrow()
{
DoSomethingThatShouldNotThrowAnException();
}
The Environmental Vandal
A 'unit' test which for various 'requirements' starts spilling out into its environment, using and setting environment variables / ports. Running two of these tests simultaneously will cause 'unavailable port' exceptions etc.
These tests will be intermittent, and leave developers saying things like 'just run it again'.
One solution Ive seen is to randomly select a port number to use. This reduces the possibility of a conflict, but clearly doesnt solve the problem. So if you can, always mock the code so that it doesn't actually allocate the unsharable resource.
The Turing Test
A testcase automagically generated by some expensive tool that has many, many asserts gleaned from the class under test using some too-clever-by-half data flow analysis. Lulls developers into a false sense of confidence that their code is well tested, absolving them from the responsibility of designing and maintaining high quality tests. If the machine can write the tests for you, why can't it pull its finger out and write the app itself!
Hello stupid. -- World's smartest computer to new apprentice (from an old Amiga comic).
The Forty Foot Pole Test
Afraid of getting too close to the class they are trying to test, these tests act at a distance, separated by countless layers of abstraction and thousands of lines of code from the logic they are checking. As such they are extremely brittle, and susceptible to all sorts of side-effects that happen on the epic journey to and from the class of interest.
Doppelgänger
In order to test something, you have to copy parts of the code under test into a new class with the same name and package and you have to use classpath magic or a custom classloader to make sure it is visible first (so your copy is picked up).
This pattern indicates an unhealthy amount of hidden dependencies which you can't control from a test.
I looked at his face ... my face! It was like a mirror but made my blood freeze.
The Mother Hen -- Frank Carver
A common setup which does far more than the actual test cases need. For example creating all sorts of complex data structures populated with apparently important and unique values when the tests only assert for presence or absence of something.
Advanced Symptom of: Inappropriately Shared Fixture
I don't know what it does ... I'm adding it anyway, just in case. -- Anonymous Developer
The Test It All
I can't believe this hasn't been mentioned till now, but tests should not break the Single Responsibility Principle.
I have come across this so many times, tests that break this rule are by definition a nightmare to maintain.
Line hitter
On the first look tests covers everything and code coverage tools confirms it with 100%, but in reality tests only hit code without any output analyses.
참고URL : https://stackoverflow.com/questions/333682/unit-testing-anti-patterns-catalogue
'Programming' 카테고리의 다른 글
데이터베이스에 대한 모든 연결을 종료하는 스크립트 (RESTTEDTED_USER ROLLBACK 이상) (0) | 2020.05.06 |
---|---|
Angular 2 Typescript 앱에서 moment.js 라이브러리를 사용하는 방법은 무엇입니까? (0) | 2020.05.06 |
EditText가 비어 있는지 확인하십시오. (0) | 2020.05.06 |
numpy : 배열에서 고유 한 값에 대한 가장 효율적인 빈도 수 (0) | 2020.05.06 |
socket.io에 대한 초보자 초보자 자습서? (0) | 2020.05.06 |