단위 테스트는 '기능적'소프트웨어 만 포함해야합니다


9

우리는 새로운 소프트웨어 개발 프로젝트에서 StructureMap 을 사용하고 있습니다. 팀 구성원 중 하나가 기본적으로 StructureMap 컨테이너 구성을 테스트하는 단위 테스트를 구현했습니다 . 다음을 수행하여이를 수행합니다.

  • 응용 프로그램 네임 스페이스의 클래스에 대해 구성된 어셈블리 인스턴스 수를 계산합니다.
  • 클래스 수준에서 예상 인스턴스를 정의합니다
  • 예상 인스턴스가 발견 된 총 인스턴스와 일치하는지 확인합니다.
  • 예상 인스턴스가 테스트에 정의 된 인스턴스와 일치하는지 확인

이에 대한 예는 다음과 같습니다.

var repositories = container.GetAllInstances<IEnvironmentRepository>();
Assert.AreEqual(1, repositories .Count());
foundInstances = foundInstances + repositories .Count();

우리는 또한 다음 수업에 대한 '단위 테스트'를 가지고 있습니다.

public MyClass(IEnvironmentRepository environmentRepository)
        {

        }

이 테스트에서는 IEnvironmentRepository를 모방하므로 라이브 시스템에서와 같이 컨테이너에서 컨테이너를 주입하지 않습니다.

동료는 "단위 테스트는 자체 구성 만 테스트합니다"라는 줄에 주석이있는 구조 맵 구성의 단위 테스트를 무시했습니다. 이것은 분명히 테스트의 목적이며 내 의견으로는 완벽하게 유효합니다. 테스트를 무시한 사람이 IEnvironmentRepository(테스트는 여전히 무시한 상태)에 대한 구조 맵 구성을 제거 하고 전체 단위 테스트 스위트를 실행하도록 요청했으며 모두 통과했습니다. 그런 다음 응용 프로그램을 실행했으며 이제 컨테이너 구성이 유효하지 않기 때문에 실패했습니다. 내 의견으로는, 이것은 시험의 가치를 입증했으며 내 동료는 여전히 동의하지 않았다. 그는 우리가 구성을 테스트해서는 안된다고 말했지만, 이것이 단위 테스트의 범위 내에 있다고 생각합니다.

그래서 많은 질문들;

  • 유효한 단위 테스트입니까-우리는 컨테이너 맵의 구성이 아닌 컨테이너의 구성을 테스트하고 있습니다 (그러나 중복을 볼 수는 있습니다)
  • 그렇지 않은 경우 테스트하지 않고 구성을 어떻게 검증 할 수 있습니까? 실수로 필요한 코드 줄을 삭제하고 체크인하는 것을 어떻게 막을 수 있습니까?
  • 해야 MyClass단위 테스트의 인스턴스를 해결 IEnvironmentRepository용기로부터이 통과?

10
테스트에 대한 10 가지 의견 중 9 개는 프레임 워크 가 모든 형태의 자동화 된 테스트 를 지원 하고 사람들이 특정 자동화 된 테스트가 적절하고 적절한 단위 테스트 인지 여부에 대한 시맨틱을 원한다는 사실에서 발생 합니다 . 당신이 설명하는 테스트는 일종의 not-quite-unit-test-test와 같은 소리를 가지고 있고 자동화하고 (그리고 체크인시 실행하는) 매우 유용 할 수 있습니다-단위 테스트라고 부르지 마십시오. 테스트가 명확하게 분리 된 자체 기능 / 폴더에있는 경우 동료가 밤에 더 잘자는 지 물어보십시오.
Jeroen Mostert

2
그것은 제 의견이기도합니다. 아마도 유용 할 것입니다. 단위 테스트는 아니지만 값을 추가하는 것이 입증되었습니다. 그의 대답은 다른 단위 테스트가 이것을 선택했을 것이라고 생각했지만, 엄격한 단위 테스트로 작성된 경우 종속성을 조롱 할 수 있으므로 구성을 사용할 때까지 구성이 유효한지 알 수 없습니다.
ChrisBint

4
당신의 동료는 진대 그가 시험 구성하지라는 점,이 진짜 잘못하고 "파란색"입니다 "빨간색"말의 아니다 - / 테스트하지 않아야 수없는 전개에 따라 다를 실제로 수있는 구성을? 테스트는 하나의 설정에 밀접하게 연결됩니다. 그러나 코드 아티팩트와 관련된 구성은 예외가 아니며, 다양하지 않으며 잘못 가져올 수있는 방법이 있기 때문입니다. 이상적으로는 DRY 메타 데이터에서 빌드 타임에 이러한 구성을 생성하지만 이것이 불가능한 경우에는 이와 같은 테스트로 가치가 추가됩니다. 피할 수없는 배포 오류보다 낫습니다.
Jeroen Mostert

