왜 단위 테스트 개인 메소드가 나쁜 습관으로 간주됩니까?


17

문맥:

현재 Python에서 작은 프로젝트를 진행하고 있습니다. 나는 일반적으로 문서화되어 일부 공공 방법으로 내 수업을 구성하지만, 주로 높은 수준의 개념 (클래스의 사용자가 알고 사용해야하는지), 그리고 무리를 다루는 숨겨진 의 담당 방법 (밑줄로 시작하는) 복잡하거나 낮은 수준의 처리.

코드에 대한 자신감을 갖고 나중에 수정해도 이전 동작이 중단되지 않도록 테스트가 필수적이라는 것을 알고 있습니다.

문제:

신뢰할 수있는 기반에서 더 높은 수준의 공개 메소드를 빌드하기 위해 일반적으로 개인 메소드를 테스트합니다. 코드 수정으로 회귀가 발생했는지 여부와 위치를 쉽게 찾을 수 있습니다. 이는 내부 테스트가 약간의 수정으로 인해 중단 될 수 있으며 수정 / 교체해야 함을 의미합니다.

그러나 개인 테스트 단위 테스트는 적어도 논쟁의 여지가 있거나 더 자주 나쁜 관행으로 간주됩니다. 이유는 : 공개 행동 만 테스트해야합니다 ( 참조 )

질문:

모범 사례를 따르는 것에 관심이 있으며 이해하고 싶습니다.

  • 개인 / 숨겨진 방법에서 단위 테스트를 사용하는 것이 왜 나쁜가 (위험은 무엇입니까)?
  • 공개 방법이 저수준 및 / 또는 복잡한 처리를 사용할 수있는 모범 사례는 무엇입니까?

정밀성 :

  • 질문 하는 방법 이 아닙니다 . 파이썬은 개인 정보 보호의 진정한 개념을 가지고 있지 않으며 숨겨진 메소드는 단순히 나열되지 않지만 이름을 알면 사용할 수 있습니다
  • 나는 프로그래밍 규칙과 패턴을 배운 적이 없다 : 나의 마지막 수업은 80 년대부터 시작되었다. 나는 주로 시행 착오와 인터넷 참조를 통해 언어를 배웠다.


2
OP, 비공개 메소드 테스트가 "나쁜"것으로 간주되었다는 소식은 어디서 읽었습니까? 단위 테스트에는 여러 가지 방법이 있습니다. 단위 테스트, 블랙 박스 테스트 및 화이트 박스 테스트를 참조하십시오 .
존 우

@ JohnWu : 화이트 박스 테스트와 블랙 박스 테스트의 차이점을 알고 있습니다. 그러나 화이트 박스 테스트에서도 개인 메서드를 테스트해야 할 필요성은 디자인 문제의 힌트입니다. 내 질문은 내가 거기에 빠질 때 가장 좋은 길이 무엇인지 이해하려는 시도입니다.
Ballesta Serge

2
또한 화이트 박스 테스트에서도 개인용 메소드를 테스트해야한다는 것이 디자인 문제의 힌트라는 것을 어디서 읽었습니까? 나는 대답을 시도하기 전에 그 신념에 대한 추론을 이해하고 싶습니다.
John Wu

즉, @SergeBallesta는 개인 메소드 테스트가 나쁜 습관이라고 믿게 만든 기사에 대해 언급합니다. 그런 다음 왜 믿었는지 설명하십시오.
Laiv

답변:


18

몇 가지 이유 :

  1. 일반적으로 클래스의 전용 메서드를 테스트하려는 경우 디자인 냄새 (아이스버그 클래스, 재사용 가능한 공용 구성 요소가 충분하지 않은 등)입니다. 거의 항상 "더 큰"문제가 있습니다.

  2. 공용 인터페이스를 통해 테스트 할 수 있습니다 (클라이언트가 호출 / 사용하는 방식이기 때문에 테스트하려는 방법). 개인 메소드에 대한 모든 통과 테스트에서 녹색 표시등을 보면 잘못된 보안 감각을 얻을 수 있습니다. 공용 인터페이스를 통해 개인 기능에 대한 최첨단 사례를 테스트하는 것이 훨씬 좋습니다.

  3. 개인 방법을 테스트하면 심각한 테스트 복제 (유사하게 보이는 느낌)가 발생할 위험이 있습니다. 필요한 것보다 많은 테스트가 중단 될 수 있기 때문에 요구 사항이 변경 될 때 중요한 결과가 발생합니다. 또한 테스트 스위트로 인해 리팩토링하기 어려운 위치에 놓을 수 있습니다. 테스트 스위트는 안전하게 재 설계하고 리팩토링 할 수 있도록 도와주기 때문에 가장 아이러니합니다.

여전히 개인 부품을 시험하고 싶은 유혹이 있다면 팁 (귀하와 YMMV를 귀찮게하는 경우 사용하지 마십시오.하지만 과거에는 나에게 잘 작동했습니다) : 때로는 개인 기능에 대한 단위 테스트를 작성하여 확인하십시오. 그들은 그들이 당신이 가치 있다고 생각하는 방식을 정확하게 작동하고 있습니다 (특히 언어를 처음 사용하는 경우). 그러나 테스트가 완료된 후에는 테스트를 삭제하고, 공개 테스트가 확실하고 누군가 개인 기능을 심각하게 변경 한 경우 포착 할 수 있도록하십시오.

