programing tip

높은 수준의 단위 테스트 및 모의 개체의 가치

itbloger 2020. 12. 2. 08:11
반응형

높은 수준의 단위 테스트 및 모의 개체의 가치


모의 객체를 광범위하게 사용해야하는 고수준의 잘 작성된 코드 단위 테스트가 가치가 거의 또는 전혀 없다고 믿기 시작했습니다. 이 주장이 올바른지 궁금합니다. 아니면 뭔가 빠졌나요?

높은 수준이란 무엇을 의미합니까? 이것들은 먹이 사슬의 맨 위에있는 클래스와 기능입니다. 그들의 입력과 출력은 사용자 입력과 사용자 인터페이스 인 경향이 있습니다. 대부분의 작업은 사용자 입력을 받고 하위 수준 엔터티에 대한 일련의 호출로 구성됩니다. 그들은 종종 의미있는 반환 값이 거의 없거나 전혀 없습니다.

잘 쓰여졌다는 것은 무엇을 의미합니까? 이 경우 종속성 (인터페이스 및 종속성 주입 사용)에서 분리 된 코드를 언급하고 있으며, 한 줄씩 일관된 추상화 수준에 있습니다. 까다로운 알고리즘이 없으며 조건부도 거의 없습니다.

이런 종류의 코드에 대한 단위 테스트를 작성하는 것이 싫습니다 . 단위 테스트는 거의 전적으로 모의 객체 설정으로 구성됩니다. 한 줄씩 단위 테스트는 구현의 거울 이미지처럼 읽습니다. 실제로 구현을 살펴봄으로써 단위 테스트를 작성합니다. "먼저이 모의 메서드가 호출 되었다고 주장한 다음이 모의 메서드가 호출 되었다고 주장합니다 ..."등 입니다. 메서드의 올바른 시퀀스를 호출하는 것이 아니라 메서드의 동작을 테스트해야합니다 . 또 다른 사실은이 테스트가 리팩토링에 매우 취약 하다는 사실 입니다. 테스트가 너무 취약하다면 완전히 산산조각이 나고 테스트중인 코드가 리팩토링 될 때 다시 작성해야한다면 단위 테스트의 주요 이점 중 하나가 손실되지 않았습니까?

이 게시물이 논쟁 적이거나 질문이 아닌 것으로 표시되는 것을 원하지 않습니다. 그래서 저는 제 질문을 직접 말할 것입니다. 제가 설명한 종류의 코드를 단위 테스트하는 올바른 방법은 무엇입니까, 아니면 모든 것이 단위 테스트를 필요로하지 않는다는 것을 이해하고 있습니까?


내 경험상, 코드 수준이 낮을수록 (사소하지 않은) 단위 테스트는 작성하는 데 필요한 노력에 비해 더 많은 가치가 있습니다. 먹이 사슬이 올라 갈수록 테스트는 점점 더 정교 해지고 비용이 많이 듭니다.

단위 테스트는 리팩토링 중에 무언가를 깨뜨릴 때 알려주기 때문에 중요합니다.

더 높은 수준의 테스트에는 고유 한 가치가 있지만 더 이상 단위 테스트라고 부르지 않습니다. 이를 통합 테스트 및 수용 테스트라고합니다. 통합 테스트는 서로 다른 소프트웨어 구성 요소가 얼마나 잘 작동하는지 알려주기 때문에 필요합니다.

수락 테스트는 고객이 서명하는 것입니다. 수락 테스트는 일반적으로 다른 관점을 제공하기 위해 프로그래머가 아닌 다른 사람이 작성합니다. 프로그래머는 작동하는 것에 대한 테스트를 작성하는 경향이 있고, 테스터는 작동하지 않는 것을 테스트하여 깨뜨 리려고합니다.

조롱은 단위 테스트에만 유용합니다. 통합 및 수용 테스트의 경우 모킹은 데이터베이스 및 통신 인프라와 같은 실제 시스템 구성 요소를 실행하지 않기 때문에 쓸모가 없습니다.


제쳐두고

대담한 진술을 만지십시오.

"나는 메소드의 올바른 순서를 호출하는 것이 아니라 메소드의 동작을 테스트해야합니다."

객체 테스트 대상의 동작 입니다 걸리는 일련의 작업. 이것은 실제로 "행동"테스트이지만 "메서드의 동작"이라고 말하면 상태 저장 테스트를 의미한다고 생각합니다. 입력을 제공하고 올바른 출력을 확인합니다.

일부 BDD 순수 주의자들은 입력과 출력이 무엇인지보다 클래스가 무엇을 호출해야하는지 테스트하는 것이 훨씬 더 의미가 있다고 주장하기 때문에이 구분을합니다. 왜냐하면 시스템이 어떻게 작동하는지 완전히 안다면, 그러면 입력과 출력이 정확할 것입니다.

