단위 테스트가 불가능한 함수 및 클래스의 종류와 이유


21

좋은 단위 테스트를하지 않은 개발자의 주된 변명은 "코드는 단위 테스트 가능한 방식으로 설계되지 않았습니다"입니다. 단위 테스트 할 수없는 디자인 및 코드 유형을 이해하려고합니다.


2
변명? 동료? 관리자? 어떤 언어 / 프레임 워크를 사용하고 있습니까?

1
애플리케이션에 많은 레거시 코드가 있으며 재 설계 할 시간이 없습니다.
knut

4
@ gnat : 동의하지 않습니다. 인용 한 질문은 단위 테스트가 유용하지 않은 상황에 관한 것입니다. 현재 질문은 단위 테스트를 어렵게 만드는 상황에 관한 것입니다.
Arseni Mourzenko

@MainMa는 분명히 다른 질문을 읽습니다. "단위 테스트 할 수없는 디자인 및 코드 유형을 이해하려고합니다." => "단위 테스트를하지 않는 것이 언제 적절한가요?"
gnat dec

1
@ manizzzz : 질문으로 편집하고 싶을 수도 있습니다.
jmoreno

답변:


27

몇 가지 요인으로 인해 코드를 단위 테스트하기가 어려울 수 있습니다. 이 경우 리팩토링을 통해 코드를 테스트 할 수 있도록 코드를 개선 할 수 있습니다.

테스트하기 어려운 코드의 예 :

  • 1000-LOC 기능
  • 글로벌 상태에 크게 의존하는 코드,
  • 인터페이스와 의존성 주입에 의존하는 대신 데이터베이스 컨텍스트와 같은 객체를 빌드하기 위해 구체적이고 복잡한 코드,
  • 느리게 수행하는 코드 ,
  • 스파게티 코드
  • 가독성이나 유지 관리에 신경 쓰지 않고 수년 동안 수정 된 레거시 코드,
  • 어려움과 같은 변수 이름을 사용하는 예제 코드의 저자 (의 원래 의도에 대해 어떠한 의견이나 힌트가없는 코드를 이해합니다 function pGetDp_U(int i, int i2, string sText).

단위 테스트는 코드의 작은 부분과 관련되므로 명확한 아키텍처가 부족하더라도 코드를 단위 테스트하기가 어렵지 않습니다. 불분명 한 아키텍처는 여전히 통합 및 시스템 테스트에 부정적인 영향을 미칩니다.


8
또한 난수, 현재 시간, 유선 I / O 등과 같은 순수하지 않은 함수에 대한 종속성을 주입하지 않는 코드는 테스트하기가 어렵습니다.
9000

코드를 테스트하는 것이 쉽지 않습니다. 코드를 엉망으로 만들지 말고 올바른 테스트 툴만 있으면됩니다. 예를 들어 Microsoft Fakes를 사용해보십시오.
gbjbaanb

@ MainMa, 나는이 대답을 좋아한다. 또한 다른 테스트를 통합 및 시스템 테스트에 적용하는 요소에 대해 약간의 의견을 제시 하시겠습니까? 과거의 질문과 비슷한 질문을 한 이유는 어떤 유형의 테스트가 어디에 가장 적합한 지 (또는 아마도 가장 비용 효율적으로 어디에 넣는 지) 설명하는 로드맵이 없었기 때문입니다. 단위 테스트는 단 하나뿐이었습니다.
J Trana

14

코드를 단위 테스트하기 어렵게 만드는 많은 것들이 있습니다. 우연히도 많은 것들이 코드를 유지하기 어렵게 만듭니다.

  • 데메테르 법칙 위반.
  • 의존성주입 하는 대신 메소드 내에 객체를 생성합니다 .
  • 단단한 커플 링.
  • 응집력이 약합니다.
  • 부작용에 크게 의존합니다.
  • 글로벌 또는 싱글 톤에 크게 의존합니다.
  • 많은 중간 결과를 노출하지 않습니다. (한 번 출력하고 사용 가능한 중간 결과가없는 10 페이지 길이의 수학 함수를 단위 테스트해야했습니다. 선행 작업은 기본적으로 코드에서 발생하는 모든 응답을 하드 코딩했습니다.)
  • 데이터베이스와 같이 조롱하기 어려운 서비스에 직접적으로 의존합니다.
  • 런타임 환경은 임베디드 대상과 같은 개발 환경과 크게 다릅니다.
  • 컴파일 된 형식으로 만 사용할 수있는 장치 (타사 DLL과 같은)

나는 이것이 훌륭한 대답이라고 생각합니다. 많은 코드 수준 문제와 전역 상태 문제를 다룹니다. @MainMa에는 유효하지만 덜 잘 정의 된 다른 문제가 있습니다. Jeffery Thomas는 I / O 및 UI에 대해 언급합니다. 이 세 가지 답변 중 좋은 부분을 추가하면 훌륭한 응집력을 얻을 수 있다고 생각합니다. 코드 반 패턴에 초점을 맞추기 때문에이 답변이 가장 좋습니다.
M2tM

1
Argh-비즈니스 요구 사항과 유사하지 않고 주어진 시간에 출력되는 유닛 테스트 주장보다 더 나쁘지 않은가? 왜 3입니까? 테스트가 처음으로 실행 / 실행 된 시간이 3 회 였기 때문에 :)
Michael

