単体テストの一般的な命名規則は何ですか?[閉まっている]


203

一般的な

  • すべてのテストで同じ基準に従います。
  • 各テストの状態が何であるかを明確にします。
  • 予想される動作について具体的に説明します。

1)MethodName_StateUnderTest_ExpectedBehavior

Public void Sum_NegativeNumberAs1stParam_ExceptionThrown() 

Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown () 

Public void Sum_simpleValues_Calculated ()

出典:単体テストの命名基準

2)各単語をアンダースコアで区切る

Public void Sum_Negative_Number_As_1st_Param_Exception_Thrown() 

Public void Sum_Negative_Number_As_2nd_Param_Exception_Thrown () 

Public void Sum_Simple_Values_Calculated ()

その他の

  • Testでメソッド名を終了する
  • クラス名でメソッド名を開始する

Behavior Driven Developmentを参照してください。
ウェッジ

回答:


94

私はこの一人についてあなたとほとんど一緒です。使用した命名規則は次のとおりです。

  • 各テストの状態を明確にします。
  • 予想される動作について具体的。

テスト名からさらに何が必要ですか?

レイの答えに反して、私はテスト接頭辞が必要だとは思いません。それはテストコードです。コードを識別するためにこれを行う必要がある場合は、より大きな問題が発生するので、テストコードを本番コードと混同しないでください。

アンダースコアとそのテストコードの長さと使用については、誰が気にしていますか?読みやすく、テストの内容が明確である限り、あなたとあなたのチームだけがそれを見ることができます。:)

そうは言っても、私はそれを使って自分の冒険をテストし、ブログに書くのはまだかなり新しいです:)


20
「読みやすく、明確である限り」と「誰が...気にかけているか」というわずかな矛盾。まあ、それが判読不能で明確でないときは誰もが気にするので、それが重要なのです。:-)
デビッドビクター

1
プレフィックスの1つの追加引数。IDEでファイルを検索する場合Test、クラス名で始まるテストケースを簡単に検索できます。クラス名とテストクラス名が同じであれば、私たちは常に2つのファイルのパスを一時停止し、読むために持ってしようとしている
このユーザーはHELPニーズ

@THISUSERNEEDSHELP src / libssrc / testsのような適切なフォルダー構造にすることで、簡単にポイントを克服できると思います。私はいくつかのテストランナーのフレームワークのような接頭辞必要とします知っているテスト、テストコードの識別のためにそのような場合には避けられませんが、残りのためにそれを反復することができていない必要な接頭辞。
negrotico19

@ negrotico19 IntelliJのような場合Search Everywhere(シフトシフト)またはFind a Class By Name(CMD O)の場合を考えています。私はそれがあることを取得しますいずれかのフォルダ構造やモジュール構造により区別することが、私たちは何かを検索したとき、我々はすでに我々が検索したいものを知っています。私がテストを探していた場合、私はに私の検索を制限したいtest、その後、名前を検索ではなく、名前を検索し、その後、目で手動テストを除外する。それは小さな違いだが、それは「テスト[クラス名]」の方がはるかに簡単だと一つだけがポップアップし、精神的な負担を軽減している
このユーザーはHELP NEEDS

37

これも一読の価値があります:単体テストの構造化

構造には、テストされるクラスごとにテストクラスがあります。それはそれほど珍しいことではありません。しかし、私が変わったことは、テストされるメソッドごとにネストされたクラスがあったことです。

例えば

using Xunit;

public class TitleizerFacts
{
    public class TheTitleizerMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void Name_AppendsTitle()
        {
            // Test code
        }
    }

    public class TheKnightifyMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void MaleNames_AppendsSir()
        {
            // Test code
        }

        [Fact]
        public void FemaleNames_AppendsDame()
        {
            // Test code
        }
    }
}

そしてここに理由があります:

1つには、テストを整理しておくのに良い方法です。メソッドのすべてのテスト(またはファクト)はグループ化されます。たとえば、CTRL + M、CTRL + Oショートカットを使用してメソッド本体を折りたたむと、テストを簡単にスキャンして、コードの仕様のように読み取ることができます。

私もこのアプローチが好きです:

MethodName_StateUnderTest_ExpectedBehavior

したがって、おそらく次のように調整します。

StateUnderTest_ExpectedBehavior

各テストはすでにネストされたクラスにあるため


2
Visual StudioでResharperのテストランナーを使用しているユーザーのために、8.xでネストされたテストクラスを使用してバグを修正しました。それ以来、これははるかに私の好ましい構造になりました。
angularsen 2015年

MethodName_StateUnderTest_ExpectedBehaviorアプローチで名前が本当に長くなることは重要ですか?「InitializeApiConfiguration_MissingApiKey_IllegalArgumentException」など。これは本当に良いテスト名ですか?
ポートフォリオ

28

私はMethodName_DoesWhat_WhenTheseConditionsそのような慣例を使用する傾向があります:

Sum_ThrowsException_WhenNegativeNumberAs1stParam

ただし、私がよく目にするのは、テスト名を以下のユニットテスト構造に従うことです。

  • アレンジ
  • 行為
  • 主張する

これは、次のBDD / Gherkin構文にも従います。

  • 与えられた
  • いつ
  • その後

これは、次の方法でテストに名前を付けることになります。 UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