2
설명하는 것은 장치를 테스트하는 것이 아니라 타사 소프트웨어의 구성을 테스트하는 것입니다. 이러한 것들을 테스트하는 테스트를하는 것이 환상적으로 유용 하지만 단위 테스트가 아닌 통합 테스트이며 연결이 끊어 질 수 있습니다.
Phoshi

3
@ChrisBint Goodness 은혜로운 아니요, 컨테이너 테스트를 직접 작성했습니다. 그들은 많은 가치를 가지고 있으며 단지 단위 테스트가 아닙니다. 괜찮습니다. 통합 테스트는 단위 테스트가 할 수없는 것을 포착하는 데 매우 중요합니다 .
Phoshi

답변:


13

이것은 완벽하게 유효한 자동화 테스트입니다. 코드베이스의 스켈 레탈 컴포넌트의 건전성을 검증 할 때이를 "아키텍처 테스트"라고합니다.

IoC 컨테이너가 애플리케이션의 모든 객체 트리를 분석하고 구성 할 수 있습니까? 자동 매퍼가 등록 된 모든 객체간에 실패없이 매핑 할 수 있습니까? 어니언 아키텍처의 중앙 레이어는 외부를 참조 하지 않습니까?

이 테스트를 통해 정확한 범인을 지적함으로써 구성 버그가 몰래 들어 오면 많은 시간을 절약 할 수 있습니다. 좋은 프레임 워크는 무엇이 잘못되었는지에 대한 매우 정확한 오류 메시지를 제공하며 운이 좋으면 런타임 스택 추적에 깊이 묻히지 않고 테스트를 실행하는 즉시 (이상적으로 지속적으로) 얻을 수 있습니다.

그것들이 단위 테스트인지 아닌지는 모르지만 여전히 대부분 메모리에서 작동하고 꽤 빠르게 실행됩니다. 다시 말하지만, 나는 단위 테스트에 대해 보편적으로 받아 들여진 정의와 같지 않습니다.


아이러니하게도 이것은 동료에게 설명하는 방법과 거의 같으며 유효성 검사 (컨테이너 인스턴스 중 하나를 삭제하고 응용 프로그램을 실행)를하더라도 그는 여전히 가치를 보지 못했습니다. 나는 모든 사람들이 자신의 의견을 가지고 있음을 이해하고 나는 내 목소리를 들었다. 나는 "아키텍처 테스트"라는 용어를 좋아한다. 나는 그것을 훔칠 것이다!
ChrisBint

6

이와 같은 테스트의 문제점은 프로그램의 요구 사항이 아니라 프로그램의 내부를 테스트합니다. 프로그램이 필요에 따라 작동하더라도 테스트가 실패 할 수 있습니까?

귀하의 경우 컨테이너 설정을 변경할 때마다 주입이 필요한 새로운 종속성이있을 때 테스트를 중단합니다.

또한 추가 종속성 요구 사항을 추가하지만 컨테이너에 추가하고 컨테이너 테스트를 변경하는 것을 잊지 마십시오. 모든 것이 통과되지만 프로그램이 중단됩니다.

더 나은 자동화 테스트는 프로그램을 시작하고 충돌하는지 확인하는 것입니다.

단위 테스트를 통과하더라도 통합 또는 UI 테스트에서 이러한 유형의 오류를 포착해야합니다.

그러나 컨테이너 설정의 복잡성이 증가하는 것은 어려운 일입니다. 아마도 일부 '나쁜'테스트는 그만한 가치가 있습니다.


1

단위 테스트 테스트 코드. 이 이외의 것은 "기타"자동화 테스트입니다. 원하는대로 호출하십시오. 여기서 구성을 테스트하는 것 같습니다. 환경에 따라 구성이 변경 될 수 있으면 단위 테스트에 속하지 않습니다. 테스트가 다른 테스트와 다른 유형임을 나타내려면 테스트 속성을 추가하십시오.


구성은 정적이며 환경에 의해 구동되지 않으며 구성에 존재하는 모든 클래스는 모든 환경에서 동일한 방식으로 사용됩니다. 예, 설정 될 수있는 경우의 수는 설정에서 인스턴스의 수와 일치해야합니다 입니다 시험의 일부를. 내 예제에서 알 수 있듯이 IEnvironmentRepository를 제거하면 다른 단위 테스트가 통과되었습니다. 특정 컨테이너 테스트는 2 개의 Asserts에서 실패했을 것입니다. 1-가능한 인스턴스 선언의 총 수가 일치하지 않았고 2-IEnvironmentRepository의 특정 인스턴스 수가 일치하지 않았습니다.
ChrisBint

1
컨테이너의 정확성은 코더에 의해 정의됩니다. 테스트중인 코드와 테스트 자체가 각 수정에 대해 변경되어야한다는 사실은 즉시 알람 벨 울림을 설정합니다. DI는 그 자체가 아니라 목적을위한 수단입니다. 구조 맵을 사용하지 않고 DI 스타일로 코드를 작성하는 것은 완벽하게 가능합니다. 내 견해로는 선의의 단위 테스트가 아닙니다. 물론 컨테이너는 입증되어야하지만 자동화 된 테스트를 통해 그렇게하는 것의 효과는 여기에 제공된 제한된 정보로 인해 다소 약한 것 같습니다.
로비 디

