단위 테스트 명명 모범 사례 [닫기]


564

단위 테스트 클래스 및 테스트 방법의 이름을 지정하는 가장 좋은 방법은 무엇입니까?

이것은 이전에 SO에 대해 논의 되었습니다. 단위 테스트에 대한 인기있는 명명 규칙은 무엇입니까?

이것이 매우 좋은 접근법인지는 모르겠지만 현재 테스트 프로젝트에서 각 프로덕션 클래스와 테스트 클래스 사이에 일대일 매핑이 있습니다 (예 : Product및) ProductTest.

테스트 클래스에는 테스트 할 메소드 이름, 밑줄, 상황 및 예상되는 상황이 포함 된 메소드가 있습니다 (예 :) Save_ShouldThrowExceptionWithNullName().



1
이것은 귀하의 질문에 대답하지 않지만 읽을 가치가 있습니다 : haacked.com/archive/2012/01/02/structuring-unit-tests.aspx
Robs

3
Google 스타일 가이드 test<MethodUnderTest>_<state>: testPop_emptyStack google-styleguide.googlecode.com/svn/trunk/javaguide.html 5.2.3 메서드 이름. 확실하지 않은 경우 Google을 따르십시오.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
@CiroSantilli 六四 事件 法轮功 包 卓 轩 그리고 다음 문장은 "테스트 방법의 이름을 정하는 올바른 방법은 없습니다"라고 말합니다. 그림을 이동.
user2418306

1
필자는 몇 년이 지난 후에도 필 하크의 추천을 선호합니다 .
pimbrouwers

답변:


524

같은 I 로이 Osherove의 네이밍 전략 , 다음입니다 :

[UnitOfWork_StateUnderTest_ExpectedBehavior]

메소드 이름과 구조화 된 방식에 필요한 모든 정보가 있습니다.

작업 단위는 단일 메소드, 클래스 또는 여러 클래스만큼 작을 수 있습니다. 이 테스트 사례에서 테스트하고 통제 할 모든 사항을 나타내야합니다.

어셈블리의 경우 나는 전형적인 .Tests 끝을 클래스에 대해 매우 광범위하고 동일하다고 생각합니다 Tests.

[NameOfTheClassUnderTestTests]

이전에는 테스트 대신 Fixture를 접미사로 사용했지만 후자가 더 일반적이라고 생각하고 명명 전략을 변경했습니다.


228
나를 위해 메소드 이름을 테스트 메소드에 넣는 것은 의미가 없습니다. 방법의 이름을 바꾸면 어떻게 되나요? 리팩토링 도구는 테스트 이름을 변경하지 않습니다. 결국 손으로 테스트 방법의 이름을 바꾸거나 이름이 잘못 지정된 테스트가있을 수 있습니다. 댓글과 같습니다. 훨씬 더 나쁜 것은 코드에 주석을 달지 않는 것입니다.
Piotr Perak

80
@Peri, 나는 그것이 절충이라고 생각합니다. 한편으로는 테스트 이름이 구식이 될 수 있으며, 다른 한편으로는 테스트가 테스트하는 방법을 알 수 없습니다. 후자가 훨씬 더 자주 나타납니다.
Joel McBeth

15
Peri의 의견을 추가하기 위해-모든 방법은 어떤 행동에 책임이 있습니다 UpdateManager.Update(). 마음이 갖는 내 테스트 전화를하는 경향이 WhenUpdating_State_Behaviour또는 WhenUpdating_Behaviour_State. 이렇게하면 메서드 이름을 테스트 이름에 넣지 않고 클래스의 특정 동작을 테스트 할 수 있습니다. 그러나 가장 중요한 것은 실패한 테스트의 이름을 볼 때 비즈니스 로직이 실패한 실마리를 가져야한다는 것입니다.
Ramunas

8
Resharper와 IntelliJ는 아마도 테스트 방법을 찾고 해당 도구를 사용하여 리팩토링 / 이름을 바꾼 경우 이름을 바꿀 것을 제안합니다. 또한 메소드 이름을 언급하고 주석도 업데이트하는 주석을 찾아보십시오.
Jeff Martin