개인 메소드를 테스트 할시기 : 이 답변이 인기를 얻었으므로 "모범 사례"는 항상 "최고 사례"라고 언급 할 의무가 있습니다. 맹목적으로 또는 맹목적으로해야한다는 의미는 아닙니다. 개인용 메소드를 테스트해야한다고 생각하고 (레거시 애플리케이션에 대한 특성화 테스트를 작성하는 것과 같은) 정당한 이유가있는 경우 개인용 메소드를 테스트하십시오 . 특정 상황은 항상 일반적인 규칙이나 모범 사례보다 우선합니다. 잘못 될 수있는 몇 가지 사항 만 알아 두십시오 (위 참조).

나는 이것을 반복하지 않을 SO에 대해 자세히 설명하는 대답이 있습니다 : https : //.com/questions/105007/should-i-test-private-methods-or-only-public-ones/ 47401015 # 47401015


4
이유 1 : Nebulous. 이유 2 : 개인 헬퍼 메소드가 공용 API의 일부가 아니어야하는 경우 이유 3 : 수업을 제대로 설계하지 않으면 아닙니다. 마지막 팁 : 내가 작성한 방법이 효과가 있음을 입증하는 완벽하게 좋은 테스트를 왜 삭제해야합니까?
Robert Harvey

4
@RobertHarvey 이유 2 : 공개 API를 통해 간접적으로 액세스 가능! = 공개 API의 일부 임. 퍼블릭 API를 통해 프라이빗 함수를 테스트 할 수없는 경우 아마도 죽은 코드이므로 제거해야합니까? 또는 수업은 실제로 빙산 (이유 1)이므로 리팩터링해야합니다.
Frax

5
@RobertHarvey 퍼블릭 API를 통해 프라이빗 함수를 테스트 할 수 없다면 유용한 목적이 없으므로 삭제하십시오.
David Arno

1
@RobertHarvey 1 : 디자인 냄새는 항상 다소 주관적이거나 모호합니다. 그러나 나는 안티 패턴의 구체적인 예를 나열했으며 SO 답변에 더 자세히 설명되어 있습니다. 2 : 개인 메소드는 공개 API의 일부가 될 수 없습니다 (정의 : 비공개) ... 귀하의 질문이 많은 의미가 있다고 생각하지 않습니다. 나는 당신이 bin_search(arr, item)(공개) 및 bin_search(arr, item, low, hi)(개인, 빈 검색을 수행하는 많은 방법이 있습니다 )와 같은 것이 있다면 테스트해야 할 모든 것이 대중을 향한 것 ( bin_search(arr, item))
Matt Messersmith

1
@RobertHarvey 3 : 첫째로, 나는 말했다 위험 하지 보장합니다 . 둘째, "적절하게하면 효과가있다"고 주장하는 것은 자급 자족입니다. 예를 들어, " 제대로 작동 하면 운영 체제를 단일 기능으로 작성할 수 있습니다 ". 이것은 거짓이 아니지만 유용하지 않습니다. 팁 : 구현이 변경되면 (즉, 개인 impl을 교체하려는 경우) 테스트 스위트가 방해를 받으므로 삭제하지 않아야합니다 (실패하지 않은 테스트는 실패합니다).
Matt Messersmith

14

단위 테스트의 주요 목적 중 하나는 프로그램 내부를 리팩터링하고 기능이 손상되지 않았 음을 확인할 수 있다는 것입니다. 프로그램 코드를 변경하면 테스트를 다시 작성해야합니다.


왜 답이 다운되었는지 확실하지 않습니다. 요컨대, 짧고 100 % 정답을 얻습니다.
David Arno

3
@DavidArno : 아마도 프라이빗 메소드 테스트는 테스트 세분 성과는 크게 관련이 없기 때문일 수 있습니다. 구현 세부 사항에 연결하는 것과 관련이 있습니다.
Robert Harvey

11

개인 메소드에 대한 단위 테스트 작성 은 단위 테스트를 구현 세부 사항에 연결합니다.

단위 테스트는 클래스의 외부 표면 (공개 API)에서 클래스의 동작을 테스트해야합니다. 단위 테스트는 클래스의 내부에 대해 아무것도 알 필요가 없습니다. 클래스의 구현 세부 사항에 대해 단위 테스트를 작성하면 리팩토링 할 때가 필요합니다. 리팩토링은 안정적인 API의 일부가 아니기 때문에 테스트를 거의 중단 할 것입니다.

말했다, 왜 당신은 당신의 개인 방법에 대한 단위 테스트를 작성하려면?

