2009-10-14 8 views
5

나는 단시간에 단위 테스트를 사용했지만, 파서, 수학, 복잡한 비즈니스 로직을 수행하는 등 상당한 양의 논리를 실제로 수행하는 클래스/메소드에만 유용하다고 생각하기 시작했습니다. 모든 좋은 후보자들 테스트를 위해, 의문의 여지가 없습니다. 다른 클래스의 객체 (대개 위임을 통해 작동하는 객체)에 대한 테스트를 사용하는 방법을 알아 내려고 정말 고심하고 있습니다.대부분 서비스 지향적 인 앱에 대한 유용한 단위 테스트를 작성하려면 어떻게해야합니까?

사례 : 현재 프로젝트는 많은 데이터베이스와 서비스를 조정합니다. 대부분의 클래스는 서비스 메소드의 모음이며, 대부분의 메소드는 몇 가지 기본 조건부 로직을 수행합니다 (for-each 루프). 그런 다음 다른 서비스를 호출합니다.

이와 같은 객체를 사용하면 모의 테스트가 실제로 실행 가능한 유일한 전략이기 때문에 필자는 그 중 일부에 대한 모의 작업을 충실히 수행했습니다. 그리고 정말, 정말 다음과 같은 이유로, 그것을 좋아하지 않아 :

  1. 행동이 내가 클래스 구현을 변경할 때마다 일을 중단하게 대한 기대를 지정하는 모의 객체를 사용하여, 변화의 종류가 아닌 경우에도 것과 해야지 단위 테스트에 차이를 만들어라. 내 생각에 단위 테스트는 "메소드가 A, B, C를 순서대로 수행해야 할 필요가 없다"라고 명시하지 않고 기능을 테스트해야합니다. 나는 시험이 마음에 든다. 왜냐하면 무언가가 깨지면 내가 알 수있는 자신감으로 물건을 바꿀 수 있기 때문에 자유롭기 때문이다. 그러나 mock은 엉덩이를 바꿀만큼 고통 스럽다.
  2. 의도 된 동작이 간단하다면 mock을 쓰는 것이 종종 클래스를 작성하는 것보다 더 효과적입니다.
  3. 내 테스트에서 모든 서비스와 구성 요소 개체의 완전히 다른 구현을 사용하기 때문에 결국 모든 내 테스트가 실제로 동작의 가장 기본적인 골격이라고 확인합니다. "if"및 "for"문 여전히 작동합니다. 지루한. 나는 그것들에 대해 걱정하지 않는다.

내 응용 프로그램의 핵심은 모든 조각이 함께 작동, 그래서 (그들은 분명 적절한있어 장소를 제외하고) 모두 단위 테스트를 죽겠다 대신 외부 통합 테스트로 이동 을 고려하고 어떻게 정말 - 열심히 가능성이 적은 케이스를 설정하고 적용 할 수는 있지만 실제로는 실행하는 것이므로 시스템을 실제로 연습하십시오.

모의 객체 사용이 실제로 유용하지 않은 경우는 없습니다.

생각하십니까?

+0

"나는 모의 객체를 사용하여 실제로 유용 어떤 경우를 확인할 수 없습니다." 그것은 아마도 너무 강한 성명서 일 것입니다. 특정 (좁은) 경우에는 조롱이 도움이되지 않습니다. 그러나 모의에 관한 담요 진술은 당신이 제시 한 증거에 대해 다소 강할 수 있습니다. 그것이 당신의 결론이라고 확신합니까? –

+1

글쎄, 물론 그것은 내 경험 범위와 내가 겪은 이슈들에 걸쳐있다. 나는 아무도 그 (것)들에게서 이득을 파생하지 않는다는 것을 가장하지 않는다.그러나 많은 다른 프로젝트에서 많은 개발 작업을 해본 결과 내가 사용하고 싶지 않은 곳을 보지 못했기 때문에 예제가 궁금합니다. 하지만 이해가 안되기 때문에 틀렸어. 만약 그렇다면 누군가가 나에게 도전하기를 바란다. – levand

답변

0

여기에 쓰기가 가능하지만 단위 테스트를 대체해서는 안됩니다. 그러나 당신이 글쓰기를 스스로 말한 이후로, 고립 프레임 워크 (일명 조롱 프레임 워크)를 사용하는 것이 좋습니다.이 프레임 워크는 여러분의 환경에도 사용할 수있을 것이라고 확신합니다. 내 마음에