62
좋은 메소드 이름은 종종 메소드가 수행하는 조치와 동일합니다. 분석법 또는 시험 수행 후 시험 명명 을 결정해야하는 경우 시험 법의 이름을 바꿔야 할 수도 있습니다 . (모든 경우에 해당되지는 않음)
Kaadzia

121

테스트 픽스처의 이름을 지정하는 동안 테스트에 대한 "Should" 이름 지정 표준 을 따르고 싶습니다. 유닛 (예 : 클래스) .

설명하기 (C # 및 NUnit 사용) :

[TestFixture]
public class BankAccountTests
{
  [Test]
  public void Should_Increase_Balance_When_Deposit_Is_Made()
  {
     var bankAccount = new BankAccount();
     bankAccount.Deposit(100);
     Assert.That(bankAccount.Balance, Is.EqualTo(100));
  }
}

"해야" ?

테스트 작성자가 "[일부 상태에있을 때] [후 / 전 / 일] [조치가 수행되어야 함"] 줄에 문장으로 테스트 이름을 지정해야한다는 것을 알게되었습니다.

그렇습니다. "Should"를 어디에나 쓰는 것은 약간 반복적이지만 필자가 말한 것처럼 작가가 올바른 방식으로 생각하도록 강요합니다 (초보자에게는 좋을 수 있습니다). 또한 일반적으로 읽을 수있는 영어 테스트 이름이됩니다.

업데이트 :

나는 지미 Bogard는 '해야'의 팬이기도 한 것으로 나타났습니다 심지어이라는 단위 테스트 라이브러리가 한다는 .

업데이트 (4 년 후 ...)

관심있는 사람들을 위해, 테스트 이름 지정에 대한 나의 접근 방식은 수년에 걸쳐 진화했습니다. 위에서 설명한 should 패턴 의 문제 중 하나는 테스트중인 방법을 한 눈에 알기 쉽지 않은 것으로 설명합니다. OOP의 경우 테스트중인 메소드로 테스트 이름을 시작하는 것이 더 합리적이라고 생각합니다. 잘 설계된 클래스의 경우 읽을 수있는 테스트 메소드 이름이 있어야합니다. 이제와 비슷한 형식을 사용합니다 <method>_Should<expected>_When<condition>. 문맥에 따라 분명히 당신은 should / When 동사를 더 적절한 것으로 대신하고 싶을 것입니다. 예: Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()


32
어쩌면 더 좋고 덜 중복 될 수 increasesBalanceWhenDepositIsMade()있습니다. 테스트가 작동한다고 가정하면 그 내용을 알려주는 문장을 작성하십시오 .
hotshot309

3
최근에 비슷한 명명 규칙을 언급 한 기사를 보았습니다. 테스트 픽스처별로 정렬 할 때 테스트 목록을 쉽게 읽을 수 있도록 설계되었습니다. "BankAccount"와 같은 줄 아래에 (다른 줄에) "Should_Increase_Balance_When_Deposit_Is_Made" "Should_Decrease_Balance_When_Withdrawal_Is_Made"등. TDD와 관련된 사양과 매우 흡사합니다.
Simon Tewsi

기사를 찾았습니다. Justin Etheredge의 CodeThinked 블로그 Moq 3을 이용한 모의 시작 – 1 부에 있습니다.
Simon Tewsi

11
나는 또한 When and When를 사용하지만 다른 방법으로 사용합니다. 예 : WhenCustomerDoesNotExist_ShouldThrowException (). 나에게 이것은 When then When보다 훨씬 더 의미가있다 (즉, 특정 시나리오에서 예상되는 특정 결과가 있어야한다). 이것은 또한 AAA (Arrange, Act, Assert)
와도 일치

2
@Schneider : "should"= "recommended"를 고려한 다음 선택 사항으로 생각합니다. "shall"= "must"를 사용하는 것이 lexicaly가 더 나은 것이 아니라 필수 / 필수입니다. 예를 들어, RFC는 둘 사이의 차이를 만듭니다. 테스트를 통과하는 것이 권장되거나 필요합니까?
blackwizard

79

나는이 명명 스타일을 좋아한다 :

