連載:VSTSの単体テスト機能は本当に使えるのか?

第3回 VSTSで提供される注目すべき単体テスト機能

株式会社 アークウェイ 中西 庸文
Microsoft MVP 2006 - Solutions Architect)
2007/02/07
Page1 Page2 Page3 Page4

 テスト用テーブルに挿入されたテスト・データの行数分だけテストが反復実行されたことが確認できるはずだ。

テスト・データの行数分だけ反復実行されたテスト結果

 このように、データ・ドリブン単体テストではテスト・メソッドのDataSource属性で指定されたテスト用テーブルからレコードが返されるたびに、そのテスト・メソッドが呼び出されることになる。これによって、テスト・コードは実行中のテストにおいてテスト・データを使用でき、テスト用テーブルに挿入された各レコードに対してテストを反復実行させることが可能となる。

ASP.NET単体テスト

 ASP.NETプロジェクトで作業を行っている際に、ASP.NETプロジェクトの一部であるクラスの単体テストを実施したいと思ったことはないだろうか。VS 2005では、ほかのプロジェクトからWebプロジェクトを参照することができるので、このような単体テストであっても通常の単体テストと同じ方法でテストを実施することができる。ただし、テスト対象のクラスがPageオブジェクトなどのASP.NETに依存するAPIを使用している場合には、実行時例外が発生してしまうので単体テストを実施することはできない。

 VSTSの「ASP.NET単体テスト」を使用すれば、従来では難しかったASP.NETプロジェクト内のクラスに対しての単体テストを簡単に実行することができる。また、ASP.NET単体テストではテストを実行する環境としてIISやASP.NET開発サーバなどの選択も可能だ。

 それでは実際にPet Shopを使用してASP.NET単体テストの機能を検証してみよう。ここでは、Pet Shop ASP.NETプロジェクトのWebUtilityクラスのGetProductNameメソッド(=プロダクトIDからプロダクト名を取得し、取得したプロダクト名をキャッシュに格納する簡単なユーティリティ・メソッド)をテストするためのASP.NET単体テストを作成することにする。

ASP.NET単体テストの自動生成

 ここではWebUtilityクラスからASP.NET単体テストを自動生成する。

 まず、VS 2005上でPet ShopのApp_Codeフォルダ配下にあるWebUtilityクラスのGetProductNameメソッドのコードを表示し、メソッド名部分を右クリックしてコンテキスト・メニューを表示し、[単体テストの作成]を選択する。

 [単体テストの作成]ダイアログ上では、WebUtilityクラスのGetProductNameメソッドにチェックが入っていることを確認する。

単体テストの自動生成
VS 2005のコード・エディタでテスト対象のメソッドを右クリックしてコンテキスト・メニューを表示し、そこから[単体テストの作成]を選択する。これにより、単体テストを自動生成するためのダイアログが表示される。

 次に、[単体テストの作成]ダイアログの[設定]ボタンをクリックして表示される[テスト生成の設定]ダイアログの[メソッド名]に「ProductNameが取得できるべき」と入力して、単体テストを自動生成する。

テスト生成の設定
[単体テストの作成]ダイアログの[設定]ボタンをクリックする。これにより、単体テストの自動生成に関する設定を行うためのダイアログが表示される。日本語のテスト・メソッド名を使用する場合には、このダイアログ上でメソッド名を設定するとよい。

 これらの設定により、ASP.NET 開発サーバで実行されるASP.NET単体テストが自動生成されるので、テスト・メソッドの内容を適切に修正する。以下に修正後のテスト・クラスのコードを示す。

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;

namespace PetShop.Tests
{
  /// <summary>
  /// PetShop.Web.WebUtilityのテスト・クラス。
  /// すべてのPetShop.Web.WebUtility単体テストをここに含める。
  /// </summary>
  [TestClass()]
  public class WebUtilityTest
  {
    private TestContext testContextInstance;