2

, 단위 테스트 기능을 테스트한다고 지정하지 "를 방법은 A, 다음 다음 B, C, 그 순서에 아무것도를 할 필요가있다."

동의합니다. 모의 행동 테스트는 당신이 발견 한 것과 같이 취성 테스트로 이어질 수 있습니다. 스텁을 사용한 상태 기반 테스팅은 그 문제를 줄입니다. 파울러는 이걸 Mocks Aren't Stubs에 넣었습니다.모의 객체를 작성

은 종종 자신 모의 객체 또는 스텁에 대한

은, 절연 (조롱) 프레임 워크를 사용하는 것이 클래스를 작성하는 것보다 작업 입니다. 결국, 내 모든 시험이 정말 을 확인에서

는 행동의 가장 기본 골격이다 : "만일"과 "를" 문은 여전히 ​​

지점을 작업하고 루프 논리 것을; 나는 그들을 테스트하는 것이 좋습니다. 필자는 getter와 setter, 한 줄의 순수한 위임 메서드 등을 테스트 할 필요가 없다고 생각합니다.

통합 테스트는 귀하와 같은 복합 시스템에 매우 유용 할 수 있습니다. 나는 그들 대신에 단위 테스트 외에 을 추천 할 것이다.

하위 레벨 또는 작성 서비스의 기본 클래스를 테스트하고 싶습니다. 그게 가장 큰 쾅을 볼 수있는 곳입니다.

편집 : 파울러는 "고전적"용어를 사용하지 않습니다 (이는 내가 틀렸을 가능성이 높음). 내가 상태 기반 테스트에 관해 이야기 할 때, 테스트 대상 클래스에 스텁을 주입하여 종속 관계를 테스트하고, 테스트중인 클래스에서 동작 한 다음 테스트중인 클래스에 대해 어설 션을 수행하는 것을 의미합니다. 순수한 경우에는 스텁에서 아무 것도 확인하지 않습니다.

+0

메소드 스터 빙 (stubbing)에 대해 이야기 할 때 "상태 기반 테스트"또는 "상태 확인"이라는 용어를 사용하지 않습니다.이 두 가지는 완전히 별개이며 독립적입니다. Fowler의 기사에서 그는 상태 검증을 "정상적인 JUnit/TestNG 어설 션을 통해 수행되는 방법이 실행 된 후 SUT 및 그 협력자의 상태를 검사하는 것"이라고 자세히 기술합니다. –

+0

@Rogerio - Fowler와 거의 같은 의미입니다. Roy Osherove는 The Unit Testing의 기사에서 "Stub을 사용할 때 assert는 테스트중인 클래스에서 수행됩니다." mock을 사용하면 "테스트에서는 mock 객체를 사용하여 테스트가 통과하는지 확인합니다." 파울러와의 가장 큰 차이점은이 버전의 상태 확인에서는 주입 된 스텁을 사용하여 모든 공동 작업자로부터 SUT를 격리하고 ** 오직 SUT의 상태를 검사하는 것입니다 (정규 xUnit 어설 션으로). http://www.artofunittesting.com/ – TrueWill

+0

맞습니다. "스텁을 사용한 상태 기반 테스팅"을 너무 많이 읽었습니다. 다른 한편으로, 스텁은 단순히 자동 어서션을 수행하지 않는 퇴보 한 모크로 볼 수 있습니다. 구현 측면에서 JMockit Expectations의 모의 객체와 스텁에 대한 지원은 대부분 공유됩니다. 그러나 JMockit Annotations API는 테스트 된 유닛에서 종속성에 이르는 호출에 대해 메소드 호출 인수에 대해 정기적 인 어설 션을 수행 할 수 있도록하여 상태 확인 개념을 변형합니다. 아니면 이걸 다른 것이라고 불러야 할지도 모르겠다. 아직도 그것에 대해 생각하고있다. –

3

빠르고 안정적인 통합 테스트를 작성할 수 있다면 그럴 것입니다. 모의 또는 스텁은 필요할 때만 테스트를 계속하십시오.