だからあなたの例に:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

ただし、テストは最初にテストするメソッド名を優先することをお勧めします。テストをアルファベット順に配置したり、VisStudioのメンバードロップダウンボックスにアルファベット順にソートして表示したりできるため、1つのメソッドのすべてのテストがグループ化されます。


いずれにせよ、すべての単語ではなく、テスト名の主要なセクションをアンダースコアで区切るのが好きです。これにより、テストのポイントがわかりやすくなり、理解しやすくなります。

言い換えれば、私のように:Sum_ThrowsException_WhenNegativeNumberAs1stParamより良いですSum_Throws_Exception_When_Negative_Number_As_1st_Param


22

私は、アンダースコアやセパレータなしで「PascalCasing」を使用して、他のメソッドと同様にテストメソッドに名前を付けています。メソッドのPostfix Testは省略しました。値が追加されないためです。メソッドがテストメソッドであることは、属性TestMethodで示されます。

[TestMethod]
public void CanCountAllItems() {
  // Test the total count of items in collection.
}

各Testクラスは他の1つのクラスのみをテストする必要があるため、クラスの名前はメソッド名から除外します。テストメソッドを含むクラスの名前は、テスト中のクラスのように、接尾辞「Tests」を付けた名前になります。

[TestClass]
public class SuperCollectionTests(){
    // Any test methods that test the class SuperCollection
}

不可能な例外やアクションをテストするメソッドの場合、テストメソッドの前に「できない」という単語を付けます

[TestMethod]
[ExpectedException(typeOf(ArgumentException))]
public void CannotAddSameObjectAgain() {
  // Cannot add the same object again to the collection.
}

私の命名規則は、ブライアンクックの記事「TDDヒント:テスト命名規則とガイドライン」基づいています。この記事はとても役に立ちました。


1
投稿へのリンクの+1-テストで「テスト」接頭辞を使用する必要はありません。テストで期待される動作が指定されていることを確認してください。たとえば、CanRetrieveProperCountWhenAddingMultipleItems()
bryanbcook

2
予想される動作が含まれていないため、気に入らない
ヨハネスルドルフ

5

CamelCasingは単語を分離し、下線は命名体系の一部を分離するため、最初の名前のセットは私には読みやすくなっています。

また、関数名、またはそれを囲む名前空間やクラスのどこかに "Test"を含める傾向があります。


2
@Frank methodName = camelCase MethodName = PascalCase
Metro Smurf

@ metro-smurf:興味深い違いです。PascalCaseという用語を聞いたことがなく、長い間使用してきました。PascalCaseという用語がMicrosoftの開発者サークルで登場するのは私だけですが、それはあなたがしていることですか?
フランク・シュツェルバ09年

パスカルケーシングとキャメルケーシングの歴史(from:Brad Abrams-blogs.msdn.com/brada/archive/2004/02/03/67024.aspx)... "フレームワークの初期設計では、何百時間もかかっていました名前付けスタイルについての議論。これらの議論を容易にするために、私たちは多くの用語を作り出しました。AndersHeilsberg(Turbo Pascalの元の設計者)が設計チームの主要メンバーであるので、ケーシングスタイルにPascal Casingという用語を選んだのも不思議ではありません。 Pascalプログラミング言語によって普及しました。」
ヘリアック2013

-3

あなたが単一の練習に従う限り、それは本当に問題ではありません。一般的に、私はメソッドのすべてのバリエーションをカバーするメソッドの単一の単体テスト(私は単純なメソッドがあります)を記述し、それを必要とするメソッドのより複雑なテストのセットを記述します。したがって、私の命名構造は通常テストです(JUnit 3からの引き継ぎ)。


-8

テストの名前空間、クラス、メソッドには「T」プレフィックスを使用しています。

私はきちんと整理して、名前空間を複製するフォルダーを作成してから、テスト用のテストフォルダーまたは別のプロジェクトを作成し、基本的なテストの本番環境を複製します。

AProj
   Objects
      AnObj
         AProp
   Misc
      Functions
         AFunc
   Tests
      TObjects
         TAnObj
            TAnObjsAreEqualUnderCondition
      TMisc
         TFunctions
            TFuncBehavesUnderCondition

私は、何かがテストであることを簡単に確認できます。それが関連する元のコードを正確に知っています(それを解決できない場合、テストはとにかく複雑すぎます)。

インターフェースの命名規則と同じように見えます(つまり、「I」で始まるものと混同したり、「T」で混乱したりすることはありません)。

テストあり、またはなしでコンパイルするのは簡単です。

とにかく理論的には優れており、小規模なプロジェクトではかなりうまく機能します。


3
興味深いアプローチ。一部の人々は、Tプレフィックスがジェネリックで使用する規則(たとえばfunc(T1、T2、TResult))と競合すると主張するかもしれませんが、個人的にはチーム内でコンセンサスがある限り気にしません。名前は短く、読みやすくしています。
2011年

ハンガリー語(表記)が多すぎます。また、述べたように、プレフィックスTはジェネリック型パラメーターに使用されます。
ダニーVarod

私は同意します。ハンガリー語の表記は廃止されました。また、標準のジェネリック型パラメーターと競合するため、この場合に適用される例外はありません(インターフェースの場合など)。
SonOfPirate
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.