Language

操作手順: "使用から生成"機能を使ったテストファースト開発

このトピックでは、テスト優先開発をサポートする Generate From Usage 機能を使用する方法について説明します。

テスト優先開発 は、最初に製品の仕様に基づいて単体テストを記述し、テストを成功させるために必要なソース コードを記述するソフトウェア設計のアプローチです。 Visual Studio では、新しい型とメンバーを定義する前に、テスト ケースで最初に参照するときにソース コードで新しい型とメンバーを生成することで、テスト優先開発がサポートされます。

Visual Studio は、ワークフローの中断を最小限に抑えて、新しい型とメンバーを生成します。 コード内の現在の場所を離れることなく、型、メソッド、プロパティ、フィールド、またはコンストラクターのスタブを作成できます。 ダイアログ ボックスを開いて型生成のオプションを指定すると、ダイアログ ボックスが閉じると、フォーカスはすぐに現在開いているファイルに戻ります。

Generate From Usage 機能は、Visual Studio と統合されたテスト フレームワークで使用できます。 このトピックでは、Microsoft 単体テスト フレームワークについて説明します。

注

この記事の手順では、Visual Studio で使用できる対話型開発エクスペリエンス (IDE) の最新バージョンについて説明します。 コンピューターには、一部のユーザー インターフェイス要素に対して異なる名前または場所が表示される場合があります。 別のバージョンの Visual Studio または異なる環境設定を使用している可能性があります。 詳細については、「IDEのカスタマイズ」を参照してください。

Windows クラス ライブラリ プロジェクトとテスト プロジェクトを作成する

  1. C# または Visual Basic で、新しい Windows クラス ライブラリ プロジェクトを作成します。 使用している言語に応じて、 GFUDemo_VB または GFUDemo_CSに名前を付けます。

  2. ソリューション エクスプローラーで、上部にあるソリューション アイコンを右クリックし、[追加>新しいプロジェクト] を選択します。

  3. 新しい 単体テスト プロジェクト (.NET Framework) プロジェクトを 作成します。

クラス ライブラリ プロジェクトへの参照を追加する

  1. ソリューション エクスプローラーの単体テスト プロジェクトで、[参照] エントリを右クリックし、[参照の追加] を選択します。

  2. [ 参照マネージャ ]ダイアログ ボックスで、[ プロジェクト ]を選択し、クラス ライブラリ プロジェクトを選択します。

  3. [ OK] を 選択して、[ 参照マネージャー ] ダイアログ ボックスを閉じます。

  4. ソリューションを保存します。 これで、テストの記述を開始する準備ができました。

単体テストから新しいクラスを生成する

  1. テスト プロジェクトには、 UnitTest1 という名前のファイルが含まれています。 ソリューション エクスプローラーでこのファイルをダブルクリックして、コード エディターで開きます。 テスト クラスとテスト メソッドが生成されました。

  2. クラス UnitTest1 の宣言を見つけて、 AutomobileTestに名前を変更します。

    注

    IntelliSense では、IntelliSense ステートメントの入力候補用に、入力候補モードとサジェストモードの 2 つの選択肢が提供されるようになりました。 クラスとメンバーが定義される前に使用される状況では、提案モードを使用します。 IntelliSense ウィンドウが開いている場合は、Ctrl+Alt+Space キーを押して、補完モードとサジェストモードを切り替えることができます。 詳細については、「 IntelliSense の使用 」を参照してください。 提案モードは、次の手順で「 Automobile 」と入力するときに役立ちます。

  3. TestMethod1() メソッドを見つけて、名前を DefaultAutomobileIsInitializedCorrectly() に変更します。 このメソッド内で、次のスクリーンショットに示すように、 Automobileという名前のクラスの新しいインスタンスを作成します。 コンパイル時のエラーを示す波下線が表示され、クイック アクションのエラー電球が左の余白に表示されるか、カーソルを移動すると波線の下に直接表示されます。

    Visual Basic のクイック アクション

    C のクイック アクション#

  4. [クイック アクション] 電球を選択またはクリックします。 Automobile型が定義されていないことを示すエラー メッセージが表示されます。 また、いくつかのソリューションも提示されます。

  5. [ 新しい型の生成 ] をクリックして [ 型の生成 ] ダイアログ ボックスを開きます。 このダイアログ ボックスには、別のプロジェクトでの型の生成を含むオプションが表示されます。

  6. プロジェクトの一覧で、GFUDemo_VBまたはGFUDemo_CSをクリックして、テスト プロジェクトではなくクラス ライブラリ プロジェクトにファイルを追加するように Visual Studio に指示します。 まだ選択されていない場合は、[ 新しいファイルの作成 ] を選択し、 Automobile.cs または Automobile.vbに名前を付けます。

    [新しい型の生成] ダイアログ ボックス

  7. [ OK] を クリックしてダイアログ ボックスを閉じ、新しいファイルを作成します。

  8. ソリューション エクスプローラーで、GFUDemo_VBまたはGFUDemo_CSプロジェクト ノードの下を見て、新しいAutomobile.vbまたはAutomobile.cs ファイルが存在することを確認します。 コード エディターでは、フォーカスは引き続き AutomobileTest.DefaultAutomobileIsInitializedCorrectlyされるため、中断を最小限に抑えてテストを記述し続けられます。