공지 사항,하지만, 모의 객체를 사용하면 설명 된대로 반드시 같은 고통스러운 아니라고 :

  1. 비웃음 API를 사용하면 테스트중인 모든 장치의 호출을 허용 느슨한/비 엄격한 모의 객체를 사용하자 공동 작업자에게 따라서 모든 호출을 기록 할 필요는 없지만 메소드 호출의 특정 반환 값과 같이 테스트에 필요한 결과를 생성해야하는 호출 만 기록하면됩니다.
  2. 좋은 mocking API를 사용하면 조롱을 지정하는 테스트 코드를 거의 작성하지 않아도됩니다. 어떤 경우에는 단일 필드 선언이나 테스트 클래스에 적용된 단일 주석이 없어 질 수 있습니다.
  3. 부분적 조롱을 사용하면 특정 테스트에 대해 서비스/구성 요소 클래스의 필요한 메소드 만 실제로 조롱 될 수 있습니다. 그리고 이것은 문자열에서 상기 메소드를 지정하지 않고 수행 할 수 있습니다.
+0

+1. 엄격한 모의는 취성 시험에 대한 빠른 경로입니다. – TrueWill

0

몇 가지 질문을 하나씩 게시 했으므로 하나씩 답변 해 드리겠습니다.

대부분 서비스 지향적 인 앱에 대한 유용한 단위 테스트를 작성하려면 어떻게해야합니까?

"주로 서비스 지향 응용 프로그램"에 대한 단위 테스트에 의존하지 마십시오! 예, 나는 그것을 한 마디로 말했다. 이러한 유형의 앱은 서비스 통합이라는 한 가지 일을하기위한 것입니다. 따라서 단위 테스트 대신 통합 테스트를 작성하여 통합이 올바르게 작동한다는 점을 강조합니다.

모의 객체 사용이 실제로 유용하지 않은 경우가 있습니다.

모의는 유용 할 수 있지만 컨트롤러에서는 사용하지 않습니다. 컨트롤러는 통합 테스트에 포함되어야합니다. 서비스 은 단위 테스트로 처리 할 수 ​​있지만 테스트의 양이 프로젝트 속도를 늦추면 별도의 모듈로 유지하는 것이 좋습니다.

생각 하시겠습니까? 나를 위해

, 나는 몇 가지에 대해 생각하는 경향이 : 내 응용 프로그램이 무엇을하고

  1. ?
  2. 시스템 레벨/통합 테스트를 수행하는 것이 얼마나 비쌉니까?
  3. 별도로 테스트 할 수있는 모듈로 응용 프로그램을 분할 할 수 있습니까?

귀하가 제공 한 시나리오에서 신청서 은 많은 서비스가 통합 된입니다. 따라서 단위 테스트보다 통합 테스트에 많이 의존 할 것입니다. 난 당신이 작성한 모의 객체의 대부분은 HTTP 관련 클래스 등

내가 통합/시스템 레벨 테스트의 큰 팬이에요 위해왔다 셨을 텐데요 가능한 이유는 다음과 :

  1. 에서 어제의 디자인을 다시 고려하는 것은 점점 더 빠른 속도로 발생합니다. 통합 테스트는 구현 세부 사항을 전혀 염려하지 않으므로 신속한 변경이 용이합니다. 다이나믹 한 언어가 풀 스윙이기 때문에 모의 사람들은 더욱 위험하거나 부서지기 쉽습니다. 정적 lang을 사용하면 존재하지 않거나 맞춤법이 틀린 메소드 이름을 스텁하려는 경우 테스트가 컴파일되지 않으므로 mocks가 훨씬 안전합니다.
  2. 통합 테스트에서 작성된 코드의 양은 일반적으로 동일한 수준의 적용 범위를 달성하기 위해 단위 테스트에서 작성된 코드 양보다 60 % 적으므로 개발 시간이 단축됩니다. "네, 그러나 통합 테스트를 실행하는 데 시간이 오래 걸립니다 ..."실제로 통합 테스트를 실행하기까지는 실용적이지 않아야합니다.
  3. 통합 테스트는 더 많은 버그를 잡습니다. 조롱은 종종 인위적이며 개발자가 전체적으로 애플리케이션에 어떤 변화를 주는지 현실에서 벗어나게합니다. 통합 테스트보다 100 % 단위 테스트 커버리지의 "안전망"하에서 더 많은 버그를 생산에 허용했습니다.
  4. 내 응용 프로그램의 통합 테스트가 느린 경우 별도의 모듈로 분할하지 않았습니다. 이것은 종종 내가 분리로 추출해야 할 필요가 있다는 지표입니다.
  5. 통합 테스트는 또한 성능 문제 또는 네트워크 문제 등의 지표있어, 도달 코드 커버리지보다 당신을위한 방법으로 더 많은 일을 할
관련 문제