    /// <summary>
    /// 現在のテストの実行についての情報および機能を提供する
    /// テスト・コンテキストを取得または設定する。
    /// </summary>
    public TestContext TestContext
    {
      get
      {
        return testContextInstance;
      }
      set
      {
        testContextInstance = value;
      }
    }
    ……省略……
    /// <summary>
    /// GetProductName(string)のテスト。
    /// </summary>
    [TestMethod()]
    [HostType("ASP.NET")]
    [AspNetDevelopmentServerHost("C:\\Program Files\\Microsoft\\.NET Pet Shop 4.0\\Web", "/Web")]
    [UrlToTest("http://localhost/Web")]
    public void ProductNameが取得できるべき()
    {
      // キャッシュが空であることを確認する。
      Assert.AreEqual(0, TestContext.RequestedPage.Cache.Count);

      // プロダクトIDからプロダクト名を取得する。
      string productId = "BD-01";
      string productName = PetShop.Tests.PetShop_Web_WebUtilityAccessor.GetProductName(productId);

      // プロダクト名を確認する。
      Assert.AreEqual("Pelican", productName);

      // キャッシュに要素が追加されたことを確認する。
      Assert.AreEqual(1, TestContext.RequestedPage.Cache.Count);
      Assert.AreEqual("Pelican", (string)TestContext.RequestedPage.Cache["product_name_BD-01"]);
    }
  }
}
ASP.NET単体テストのテスト・クラス

 ここで注目してもらいたいのは、テスト・メソッドに付けられている以下の属性である。

  • HostType属性(=テストを実行するホスト・プロセスの設定。ASP.NET単体テストは、ASP.NETホスト・プロセスで実行する必要がある)
  • AspNetDevelopmentServerHost属性(=ASP.NET 開発サーバの設定。IISで実行中のWebサイトをテストする場合は、この属性は指定しない)
  • UrlToTest(=単体テストを実行するときにテストされるURL)

 また、TestContext.RequestedPageプロパティによってPageオブジェクトのCacheプロパティにアクセス可能となっている点や、実際にWebUtilityクラスのGetProductNameメソッドを呼び出す代わりに、自動生成されたASP.NET単体テスト用のラッパー・クラスであるPetShop_Web_WebUtilityAccessorクラスのGetProductNameメソッドが呼び出されている点にも注意してもらいたい。

 それではASP.NET単体テストを実行してみよう。ASP.NET開発サーバが起動してテストが実行されることが確認できるはずだ。

 このように、ASP.NET単体テストでは、ASP.NETプロジェクトのビジネス・ロジックを構成するメソッド群を簡単にテストすることが可能となる。また、ASP.NET単体テストは、実行コードと同じ環境で実行されるため、ASP.NET開発サーバとIISというようにテスト実行環境を属性ベースで簡単に切り替えることも可能である。

まとめ

 今回は、VSTSの単体テスト機能で注目すべきデータ・ドリブン単体テストやASP.NET単体テストについて説明した。これによって、従来のNUnitを使用した単体テストでは難しかった種類のテストが、VSTSのテスティング・フレームワークを使用すれば容易に実行できることを示した。

 本連載を通してご紹介したように、VSTSのテスティング・フレームワークには、強力な自動生成機能があり、この機能を有効活用しない手はない。また、単体テストを自動生成させたからといってテスト・ファースト・プログラミングができないわけではない。テストの目的が明確であれば、テスト対象メソッドのメソッド・スタブだけ記述して、そこから単体テストのスケルトン・コードを自動生成し適切な内容に修正すればよい。状況に応じてテストを自分で記述するか自動生成させるかを使い分けることができれば、より効率の良いテスト駆動開発を行うことが可能となるのだ。

 これらの内容を踏まえたうえで、NUnitからVSTSのテスティング・フレームワークへの移行を検討するだけの価値は十分にあるという最終的な結論に至った。VSTSの単体テスト機能をフル活用し、デベロッパー・テスティングを存分に楽しんでいただきたい。End of Article

中西 庸文

2006年 株式会社 アークウェイ入社。Microsoft MVP for Visual Developer - Solutions Architect。開発メンターとして開発チームに参加することで.NET開発現場の現状を改善していきたいとの思いから昨年末にアークウェイに移籍。現在は、開発者としてやるべき当たり前のことをDevBL(Development Baseline)として提唱しようとしている。

Blog:NAgilerの日記VB&C#デザインパターンINETA Japan 加盟コミュニティ)を運営中。
 
 

 INDEX
  VSTSの単体テスト機能は本当に使えるのか?
  第3回 VSTSで提供される注目すべき単体テスト機能
    1.VSTSの単体テスト機能
    2.データ・ドリブン単体テストの準備
    3.データ・ドリブン単体テストの記述
  4.ASPNET単体テスト
 
インデックス・ページヘ  「VSTSの単体テスト機能は本当に使えるのか?」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間