OrdersShouldBeCreated();
OrdersWithNoProductsShouldFail();

등등. 테스터가 아닌 사람에게는 문제가 무엇인지 분명하게 알 수 있습니다.


63
그러나 @ hotshot309, 그는 .NET을 사용할 수 있습니다-.NET 대문자 표기 규칙
Ace

2
@Ace, 나는 당신에 전적으로 동의하며이 의견을 게시 한 지 약 1 분 후에이 사실을 알게되었습니다. 나는 내 실수를 보았을 때 그것을 삭제했다고 맹세했지만 어쨌든 나는 그렇지 않았다고 생각합니다. 미안합니다.
hotshot309

3
@CoffeeAddict 식별자 내의 밑줄이 C #에서 실제로 관용적이 아닌 <del> aberration </ del>이기 때문에
Sklivvz

2
나는 또한 그렇게 should선호 하는 사용법을 피하고 싶습니다willOrdersWithNoProductsWillFail()
Calin

4
@Calin 내 의견으로는 사용 Will이 실제로 적절 하지 않으며 그렇게함으로써 실제로는 독자에게 실수로 테스트에 실패 Will하지 않을 것이라고 말하고 있습니다. 그것을 잘못 사용하는 Should것은 여기에서 더 나은 선택입니다. 왜냐하면 그것은 당신이 무언가를 원한다는 것을 나타 내기 때문입니다.하지만 테스트가 실행되면 실패 / 성공했는지 여부를 알려주므로 실제로는 그것을 암시 할 수 없습니다 사전에, 그것은 그것에 대한 논리적 설명입니다, 당신은 무엇입니까? 왜 피 Should합니까?
Eyal Solnik

51

켄트 벡 은 다음과 같이 제안합니다.

  • '단위'당 하나의 테스트 픽스처 (프로그램 클래스). 시험 설비는 클래스 자체입니다. 테스트 픽스처 이름은 다음과 같아야합니다.

    [name of your 'unit']Tests
    
  • 테스트 케이스 (테스트 픽스처 메소드)의 이름은 다음과 같습니다.

    test[feature being tested]
    

예를 들어 다음과 같은 클래스가 있습니다.

class Person {
    int calculateAge() { ... }

    // other methods and properties
}

테스트 픽스처는 다음과 같습니다.

class PersonTests {

    testAgeCalculationWithNoBirthDate() { ... }

    // or

    testCalculateAge() { ... }
}

4
더 많은 사람들이이 지침을 따르기를 바랍니다. 얼마 전 저는 "ATest", "BasicTest"또는 "ErrorTest"와 같은 이름을 가지고 있기 때문에 20 가지가 넘는 테스트 방법의 이름을 바꿔야했습니다.
웨지

85
클래스의 접미사가 주어지면 'test'의 메소드 접두사가 중복되지 않습니까?
Gavin Miller

50
켄트가 그 책을 썼을 때를 기억하십시오. 속성이 발명되지 않았습니다. 따라서 메소드 이름의 테스트 이름은 테스트 프레임 워크에 메소드가 테스트임을 나타냅니다. 2002 년 이래로 많은 일이 일어났다.
Thomas Jespersen 16:15에

14
testCalculateAge ... 이것은 테스트 방법에 대한 의미없는 이름입니다. "test"는 중복됩니다 ( "method"접두어로 모든 메소드의 이름을 지정 하시겠습니까?). 나머지 이름은 테스트 할 조건이 없거나 예상했던 것입니다. CalculateAge는 테스트중인 방법인가? ..... who knows
bytedev

1
이 전략을 사용할 때 예상되는 출력을 지정하려면 문서가 필요하다는 것을 추가하고 싶습니다. 'test'접두사에 대한 참고 사항으로; 일부 단위 테스트 프레임 워크는 테스트를 인식하기 위해 특정 접두사 또는 접미사가 필요합니다. 'Abstract'가있는 추상 클래스 접두어는 중복으로 간주되지 않습니다 (자체 문서화하기 때문에). 왜 'Test'에 동일하게 적용되지 않습니까?
siebz0r

17