응답

그 외에도 저는 개인적으로 UI 레이어에 대한 포괄적 인 테스트를 작성하지 않습니다. 응용 프로그램에 MVVM, MVP 또는 MVC 패턴을 사용하는 경우 "1 개발자 팀"수준에서 그렇게하는 것은 마음이 마비되고 비생산적입니다. UI에서 버그를 있으며, 예,이 수준에서 조롱하는 동작은 깨지기 쉬운 경향이 있습니다. 내 기본 도메인과 DAL 레이어가 제대로 작동하는지 확인하는 데 훨씬 더 관심이 있습니다.

무엇 이다 최상위 수준에 값은 통합 테스트입니다. 웹 앱이 있습니까? 컨트롤러 메서드가 ActionResult (작은 값 테스트)를 반환한다고 주장하는 대신 앱의 모든 페이지를 요청하고 404 또는 403이 없는지 확인하는 통합 테스트를 작성하세요. 배포 할 때마다 한 번씩 실행합니다.

최종 답변

나는 항상 단위 테스트와 함께 80/20 규칙을 따릅니다 . 당신이 말하고있는 높은 수준의 마지막 20 % 커버리지를 얻으려면 노력의 80 %가 될 것입니다. 내 개인 프로젝트와 대부분의 작업 프로젝트에서 이것은 성과를 거두지 못합니다.

요컨대 동의합니다. 통합 테스트를 작성하고 설명하는 코드에 대한 단위 테스트는 무시합니다.


환경에 크게 의존한다고 생각합니다. 비교적 작은 팀에 있고 테스트 무결성을 유지할 수있는 경우 응용 프로그램의 더 복잡한 부분에 단위 테스트가 있어야합니다. 제 경험으로는 대규모 팀에서 테스트 무결성을 유지하는 것은 매우 어려운 일입니다. 테스트가 처음에는 문제가 될 때까지 괜찮아지기 때문입니다 ... 어느 시점에서 테스트가 a) 유용성을 완전히 무효화하는 방식으로 "고정"되거나 b ) 즉시 주석 처리했습니다.

모의 테스트의 요점은 관리자가 코드 커버리지 메트릭이 Foo %에 있다고 주장 할 수 있도록하는 것 같습니다. 따라서 모든 것이 작동해야합니다! 그것들이 유용 할 수있는 한 가지 예외적 인 경우는 진짜로 다시 만드는 데 큰 고통을주는 클래스를 테스트해야 할 때입니다 (예를 들어 Struts에서 액션 클래스를 테스트하는 것).

나는 원시 테스트를 작성하는 데 큰 신봉자입니다. 실제 개체가있는 실제 코드. 메서드 내부의 코드는 시간이 지남에 따라 변경되지만 목적과 전반적인 동작은 일반적으로 변경되지 않습니다.


TDD를 수행하는 경우 구현 후 테스트를 작성하지 말고 반대 방향으로 작성해야합니다. 이렇게하면 테스트가 작성된 코드를 준수하도록 만드는 문제도 피할 수 있습니다. 해당 단위 내에서 특정 메서드 호출을 테스트해야하지만 해당 시퀀스는 테스트하지 않아도됩니다 (도메인 문제-비즈니스 프로세스에 필수적이지 않은 경우).

때로는 특정 방법에 대한 테스트를 작성하지 않는 것이 완벽하게 실현 가능합니다.


일반적으로 이러한 유형의 방법 / 명령을 통합 테스트 수준에 맞게 테스트하는 것으로 간주합니다. 특히, (일반적으로) 부작용이없는 더 작고 낮은 수준의 명령에 대한 "단위 테스트"입니다. 실제로 해당 모델에 맞지 않는 것을 단위 테스트하고 싶다면 가장 먼저해야 할 일은 리팩터링 / 재 설계를 통해 적합하게 만들 수 있는지 확인하는 것입니다.

더 높은 통합 (및 / 또는 시스템) 테스트 수준에서 나는 부작용이있는 것을 테스트합니다. 나는이 시점에서 가능한 한 적게 (아마도 외부 리소스 만) 조롱하려고합니다. 예를 들어 데이터베이스 계층을 다음과 같이 조롱하는 것입니다.

  1. 데이터를 얻기 위해 호출 된 방법 기록
  2. 미리 준비된 데이터 반환 방법 기록
  3. 조작 된 데이터를 삽입하기 위해 호출 된 방법 기록

참고 URL : https://stackoverflow.com/questions/1090521/the-value-of-high-level-unit-tests-and-mock-objects

반응형