2
단위 테스트는 10 분이 걸렸습니다. 배포하는 데 1 시간 이상 걸릴 수 있습니다.
ChrisBint

1
주어진 단위 테스트의 일부는 구성에서 단일 라인의 존재를 구체적으로 검증하여 어떻게 더 고립되지 않았는지 확실하지 않습니다. 내가 동의 할 수있는 일반적인 수
ChrisBint

1
그들에게 약간의 마일리지가있을 수 있습니다-당신을 정말로 판단해야합니다. 그러나 물리적으로 또는 일부 속성을 통해 분리해야합니다.
로비 디

0

의존성 주입 컨테이너의 책임은 하나의 작업 애플리케이션에서 다른 모듈을 접착하는 것 입니다.

응용 프로그램에 대해 자동화 된 테스트를 작성하는 경우 "끝에서 끝까지"테스트를 실행하는 "통합 (또는 수락)"테스트가 거의 없어야합니다.이 테스트는 응용 프로그램의 전체 파이프 라인을 테스트하여 특정 테스트 사례에 관련된 모든 모듈이 서로 붙어 있습니다. 올바르게 .

따라서 종속성 주입 컨테이너가 올바르게 구성되지 않은 경우 이러한 통합 테스트가 실패합니다. 통합 테스트는 컨테이너 구성에서 가능한 오류를 나타 내기 때문에 컨테이너 자체에 대한 단위 테스트를 쓸모 없게 만듭니다.

통합 테스트에서 가능한 모든 테스트 사례를 다룰 필요는 없습니다. UI에서 데이터베이스에 이르는 전체 기능을 다루는 기능 당 하나의 테스트 사례 만 있습니다.

통합 테스트 사례가 특정 종속성의 인스턴스화를 다루지 않는 경우 간단히 추가합니다.

통합 테스트를 통해 구성에 대한 단위 테스트를 다시 작성하지 않고도 컨테이너를 자유롭게 변경할 수 있습니다.


0

IMO의 답은 다음과 같습니다.

  1. 유효한 단위 테스트입니까-우리는 컨테이너 맵의 구성이 아닌 컨테이너의 구성을 테스트하고 있습니다 (그러나 중복을 볼 수는 있습니다)

    • 단일 테스트는 특정 코드를 테스트하고 구현 된 로직을 테스트하기 위해 필요한 경우 모든 종속성을 조롱하기 때문에 프로젝트가 아닌 structuremap 에 대한 유효한 단위 테스트입니다 . 구성 로직은 구조 맵 내에서 구현 되므로이 라이브러리 잘 테스트 해야 하며 언급 한 것과 같은 단위 테스트 를 포함해야합니다 . 더 많은 : 이와 같은 수백 가지 테스트가 포함되어 런타임에 여러 구성을 동적으로 조롱하고 테스트해야합니다. 컨테이너는 정상적으로 동작합니다.
  2. 그렇지 않은 경우 테스트하지 않고 구성을 어떻게 검증 할 수 있습니까? 실수로 필요한 코드 줄을 삭제하고 체크인하는 것을 어떻게 막을 수 있습니까?

    • 필요한 환경에서 구성을 수동으로 테스트 할 수 있으며, 필요한 특정 구성을 테스트하는 자동화 (자동 테스트)를 만들 수도 있습니다 (런타임시 작업을 조롱 할 필요 없음).
  3. MyClass 단위 테스트가 컨테이너에서 IEnvironmentRepository 인스턴스를 확인하고이를 전달해야합니까?

    • 아니요, 의존성을 모의하고 MyClass 논리를 격리 된 방식으로 테스트하기 때문에 이것은 완벽한 단위 테스트입니다.

-1

UnitTest 는 분리 된 유닛의 원하는 동작 을 확인 합니다 .

이것은 모든 종류의 구성UnitTests 의 범위에 있지 않다는 것을 의미합니다 .

그럼에도 불구하고 구성에 대한 자동 테스트가 있어야하지만 UnitTests 는 아닙니다 ...


Units의 정의는 어디서 얻습니까?
ChrisBint

나는 단위 테스팅의 예술 에서 Roy Osherove 중 하나를 좋아합니다 . 단위는 같은 이유가있는 (생산-) 코드 덩어리입니다. 나는 내 세상이 일반적으로 단일 클래스에서 최대 3 또는 5까지의 범위입니다 ...
Timothy Truckle

테스트중인 프로덕션 코드입니다.
ChrisBint

nitpickers 를 산만하게하고 싶었지만 , 다른 방법으로도 작동하지 않을 것이라고 생각했습니다 ...; o)
Timothy Truckle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.