단위 테스트 코딩 표준


22

일반적으로 코딩 표준에 대해 이야기 할 때 프로그램 자체의 코드를 참조하지만 단위 테스트는 어떻습니까? 단위 테스트에 고유 한 특정 코딩 표준 지침이 있습니까? 그들은 무엇인가?

답변:


12

머리 꼭대기에서 테스트 코드의 코딩 스타일에 세 가지 차이점이 있다고 생각할 수 있습니다.

이름 지정 테스트 방법에서의 패턴을 따릅니다 shouldDoSomethingWhenSomeConditionHolds.

테스트 내에서 다음 간격 패턴을 따르는 것이 일반적입니다.

@Test
shouldReturnAccountBalenceWhenGetBalenceIsCalled() {
    // Some lines 
    // of setup code
    // go here.

    // The action being tested happens after a blank line.

    // An assertion follows another blank line.
}

일부는 테스트 당 하나의 주장 만 주장하지만 이것은 보편적 인 것과는 거리가 멀다.

DRY (Do n't Repeat Yourself)는 프로덕션 코드보다 테스트 코드에서 고려해야 할 사항이 아닙니다. 일부 반복되는 코드는 setUp 메소드 또는 testUtils 클래스에 배치해야하지만 테스트 코드에서 반복을 0으로 유지하려고하면 리팩토링을 방해하는 밀접하게 결합되고 유연성이없는 테스트가 발생합니다.


물론 다양한 패턴이 있기 때문에 답변도 제공해야합니다.
Eric Wilson

10
이것이 Arrange, Act, Assert 패턴입니다.
StuperUser

건조는 여전히 중요합니다. 여러 테스트에서 동일한 어설 션을 수행해야하는 경우 공통 함수를 작성하고 모든 테스트에서 호출하십시오.
MiFreidgeim SO- 스톱 사악한

@MichaelFreidgeim 어쩌면 우리는 정도에 대해 이야기하고 있지만 테스트 코드에서 반복에 대한 허용 오차가 상당히 높습니다. 반복이 거의없는 테스트 스위트를 구축 한 경험이 몇 가지 있는데, 요구 사항이 변경되면 테스트를 수정하고 이해하기가 어려워졌습니다. 그런 다음 테스트에서 DRY에 대해 걱정하지 않고 테스트 스위트를 사용하기가 더 쉬워졌습니다. <shrug>
Eric Wilson

16

Roy Osherove는 테스트 이름을 지정할 때 다음 패턴을 권장합니다.

NameOfMethodUnderTest_StateUnderTest_ExpectedBehavior() 

http://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspx를 참조 하십시오


Roy에 동의합니다. ReSharper가 계속 제거해야한다고 NameOfMethodUnderTestStateUnderTestExpectedBehavior()
말하지만

메소드가 오버로드 될 때이 작업을 수행하는 방법, 이름이 같은 메소드가 여러 개있을 수 있습니까?
Narendra Pathai

6

가장 중요한 것은 단위 테스트는 본질적으로 미니 사양이라는 것을 기억하는 것입니다. 이것은 강조가 항상 가독성에 있어야 함을 의미합니다.

첫째, 이것은 이름이 테스트 대상과 주장 대상을 명확하게 전달해야한다는 것을 의미합니다.

둘째, 때로는 잊혀지는 것은 사양으로 행동을 지정하는 것입니다. 즉, 단위 테스트에는 논리가 포함되지 않아야합니다. 또는 잠재적으로 테스트보다는 프로그램 기능을 반복하는 함정에 빠질 수 있습니다.

테스트에는 설정이 복잡한 개체가 포함되는 경우도 있으므로,이 설정 논리를 개체 어머니테스트 데이터 빌더 와 같은 것을 사용하여 테스트와 별도로 유지하도록 노력해야합니다 .

몇 가지 책 권장 사항으로 마무리하겠습니다.

xUnit 테스트 패턴 : 리팩토링 테스트 코드 : 훌륭한 책, 일부는 약간 건조하다고 생각하지만 그렇게 생각하지 않습니다. 다양한 테스트 구성 방법과 유지 관리 방법에 대해 자세히 설명합니다. NUnit 등과 같은 것을 사용하는 경우 관련이 있습니다.

단위 테스팅의 기술 : .Net의 예제 : 테스트 작성 및 유지 관리에 대한 최고의 책. 정말 새롭음에도 불구하고 AAA 구문이 이제는 다른 표준 방법이 아닌 표준이 되었기 때문에 조롱 섹션이 이미 약간 발견되었습니다.

테스트를 통해 성장하는 객체 지향 소프트웨어 :이 책은 정말 놀랍습니다! 지금까지 최고의 단위 테스트 책과 설계 과정에서 일류 시민으로 단위 테스트를 실시한 유일한 고급 책. 공개 베타 였을 때이 내용을 읽고 있었으며 그 이후로 추천을 받았습니다. 이 책 전체에 걸쳐 사용 된 훌륭한 실제 작업 사례. 로이의 책을 먼저 읽는 것이 좋습니다.


IMHO 단위 테스트에는 논리가 포함되어 있으면됩니다. 올바른 동작을 결정하기 위해 동일한 작업을 수행하는 순진 알고리즘을 사용하여 최적화 된 효율적인 알고리즘 버전을 테스트하는 것이 매우 합리적입니다. 예를 들어, 선형 검색 기반 연관 배열을 작성하여 해시 테이블을 테스트한다고 가정하십시오.
dsimcha

2
예, 그러나 테스트 데이터 빌더에서 테스트 외부에 속합니다 (내부 논리가 사소하지 않은 경우 자체 테스트해야 함). 이에 대한 예외는 일반적으로 "신뢰되어"정확하고 테스트없이 사용될 수있는 타사 라이브러리입니다.
FinnNk

3

단위 테스트에 논리를 넣지 마십시오. 예를 들어, add 메소드를 테스트한다고 가정하면 다음과 같은 것을 가질 수 있습니다.

void MyTest_SaysHello()
{
   string name = "Bob";
   string expected = string.Format("Hello, {0}", name);
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello(name);
   Assert.AreEqual(expected, actual);
}

이 특정한 경우에 테스트에서와 동일한 논리를 반복 할 가능성이 있으므로 "1 + 1 == 2"가 아닌 "1 + 1 == 1 + 1"을 테스트하는 것입니다. "실제"테스트. 테스트 코드의 모양은 다음과 같습니다.

void MyTest_SaysHello()
{
   string expected = "Hello, Bob";
   IMyObjectType myObject = new MyObjectType();
   string actual = myObject.SayHello("Bob");
   Assert.AreEqual(expected, actual);
}

2
작은 수정 : 나는 'string expect = string.Format ( "Hello, Bob")'이 'string expect = "Hello, Bob"'이어야한다고 생각합니다.
Mike Rosenblum

@MikeRosenblum 당신은 분명히 바로, 누군가는 그것을 해결하기 위해 노력하고 있지만이 검토이 편집 거부
콘라드 Morawski

@ Konrad : 이상합니다. 이것은 프로그래밍 포럼입니다.
Mike Rosenblum

Mike Rosenblum이 제안한대로 답변을 다시 편집했습니다.
bdsl

0

길고 설명적인 메소드 이름. 테스트 메소드는 코드에서 호출되지 않습니다 (반사를 통해 메소드를 발견하고 호출하는 단위 테스트 실행자가 호출 함). 미쳐서 50-80 자 길이의 메소드 이름을 갖는 것이 좋습니다. 특정 이름 지정 규칙 (낙타, 밑줄, "해야한다", "필수", "언제", "주어진"등)은 이름이 세 가지 질문에 대답하는 한 실제로 중요하지 않습니다.

  • 테스트중인 것은 무엇입니까?
  • 조건은 무엇입니까?
  • 예상되는 결과는 무엇입니까?

시험 방법은 짧아야한다 .

테스트 방법은 단순하고 선형적인 구조를 가져야합니다 . if 또는 loop 구문이 없습니다.

테스트 방법은 "arrange-act-assert"패턴을 따라야합니다 .

각 테스트는 한 가지를 테스트해야합니다 . 이것은 일반적으로 테스트 당 하나의 주장을 의미합니다. 테스트 등 { Do A; Assert B; Assert C; }두 가지로 리팩토링해야합니다 { Do A; Assert B; }{ Do A; Assert C; }

임의의 데이터 또는 'DateTime.Now'와 같은 것을 피하십시오

테스트가 끝날 때 모든 테스트 픽스처 멤버가 원래 상태로 돌아 왔는지 확인하십시오 (예 : 분해 )

프로덕션 코드에서 무의식적으로 중복을 제거하더라도 테스트 픽스처의 코드 중복은 훨씬 작은 문제입니다.


-1

Farmboy가 이미 언급 한 것과 다소 비슷합니다. 내 메소드 이름 형식

 <MethodName>Should<actionPerformed>When<Condition>

예 :

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