이 경우 테스트 당 하나의 어설 션을 어리석은 일관성으로 유지합니까?


10

테스트하고있는 수업이 있습니다. 이 클래스에는 기능이 있습니다.apply(List<IRule> rules, List<ITarget> targets);

한 번의 테스트에서 각 대상이 하나의 규칙 a에 전달되었는지 확인하고 싶습니다.

rule1.AssertWasCalled(fnord => fnord.Test(target1));
rule1.AssertWasCalled(fnord => fnord.Test(target2));
rule1.AssertWasCalled(fnord => fnord.Test(target3));

나 자신을 단 하나의 주장 진술로 제한하는 것은 꽤 홉보 블린 이 될 것 같다 . 이 가정에서 정확합니까, 아니면 각 대상이 실제로 테스트되었다고 주장 할 수있는 다른 방법이 있습니까?


fnords를 볼 수 있습니다!
로스 패터슨

답변:


15

세 가지 주장은 본질적으로 하나의 테스트입니다. 컬렉션에서 메서드의 동작을 테스트하여 각 항목이 특정 호출에 대한 매개 변수인지 확인합니다 (즉, 각 항목이 올바르게 처리되었는지 확인).

데이터를 세 번 그리고 세 가지 다른 방법으로 설정하는 것은 여러 가지 주장을하는 것보다 낭비적이고 읽기 어렵습니다.

단일 어설트 "규칙"은 동일한 방법으로 다른 유형의 어설 션을 만드는 것에 관한 것입니다 (본질적으로 다른 것들을 테스트하는 것).이 경우에는 단일 행동을 테스트하는 경우에는 실제로 적용되지 않습니다.


3
실제로 : 규칙은 단위 테스트 당 하나 이상의 논리적 주장입니다. 다른 테스트에서 재사용 할 수 있도록 하나의 상위 레벨 그룹으로 그룹화 할 수 있습니다.
Laurent Bourgault-Roy

5

이 규칙이 테스트 규칙마다 하나의 문제에 집중되도록하기 위해 존재한다고 생각합니다. 한 번의 테스트로 20 가지를 테스트하면 실제로 적용 범위를 파악하기가 어렵습니다. 단어 단어없이 테스트 방법의 이름을 지정할 수 없을 때 문제가 발생한다는 것을 알고 있습니다 . 예를 들어 테스트 방법의 이름이보다 정확하게 지정되면 testFooIsTrueAndDbExistsAndBarIsNullAndAnExceptionDoesntOccur()한 테스트에서 너무 많이 테스트하는 것입니다.

귀하의 경우에는 3 번 주장해도 괜찮습니다. 코드를 더 읽기 쉽게하려면이 세 가지 어설 션을 이름이 지정된 메서드로 추출 할 수 있습니다 assertWasCalledOnTargets(...).


3

특정 예제의 경우 다음과 같은 작업을 수행하는 경우 "하나"주장 문을 사용하여 벗어날 수 있습니다.

foreach target in targets
{
     rule1.AssertWasCalled(fnord => fnord.Test(target))
}

한 번의 테스트에서 여러 번의 주장을하는 것에 대해 죄책감을 느끼지 않기 위해하는 일입니다.


나는 전에 이것을 한 적이있다. 가는 나쁜 길은 아닙니다. 읽기 쉬우 며 수행하는 작업의 특성을 이해할 수 있습니다.
CokoBWare

1

나도 이것으로 고투했다.

순수 주의자는 내 테스트마다 한 번의 주장을 주장하므로 상황이 어디에서 터 졌는지 정확히 알 수 있습니다.

그런 다음 동일한 중복 테스트 설정 코드를 많이 잘라 붙여 넣습니다. 이것의 세 번째 또는 네 번째 계층 이후에, "Oy! 충분히!"라고 말하기 시작합니다.

나의 타협은 "절대로"깨지지 않는 측면을 찾는 것이었다. 그리고 그 조각들을 함께 쌓은 다음 깨질 수있는 새로운 요소 하나 를 추가하겠습니다 . 한 번의 테스트에서 여러 개의 휘발성 영역을 계층화하면 이러한 타협을 위반하게됩니다.


1
당신은 체크 아웃해야합니다 Assume. 나는 오늘 그것에 대해 배웠다.
Wayne Werner

1

에 대한 설정 코드가에 대한 설정 코드와 target1다른 경우 target2,이 유형의 코너 절단은 결국 너무 긴 테스트 초기화 코드를 초래하는 경향이 있습니다. 이것은 차례로 혼란 스럽거나 리팩터링되고 재사용되는 결과를 낳습니다. 테스트가 리팩토링을 정당화하기에 충분히 복잡한 경우 테스트는 둘 이상의 것을 테스트하는 것입니다.

각 대상의 설정 코드가 본질적으로 동일하면 테스트를 여러 개의 개별 테스트로 나누는 것이 과도 할 수 있습니다.

경우 target1target2동일한 인터페이스의 구현이 다른 경우는, 대신 인터페이스에 단위 테스트를 추가 (및 테스트 프레임 워크는 해당 인터페이스의 모든 구현을위한 테스트를 생성 할 수있게)해야한다.

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