클래스 이름 . 테스트 픽스처 이름의 경우, "Test"는 많은 도메인의 유비쿼터스 언어에서 매우 일반적입니다. 예를 들어, 엔지니어링 도메인 : StressTest및 화장품 도메인 : SkinTest. Kent에 동의하지 않아서 죄송합니다.하지만 테스트 픽스처에서 "Test"를 사용합니다 (StressTestTest ?) 것은 혼란 스럽습니다.

"단위"는 도메인에서 많이 사용됩니다. 예 MeasurementUnit. 라는 클래스입니다MeasurementUnitTest"Measurement"또는 "MeasurementUnit"의 테스트 입니까?

따라서 모든 테스트 클래스에 "Qa"접두사를 사용하고 싶습니다. 예 QaSkinTest를 들어QaMeasurementUnit . 도메인 객체와 혼동되지 않으며 접미사 대신 접두사를 사용하면 모든 테스트 픽스처가 시각적으로 함께 존재한다는 것을 의미합니다 (테스트 프로젝트에 가짜 또는 다른 지원 클래스가있는 경우 유용합니다)

네임 스페이스 . C #에서 일하고 테스트 클래스와 동일한 네임 스페이스에 테스트 클래스를 유지합니다. 별도의 테스트 네임 스페이스를 사용하는 것보다 편리합니다. 물론 테스트 수업은 다른 프로젝트에 있습니다.

테스트 방법 이름 . 메소드 이름을 WhenXXX_ExpectYYY로 지정하고 싶습니다. 사전 조건을 명확하게하고 자동화 된 문서 (La TestDox)를 도와줍니다. 이는 Google 테스트 블로그의 조언과 유사하지만 전제 조건과 기대치가 더 분리되어 있습니다. 예를 들면 다음과 같습니다.

WhenDivisorIsNonZero_ExpectDivisionResult
WhenDivisorIsZero_ExpectError
WhenInventoryIsBelowOrderQty_ExpectBackOrder
WhenInventoryIsAboveOrderQty_ExpectReducedInventory

테스트 메소드 이름과 테스트 픽스처 이름에 대해 이야기했습니다. 테스트 픽스처 이름은 프로덕션 클래스에 맵핑됩니다. 테스트에서 생산 방법 이름을 어디에 쓰십니까?

12

나는 사용하십시오 감안할 - - 그런 때 개념. 이 짧은 기사 http://cakebaker.42dh.com/2009/05/28/given-when-then/을 살펴보십시오 . 기사에서는이 개념을 BDD 측면에서 설명하지만 변경없이 TDD에서도 사용할 수 있습니다.


Given-When-Then은 MethodName_Scenario_ExpectedBehavior와 동일합니까?

1
정확히. Given_When_Then은 다음을 더 참조합니다. GivenAnEntity_WhenSomeActionHappens_ThatResultIsExpected 테스트는 구현이 아닌 동작 을 테스트하려는 의지를 표현해야합니다 .
plog17

1
"Gifn When When"은 종종 작은 오이라고 불립니다. Cucumber, JBehave 및 Behat 도구에서 나온 DSL입니다.
bytedev

+1 이것이 가장 좋은 방법입니다. 메소드가 결과가 기대하는 것과 어떻게 작동 하는지를 분리하는 것은 매우 강력하며 다른 의견에 설명 된 많은 문제를 피합니다.
Lee


7

가장 중요한 것 중 하나는 네이밍 컨벤션에서 일관성이 있다고 생각합니다 (그리고 팀의 다른 멤버들과 동의합니다). 여러 번 같은 프로젝트에 사용 된 다양한 규칙이 있습니다.


7

나는 최근에 설명을 극대화하기 위해 테스트, 클래스 및 프로젝트를 명명하는 다음과 같은 규칙을 생각해 냈습니다.

네임 스페이스 Settings의 프로젝트에서 클래스를 테스트한다고 가정 해 MyApp.Serialization보겠습니다.

먼저 MyApp.Serialization.Tests네임 스페이스를 사용하여 테스트 프로젝트를 만듭니다 .

이 프로젝트와 물론 네임 스페이스에서 IfSettings( IfSettings.cs로 저장 ) 라는 클래스를 만듭니다 .