단단한 커플 링은 부적절한 경우에만 나쁩니다. 응집력이 높은 코드의 긴밀한 결합이 필수적입니다. 예를 들어 변수 선언 다음에 사용됩니다. 견고하게 결합되고 응집력이 높습니다.
dietbuddha

1
비즈니스 사례 / 정의없이 코드와 비교하여 출력을 확인하는 단위 테스트를 특성화 테스트라고합니다. 그들은 이전에 테스트가 없었고 종종 문서화 된 요구 사항이 없었던 유지 보수에 사용되며 해당 기능의 출력이 변경되면 중단되는 무언가를 넣어야합니다. 그들은 아무것도 아닌 것보다 낫습니다.
Andy Krouwel

5

사람들이 단위 테스트를 원하지 않는 일반적인 코드 예제 :

  • i / o와 직접 상호 작용하는 코드 (파일 읽기, 네트워크 직접 호출 등)
  • UI를 직접 업데이트하는 코드입니다.
  • 싱글 톤 또는 전역 객체를 직접 참조하는 코드.
  • 객체 또는 하위 객체 상태를 암시 적으로 변경하는 코드입니다.

모의 프레임 워크를 사용하여 이러한 모든 예제를 단위 테스트 할 수 있습니다. 내부 종속성에 대한 모의 대체물을 설정하는 것만으로 작동합니다.

단위 테스트를 할 수없는 것들 :

  • 무한 루프 (스레드 관리자, 드라이버 또는 다른 유형의 장기 실행 코드)
  • 특정 유형의 직접 어셈블리 작업 (일부 언어는 지원)
  • 특권 액세스가 필요한 코드 (불가능하지 않고 좋은 생각은 아닙니다)

2

단위 테스트를 작성하기가 더 어려운 몇 가지 영역이 있습니다. 그러나 이것이 유용한 테크닉을 단순히 테스팅에 약간의 복잡성을 추가 할 수 있기 때문에 할인해야한다는 것을 의미하지는 않습니다. 어떤 코딩과 마찬가지로 당신이 이익이 비용을 outway 여부를 결정하기 위해 자신의 분석을 수행해야하며, 맹목적으로 그물에 어떤 어떤 임의의 사람이 게시물을 수락하지.

설계된 코드로 잘못 작성

  • 부적절한 커플 링 (일반적으로 커플 링해서는 안되는 타이트한 커플 링)
  • 키친 싱크 코드 (함수가 너무 많은 로직 / 책임)

다른 범위에서 국가의 의존

당신이 무엇을하는지 알지 못한다면 이러한 나선의 대부분을 통제 할 수없는 비용. 불행히도 많은 사람들은 복잡한 테스트와 같은 것을 완화하기 위해 이러한 기술을 사용하는 방법을 종종 모릅니다.

  • 싱글 톤
  • 글로벌
  • 폐쇄

외부 / 시스템 상태

  • 하드웨어 / 장치 종속성
  • 네트워크 의존성
  • 파일 시스템 의존성
  • 프로세스 간 종속성
  • 다른 시스템 호출 종속성

동시성

  • 스레딩 (잠금, 중요 섹션 등)
  • 분기
  • 코 루틴
  • 콜백
  • 신호 처리기 (모두가 아닌 일부)

2

테스트 할 수없는 코드는 없습니다. 그러나 실제로 테스트하기 어려운 코드의 몇 가지 예가 있습니다 (노력할 가치가없는 시점까지).

하드웨어 상호 작용-코드가 하드웨어를 직접 조작하는 경우 (예 : 물리적 장치를 이동하기 위해 레지스터에 쓰는 경우) 단위 테스트가 너무 어렵거나 비쌀 수 있습니다. 테스트에 실제 하드웨어를 사용하는 경우 테스트 하네스 (아직 더 많은 장비)에 대한 적절한 피드백을 얻는 데 많은 비용이 소요될 수 있습니다. 일부 사례.

클록 상호 작용-시스템 클록 기능을 거의 사소하게 조롱하는 것이 거의 항상 가능하기 때문에 일반적으로 더 쉽습니다. 그러나 그렇게 할 수 없으면 이러한 테스트를 관리 할 수 ​​없게됩니다. 실시간을 기반으로하는 테스트는 실행하는 데 시간이 오래 걸리는 경향이 있으며 제 경험상 시스템로드로 인해 예상보다 시간이 오래 걸리기 때문에 취하기 쉽습니다. 팬텀 테스트 실패를 유발합니다.


0

이것에 대한 나의 주요 세 그룹은 다음과 같습니다.

  • 외부 서비스에 의존하는 코드

  • 테스터가 애플리케이션과 독립적으로 상태를 수정할 수없는 시스템.

  • 프로덕션 설정을 복제하지 않는 테스트 환경

이것이 개발자가 QA 엔지니어가되어 가장 많이 경험 한 것입니다.

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