단위 테스트와 점진적인 개발 사이에는 자연스러운 긴장이 있습니다. REPL (read-eval-print loop)을 사용하는 소프트웨어 개발자는 클래스 나 함수를 "성장"할 때 작은 기능을 신속하게 작성하고 테스트하는 것이 얼마나 생산적인지 입증 할 수 있습니다. 단위 테스트 중심 환경에서이를 수행하는 유일한 방법은 개인용 메소드에 대한 단위 테스트를 작성하는 것이지만 그렇게하는 데 많은 어려움이 있습니다. 단위 테스트는 작성하는 데 시간이 걸리고 테스트 할 실제 방법이 필요하며 테스트 프레임 워크는 외부 API를 오염시키지 않도록 메소드를 비공개로 유지하는 기능을 지원해야합니다.

C # 및 .NET과 같은 일부 에코 시스템에는 REPL과 같은 환경 (Linqpad와 같은 도구)이 작성 될 수있는 방법이 있지만 프로젝트에 액세스 할 수 없으므로 유틸리티가 제한됩니다. Visual Studio의 즉각적인 창은 불편합니다. 여전히 완전한 Intellisense가 없으며 완전한 이름을 사용해야하며 사용할 때마다 빌드를 트리거합니다.


4
@ user949300 진정한 Scotsman 오류에 빠지지 않고이 문제에 대해 토론하기는 다소 어렵지만 모든 종류의 테스트가 잘못되었습니다. 단위 테스트 관점에서 내부 구현 세부 사항을 모르고 메소드의 공개 계약을 테스트해야합니다. 특정 종속성이 X 번이라고 불렀다는 것이 항상 잘못된 것은 아닙니다. 이것이 의미가있는 상황이 있습니다. 이 정보가 테스트중인 해당 장치의 계약에서 실제로 전달하려는 정보인지 확인해야합니다.
Vincent Savard

3
@DavidArno : [ shrug ] 나는 이것을 잠시 동안 해왔다. Microsoft가 테스트 프레임 워크에서 프록시 개체 지원을 중단하기로 결정할 때까지 개인 메서드에 대한 단위 테스트는 항상 잘 작동했습니다. 그 결과 아무것도 폭발하지 않았습니다. 나는 개인적인 방법에 대한 테스트를 작성하여 우주에 구멍을 뚫지 않았습니다.
Robert Harvey

2
@DavidArno : 인터넷상의 누군가가 정당성을 제공하지 않고 나쁜 생각을한다고해서 왜 나에게 이점을 제공하는 완벽하게 좋은 기술을 사용하지 않겠습니까?
로버트 하비

2
내가 단위 테스트에서 얻는 주요 이점은 내 코드를 어설프게 할 수있는 "안전망"을 제공하고 변경 사항에 회귀가 발생하지 않는다는 것을 확신하는 것입니다. 이를 위해 개인 헬퍼 메소드를 테스트하면 이러한 회귀를 쉽게 찾을 수 있습니다. 개인 도우미 메서드를 리팩터링하고 논리 오류를 도입하면 해당 개인 메서드와 관련된 테스트를 중단합니다. 내 단위 테스트가 더 일반적이고 해당 코드 단위의 인터페이스 만 테스트하면 문제를 찾기가 훨씬 더 어려워집니다.
알렉산더-복원 모니카

2
@Frax 물론, 가능하지만 그 논리에 따라 시스템 전체 통합 테스트를 위해 단위 테스트를 포기해야합니다. 결국, "대부분의 경우 동일한 행동을 테스트하기 위해 이러한 테스트를 수정할 수 있어야합니다"
Alexander-Reinstate Monica

6

내 경험에 따르면 내부 클래스, 단위 테스트를 수행하는 단위는 일반적으로 테스트 된 함수, 클래스를 가져와야 함을 의미합니다. 다른 수준의 추상화를 만듭니다.

이는 단일 책임 원칙을보다 잘 준수하도록합니다.


이것이 정답입니다.
Jack Aidley

0

나는 이것이 커버리지 테스트에 일반적인 문제를 노출시키기 때문에 좋은 질문이라고 생각합니다. 하지만 좋은 대답은 이론적으로, 당신이해야하기 때문에 문제가 정확히 잘 아니라고 말할해야 하지 단위 테스트 할 수있을 개인 방법. 그것이 그들이 사적인 이유 입니다.

아마도 더 좋은 질문은 "개인 메소드를 테스트하고 싶을 때 어떻게해야합니까?"입니다.답은 분명합니다. 테스트 할 수있는 방식으로 노출해야합니다. 이제 이것이 반드시 메소드를 공개해야한다는 것을 의미하지는 않습니다. 아마도 더 높은 추상화를 원할 것입니다. 다른 라이브러리 또는 API로 이동하면 기본 API에서 해당 기능을 노출하지 않고도 해당 라이브러리에서 테스트를 수행 할 수 있습니다.

메서드의 접근성 수준이 다른 이유가 있으므로 항상 클래스가 어떻게 사용되는지 생각해야합니다.



나는 파이썬이 프라이버시의 진정한 개념이 아니며 숨겨진 메소드가 단순히 나열되지는 않지만 자신의 이름을 알 때 사용할 수
Serge Ballesta
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.