SaveStrings()방법을 테스트한다고 가정 해 봅시다 . -> 테스트 이름을 지정합니다 CanSaveStrings().

이 테스트를 실행하면 다음과 같은 제목이 표시됩니다.

MyApp.Serialization.Tests.IfSettings.CanSaveStrings

나는 이것이 테스트하고있는 것을 나에게 잘 알려 준다고 생각한다.

물론 영어에서 명사 "Tests"는 동사 "tests"와 같은 것이 유용합니다.

시험의 이름을 정할 때 창의력에는 제한이 없으므로 시험에 대한 완전한 문장 제목을 얻습니다.

일반적으로 테스트 이름은 동사로 시작해야합니다.

예를 들면 다음과 같습니다.

  • 감지 (예 DetectsInvalidUserInput)
  • 예외 (예 ThrowsOnNotFound)
  • 윌 (예 WillCloseTheDatabaseAfterTheTransaction)

기타

다른 옵션은 "if"대신 "that"을 사용하는 것입니다.

후자는 나를 불구하고 키 입력과 내가 알고하지 않기 때문에, 뭐하는 거지 더 정확히 설명 저장 하는 테스트 동작이 존재하지만 테스트입니다 경우 가 있습니다.

[ 편집 ]

위의 명명 규칙을 조금 더 오래 사용한 후에 인터페이스를 사용할 때 If 접두사가 혼동 될 수 있음 을 알았습니다 . 테스트 클래스 IfSerializer.cs 는 "파일 열기 탭"의 ISerializer.cs 인터페이스와 매우 유사하게 나타납니다 . 이것은 테스트, 테스트중인 클래스 및 인터페이스 사이를 전환 할 때 매우 성 가실 수 있습니다. 결과적으로 접두사로 That over If 를 선택 합니다.

또한 이제 다른 곳에서는 모범 사례로 간주되지 않으므로 테스트 클래스의 메소드에만 사용합니다. 테스트 메소드 이름에서 단어를 다음과 같이 구분하는 "_":

[Test] public void detects_invalid_User_Input()

나는 이것을 더 읽기 쉽다는 것을 안다.

[ 편집 종료 ]

테스트가 무엇을하고 있는지 이해하는 데 많은 시간을 절약 할 수 있기 때문에 중요한 이름 지정 테스트를 고려하기 때문에 이것이 더 많은 아이디어를 낳기를 바랍니다. .


2

VS + NUnit에서는 일반적으로 프로젝트에서 폴더를 만들어 기능 테스트를 그룹화합니다. 그런 다음 단위 테스트 픽스처 클래스를 작성하고 테스트중인 기능 유형에 따라 이름을 지정합니다. [Test] 메소드의 이름은 Can_add_user_to_domain다음 과 같습니다.

- MyUnitTestProject   
  + FTPServerTests <- Folder
   + UserManagerTests <- Test Fixture Class
     - Can_add_user_to_domain  <- Test methods
     - Can_delete_user_from_domain
     - Can_reset_password

2

테스트를 동일한 패키지에 보관하지만 테스트 대상 소스의 병렬 디렉토리에 유지하면 많은 제외 패턴을 수행하지 않고 코드를 배포 할 준비가되면 코드의 부풀림이 제거됩니다.

저는 개인적으로 "JUnit Pocket Guide"에 설명 된 모범 사례를 좋아합니다. JUnit 의 공동 저자가 쓴 책을이기는 것은 어렵습니다!


3
이것이 실제로 문제에 대한 답변이라고 생각하지 않습니다. JUnit Pocket Guide를 편집하고 굴절시킬 수 있습니까? 감사!
Nate-Wilkins

0

Foo 클래스의 테스트 케이스 이름은 FooTestCase 또는 이와 유사한 이름 (FooIntegrationTestCase 또는 FooAcceptanceTestCase)이어야합니다. 테스트 케이스이기 때문입니다. 테스트, 테스트 케이스, 테스트 픽스처, 테스트 방법 등과 같은 일부 표준 명명 규칙 은 http://xunitpatterns.com/ 을 참조하십시오 .

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