단위 테스트 : Linq를 사용한 지연된 어설 션


18

이와 같이 지연된 어설 션을 추가해도 괜찮습니까?

var actualKittens = actualKittens.Select(kitten => {
    Assert.IsСute(kitten);
    return kitten
});

왜? 따라서 구체화 된 컬렉션을 기대하는 진술로도 한 번만 반복 할 수 있습니다.

CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

또한 Select 일뿐 만 아니라 반복자가 정의되어 있고 많은 검사 및 논리 (예 : 계산 및 필터링)가있는 메소드가 될 수 있습니다.

의심의 씨앗은 테스트 실패시 그러한 코드를 읽고 디버깅하는 복잡성입니다.


1
나는하지 않을 의존하고 테스트하기 위해 이것에 대한하지만 더 나은 솔루션이없는 경우 프로덕션 코드에서이 작업을 수행하기 위해 때때로 확인합니다. 자신을 도우미 기능 sequence.WithSideEffect(item => Assert.IsCute(item))으로 만들어 더 깨끗하게 만들 수 있습니다.
usr

@ usr 당신이 그런 방식의 주요 결함을 잡은 것처럼 보입니다-반복자의 부작용.
SerG

여전히 목록을 생성하고 다시 비교하기 위해 두 번 반복하지 않아도 expectedKittens됩니까? 메소드 호출 뒤의 반복을 숨겼습니다.
IllusiveBrian

@IllusiveBrian 이런 의미에서, 예, 그렇습니다. 그것은 여전히 ​​additional보다 적습니다 .All().
SerG

답변:


37

[..]와 같은 지연된 어설 션을 추가해도 괜찮습니까?

아니 , 그렇지 않습니다. 왜? 어떤 이유로 든 두 번째 주장을 제거하면 테스트가 여전히 녹색으로 바뀌고 여전히 작동한다고 생각하지만 컬렉션이 열거되지는 않습니다. 독립적 인 어설 션이 둘 이상있는 경우이 중 하나를 비활성화하더라도 작업을 계속 수행합니다.

이 조합을 고려하십시오.

Assert.IsTrue(actualKittens.All(x => x.IsCute());
CollectionAssert.AreEquivalent(expectedKittens, actualKittens.ToList());

이제 어설트 중 하나를 비활성화하거나 제거하더라도 다른 하나는 여전히 작업을 수행합니다. 또한 컬렉션을 구체화하는 것을 잊어 버린 경우 실행하는 데 시간이 오래 걸릴 수 있지만 여전히 작동합니다. 독립적 인 테스트는 더욱 강력하고 신뢰할 수 있습니다.

두 번째 아니오도 있습니다. 다른 프레임 워크가 어떻게 처리하는지 잘 모르겠지만 MS 테스트 플랫폼을 사용하는 경우 어떤 테스트가 실패했는지 알 수 없습니다. 실패한 테스트를 두 번 클릭하면 실패한 것으로 표시 CollectionAssert되지만 실제로 중첩 된 Assert것이 잘못되어 디버그하기가 매우 어렵습니다. 예를 들면 다음과 같습니다.

    [TestMethod]
    public void TestMethod()
    {
        var numbers = new[] { 1, 2, 3 }.Select(x =>
        {
            Assert.Fail("Wrong number.");
            return x;
        });

        // This will fail and you won't be sure why.
        CollectionAssert.AreEqual(new[] { 1, 2, 3 }, numbers.ToList()); 

    }

즉, 첫 번째 테스트는 버그를 찾는 데 도움이되지 않으므로 실제로는 쓸모가 없습니다. 숫자가 유효하지 않거나 두 컬렉션이 다르기 때문에 실패했는지 여부를 알 수 없습니다.


왜? 구체화 된 컬렉션을 기대하는 진술로도 한 번만 반복 할 수 있습니다.

왜 신경 쓰는지 궁금 하신가요? 이것들은 단위 테스트입니다. 모든 비트를 최적화 할 필요는 없으며 일반적으로 테스트에는 수백만 개의 항목이 필요하지 않으므로 성능에 문제가 없습니다.

그러한 테스트를 유지해야하므로 왜 더 복잡한 테스트를해야합니까? 작동하는 간단한 주장을 작성하십시오.


어떤 이유로 든 제어 흐름에 어설 션을 묻어 야하는 경우 중첩 된 어설 션 이전에 증분 ​​/ 설정된 카운터 / 플래그를 유지하는 것이 한 가지 방법입니다. 나중에이 카운터를 확인하여 예상 제어 흐름이 수행되었다고 주장 할 수 있습니다. 완벽하지는 않지만 대부분의 첫 번째 비판을 다룹니다.
amon

1
또한 귀하 또는 다른 사람이 6 개월 후에 연기 된 주장으로 돌아와서이를 파악하는 데 시간을 낭비해야합니다.
DavidTheWin

귀하의 예에 문제가 있습니다. 호출 ToList하면 열거 형을 반복하지 않습니까?
RubberDuck

1
예 @RubberDuck, 그것은 그것도 아닙니다에서 그러나 실패 할 수 있습니다 것입니다 Assert.Fail만에 CollectionAssert당신은 실제로 주장 잘못되는 말을 할 수 없습니다. VS가 초점을 맞추지 않고 Assert.Fail다른 것에 집중한다는 것을 의미 합니다.
t3chb0t
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.