문제

때때로 나는 아무것도 주장하지 않는 단위 테스트를 접하게 됩니다.오늘 아침에 제가 접한 특별한 예는 조건이 충족되었을 때 로그 파일이 기록되는지 테스트하는 것이었습니다.오류가 발생하지 않으면 테스트가 통과되었다고 가정했습니다.

나는 개인적으로 이것에 대해 문제가 없지만, 연관된 어설션이 없는 단위 테스트를 작성하는 것은 약간의 "코드 냄새"인 것 같습니다.

이에 대한 사람들의 견해는 어떤지 궁금하십니까?

도움이 되었습니까?

해결책

이것은 공식적인 방법이 될 것입니다.

// Act
Exception ex = Record.Exception(() => someCode());

// Assert
Assert.Null(ex);

다른 팁

그것은 단순히 매우 최소한의 테스트이며, 그와 같이 문서화되어야합니다. 실행할 때 폭발하지 않음을 확인합니다. 이와 같은 테스트의 최악의 부분은 잘못된 보안 감각을 제시한다는 것입니다. 코드 적용 범위는 증가하지만 환상적입니다. 매우 나쁜 냄새.

주장이 없다면 테스트가 아닙니다.

게으른 종료 - 어설 션을 얻는 방법을 알아내는 데 약간의 시간이 걸릴 수 있지만, 그것이 기대했던 일을 알기 위해 가치가 있습니다.

이것들은 다음과 같습니다 연기 테스트 그리고 일반적입니다. 그들은 기본적인 정신 점검입니다. 그러나 그들은 당신이 가진 유일한 종류의 테스트가되어서는 안됩니다. 다른 테스트에서 여전히 어떤 종류의 검증이 필요합니다.

그런 테스트는 냄새가 난다.파일이 기록되었는지, 적어도 수정된 시간이 업데이트되었는지 확인해야 합니다.

나는 이런 식으로 작성된 테스트 중 아무것도 테스트하지 않는 테스트를 꽤 많이 보았습니다.코드는 작동하지 않았지만 폭발하지도 않았습니다.

테스트 중인 코드가 예외를 발생시키지 않아야 한다는 명시적인 요구 사항이 있고 이 사실을 명시적으로 호출하려는 경우(요구 사항 문서로 테스트) 다음과 같이 할 것입니다.

try
{
  unitUnderTest.DoWork()
}
catch
{
  Assert.Fail("code should never throw exceptions but failed with ...")
}

...하지만 이것은 여전히 ​​나에게 약간의 냄새가 난다. 아마도 그것이 부정적인 것을 증명하려고 하기 때문일 것이다.

어떤 의미에서, 당신은 코드가 예외를 던지지 않는다는 암시 적 주장을하고 있습니다. 물론 실제로 파일을 잡고 적절한 줄을 찾는 것이 더 가치가 있지만, 나는 아무것도 아닌 것보다 낫다고 생각합니다.

일반적으로, 나는 이것이 통합 테스트에서 발생하는 것을 본다. 이 경우 나는 그것과 함께 쿨합니다.

반복해서 보았을 것 같아요 단위 테스트 테스트가 얼마나 유용한 지 궁금합니다.

편집 : OP가 제공 한 예제에는 몇 가지 테스트 가능한 결과 (로그 파일 결과)가 있으므로 오류가 발생하지 않으면 작동하지 않는다고 가정합니다.

특히 대안이 전혀 테스트하지 않는 경우 좋은 실용적인 솔루션이 될 수 있습니다.

문제는 불리는 모든 기능이 No-OPS 인 경우 테스트가 통과된다는 것입니다. 그러나 때로는 부작용이 당신이 기대했던 것을 확인하는 것이 불가능합니다. 이상적인 세상에서는 모든 테스트에 대한 수표를 작성하기에 충분한 시간이있을 것입니다. 그러나 나는 거기에 살지 않습니다.