プロパティ スタブを生成する

製品仕様では、 Automobile クラスに Model と TopSpeed という名前の 2 つのパブリック プロパティがあることを示しているとします。 これらのプロパティは、既定値の "Not specified" で初期化し、既定のコンストラクターで -1 する必要があります。 次の単体テストでは、既定のコンストラクターによってプロパティが正しい既定値に設定されていることを確認します。

  1. DefaultAutomobileIsInitializedCorrectly テスト メソッドに次のコード行を追加します。

    Assert.IsTrue((myAuto.Model == "Not specified") && (myAuto.TopSpeed == -1));
    
  2. コードは Automobileで 2 つの未定義のプロパティを参照するため、 Model と TopSpeedの下に波線の下線が表示されます。 Modelの上にマウス ポインターを置き、[クイック アクション] エラー電球を選択し、[プロパティ 'Automobile.Model' の生成] を選択します。

  3. 同じ方法で、 TopSpeed プロパティのプロパティ スタブを生成します。

    Automobile クラスでは、新しいプロパティの型がコンテキストから正しく推論されます。

新しいコンストラクターのスタブを生成する

次に、 Model プロパティと TopSpeed プロパティを初期化するコンストラクター スタブを生成するテスト メソッドを作成します。 後で、テストを完了するためのコードをさらに追加します。

  1. AutomobileTest クラスに次の追加のテスト メソッドを追加します。

    [TestMethod]
    public void AutomobileWithModelNameCanStart()
    {
        string model = "Contoso";
        int topSpeed = 199;
        Automobile myAuto = new Automobile(model, topSpeed);
    }
    
  2. 赤い波線の下にあるクイック アクションのエラー電球をクリックしてから、['Automobile' にコンストラクターを生成します] をクリックします。

    Automobile クラス ファイルで、新しいコンストラクターがコンストラクター呼び出しで使用されるローカル変数の名前を調べたり、Automobile クラスで同じ名前を持つプロパティを見つけたり、コンストラクター本体に指定されたコードを使用して、引数の値をModelプロパティとTopSpeedプロパティに格納していることに注意してください。

  3. 新しいコンストラクターを生成すると、DefaultAutomobileIsInitializedCorrectly の既定のコンストラクターを呼び出す部分の下に波線が表示されます。 エラー メッセージは、 Automobile クラスに 0 個の引数を受け取るコンストラクターがないことを示しています。 パラメーターを持たない明示的な既定のコンストラクターを生成するには、[ クイック アクション] エラー電球をクリックし、[ Automobile] で [コンストラクターの生成] をクリックします。

メソッドのスタブを生成する

ModelプロパティとTopSpeed プロパティが既定値以外の値に設定されている場合、新しいAutomobileをIsRunning状態にすることができると想定します。

  1. AutomobileWithModelNameCanStart メソッドに次の行を追加します。

    myAuto.Start();
    Assert.IsTrue(myAuto.IsRunning == true);
    
  2. myAuto.Start メソッド呼び出しのクイック アクション エラー電球をクリックし、[メソッド 'Automobile.Start' を生成する] をクリックします。

  3. IsRunning プロパティの [クイック アクション] 電球をクリックし、[プロパティ 'Automobile.IsRunning' を生成する] をクリックします。

    Automobile クラスには、Start() という名前のメソッドと IsRunning という名前のプロパティが含まれるようになりました。

テストの実行

  1. [テスト] メニューの [実行] > [すべてのテスト] を選択します。

    [Run>All Tests]\(すべてのテスト\) コマンドは、現在のソリューション用に記述されたテスト フレームワーク内のすべてのテストを実行します。 この場合、2 つのテストがあり、どちらも想定どおりに失敗します。 Assert.IsTrue条件がFalseを返すので、DefaultAutomobileIsInitializedCorrectly テストは失敗します。 Automobile クラスのStart メソッドが例外をスローするため、AutomobileWithModelNameCanStart テストは失敗します。

    [ テスト結果 ] ウィンドウを次の図に示します。

    失敗したテスト結果

  2. [ テスト結果 ] ウィンドウで、各テストの結果行をダブルクリックして、各テストの場所に移動します。

ソース コードを実装する

  1. 次のコードを既定のコンストラクターに追加して、 Model、 TopSpeed 、および IsRunning のプロパティがすべて、 "Not specified"、 -1、 False (または C# の場合は false ) の正しい既定値に初期化されるようにします。

    public Automobile()
    {
        this.Model = "Not specified";
        this.TopSpeed = -1;
        this.IsRunning = true;
    }
    
  2. Start メソッドを呼び出すときは、ModelプロパティまたはTopSpeedプロパティが既定値以外に設定されている場合にのみ、IsRunning フラグを true に設定する必要があります。 メソッド本体から NotImplementedException を削除し、次のコードを追加します。

    public void Start()
    {
        if (this.Model != "Not specified" || this.TopSpeed != -1)
            this.IsRunning = true;
        else
            this.IsRunning = false;
    }
    

テストをもう一度実行する

  • [ テスト ] メニューの [ 実行] をポイントし、[ すべてのテスト] をクリックします。

    今回はテストに合格します。 [ テスト結果 ] ウィンドウを次の図に示します。

    合格したテスト結果