내가이 패턴을 사용한 다른 장소는 단위 테스트와 함께 일부 성능 테스트를 포함시키는 것입니다. 왜냐하면 모든 빌드를 실행할 수있는 쉬운 방법이기 때문입니다. 테스트는 아무것도 주장하지 않지만 테스트가 얼마나 오래 걸렸는지 측정하고 기록합니다.

나는 전에 이런 것을 본 적이 있으며 코드 커버리지 번호를 올리기 위해 이루어 졌다고 생각합니다. 아마도 코드 동작을 실제로 테스트하는 것은 아닙니다. 어쨌든, 나는 명확성을 위해 시험에 문서화되어야한다는 데 동의합니다.

테스트의 이름은 이것을 문서화해야합니다.

void TestLogDoesNotThrowException(void) {
    log("blah blah");
}

테스트는 주장없이 로그가 작성되었는지 어떻게 확인합니까?

나는 내가 올바르게 기록하고 있음을 확인한 단위 테스트를 한 적이 없다는 것을 인정해야한다. 하지만 나는 그것에 대해 생각했고 이것을 발견했습니다 논의 Junit 및 Log4J로 어떻게 할 수 있는지에 대한 것입니다. 너무 예쁘지는 않지만 작동하는 것처럼 보입니다.

테스트는 항상 무언가를 주장해야합니다. 그렇지 않으면 무엇을 증명하고 있으며, 코드가 작동한다는 증거를 지속적으로 재현 할 수 있습니까?

우리는 항상 이것을합니다. 우리는 jmock을 사용하여 의존성을 조롱하기 때문에 Jmock 프레임 워크가 우리를 위해 주장을하고 있다고 생각합니다. 그러나 그것은 다음과 같습니다. 테스트하려는 컨트롤러가 있습니다.

Class Controller {
  private Validator validator;

  public void control(){
    validator.validate;
  }

  public setValidator(Validator validator){ this.validator = validator; }
}

이제 컨트롤러를 테스트 할 때는 자체 테스트가 있기 때문에 유효성 검사기를 테스트하고 싶지 않습니다. 따라서 우리는 Jmock과 함께 테스트를 통해 Validate를 호출하도록합니다.

public void testControlShouldCallValidate(){
  mockValidator.expects(once()).method("validate");
  controller.control;
}

그리고 그게 전부입니다. 볼 수있는 "어설 션"은 없지만 제어를 호출하고 "검증"메소드가 호출되지 않으면 JMock 프레임 워크가 예외를 던집니다 ( "예상 메소드가 호출되지 않은 것"또는 무언가).

우리는 모든 곳에있는 사람들이 있습니다. 기본적으로 주장을 설정 한 다음 테스트 된 방법을 호출하기 때문에 조금 뒤로 뒤떨어집니다.

나는 때때로 선택한 단위 테스트 프레임워크(NUnit)를 사용하여 코드의 특정 부분에 대한 진입점 역할을 하는 메서드를 구축합니다.이러한 방법은 코드 하위 집합의 성능, 메모리 소비 및 리소스 소비를 프로파일링하는 데 유용합니다.

이러한 메서드는 확실히 단위 테스트가 아닙니다. [시험] 속성) 항상 무시되도록 플래그가 지정되며 소스 제어에 체크인될 때 명시적으로 문서화됩니다.

또한 저는 때때로 이러한 메서드를 Visual Studio 디버거의 진입점으로 사용합니다.저는 Resharper를 사용하여 테스트에 직접 들어간 다음 디버깅하려는 코드로 들어갑니다.이러한 방법은 소스 제어까지 도달하지 못하거나 고유한 어설션을 획득합니다.

내 "실제" 단위 테스트는 일반적인 TDD 주기 동안 구축되며 항상 직접적으로는 아니지만 항상 무언가를 주장합니다. 때로는 주장이 조롱 프레임워크의 일부이고 때로는 유사한 주장을 단일 메서드로 리팩터링할 수 있습니다.리팩터링된 메서드의 이름은 명확하게 알 수 있도록 항상 "Assert"라는 접두사로 시작됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top