SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

C#で始めるテスト駆動開発入門

ユニバーサルWindowsアプリのユニットテスト(後編)

C#で始めるテスト駆動開発入門(9)

ダウンロード CsTdd09.zip (129.9 KB)

6-1. DataTestMethod/DataRow(パラメタライズドテスト)

 これは待ち望まれていた機能です。この機能の有無が、従来のデスクトップアプリ用のユニットテストで、MSTestではなくNUnitを選ぶ大きな理由になっていました。それがストアアプリ用のMSTestで、ようやく提供されたのです(前述したように、この機能は従来のデスクトップアプリ用のMSTestではまだ使えません)。

 パラメタライズドテストには、DataTestMethod属性とDataRow属性を使います。ここでは、共有プロジェクトにFizzBuzzを実装してみましょう。

 FizzBuzzの実装手順は、従来のデスクトップアプリ用のMSTestならば「FizzBuzzを作ってみる」(PDF)のようになります(FizzBuzzをご存知ない方はこのPDFをご覧ください)。

 DataTestMethod属性とDataRow属性を使うと、テストコードは次のように書けます(最終形だけを示します)。このテストコードは、テストの共有プロジェクトに「FizzBuzzPlayerTest.cs」ファイルを作って、そこに記述します。

テストコード: DataTestMethod属性とDataRow属性を使ったパラメタライズドテスト
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;

namespace CsTdd08Tests.Shared
{
  [TestClass]
  public class FizzBuzzPlayerTest
  {
    [DataTestMethod]
    [DataRow(1, "1", DisplayName = "1のときは「1」")]
    [DataRow(2, "2", DisplayName = "2のときは「2」")]
    [DataRow(3, "Fizz", DisplayName = "3のときは「Fizz」")]
    [DataRow(5, "Buzz", DisplayName = "5のときは「Buzz」")]
    [DataRow(15, "Fizz Buzz", DisplayName = "15のときは「Fizz Buzz」")]
    public void TestSay(int n, string expected)
    {
      CsTdd08App.FizzBuzzPlayer p = new CsTdd08App.FizzBuzzPlayer();
      Assert.AreEqual<string>(expected, p.Say(n));
    }
  }
}

 完成した製品コードは次のようになります。共有プロジェクトの「FizzBuzzPlayer.cs」ファイルです。

製品コード: 完成したFizzBuzzPlayerクラス
namespace CsTdd08App
{
  public class FizzBuzzPlayer
  {
    public string Say(int number)
    {
      bool isMultipleOf3 = (number % 3 == 0);
      bool isMultipleOf5 = (number % 5 == 0);

      if (isMultipleOf3 && isMultipleOf5)
        return "Fizz Buzz";

      if (isMultipleOf3)
        return "Fizz";

      if (isMultipleOf5)
        return "Buzz";

      return number.ToString();
    }
  }
}

 なお、テストエクスプローラーでは、上述のTestSayテストは1つしか表示されませんが、それを選択すると下のペインにテスト名とともに複数の結果が表示されます(次の画像)。このテスト名は、DataRow属性に与えたDisplayName名前付き引数です。

パラメタライズドテストを実行したところ
パラメタライズドテストを実行したところ
従来のデスクトップアプリ用のMSTestでのパラメタライズドテスト

 ここで紹介したパラメタライズドテストの機能は、ストアアプリ専用です。従来のデスクトップアプリ用のMSTestでは利用できません。従来のデスクトップアプリ用のユニットテストでは、MSTestで「Chaining Assertion for MSTest」を利用したり(『C#で始めるテスト駆動開発入門(2):Visual StudioのMSTestでTDDを行う方法』)、NUnitなどの他のユニットテスティングフレームワークを採用するなどしていました。

#ifディレクティブの利用

 ここで、共有しているユニットテストのコードでも、#ifディレクティブを使ってWindowsとPhoneのコードを切り分けられることを確かめておきましょう。

 Phone用のユニットテストプロジェクトには、WINDOWS_PHONE_APPコンパイル定数がすでに定義されています。Windows用のユニットテストプロジェクトには定義されていないので、プロジェクトのプロパティを開き、左の[ビルド]タブを選び、[条件付きコンパイルシンボル]の欄の末尾に「;WINDOWS_APP」と追加します。

 そうしたら、Phone用のFizzBuzzの仕様を変えることにしましょう。Phoneの画面が狭いことを考慮して、3と5の倍数のときは「Fizz Buzz」ではなく、スペースを削った「FizzBuzz」を返すことにします。すると、#ifディレクティブを使って、テストコードは次のように書けます。

テストコード: #ifディレクティブを使ってテストを切り分ける
    [DataTestMethod]
    [DataRow(1, "1", DisplayName = "1のときは「1」")]
    [DataRow(2, "2", DisplayName = "2のときは「2」")]
    [DataRow(3, "Fizz", DisplayName = "3のときは「Fizz」")]
    [DataRow(5, "Buzz", DisplayName = "5のときは「Buzz」")]
#if WINDOWS_APP
    [DataRow(15, "Fizz Buzz", DisplayName = "15のときは「Fizz Buzz」")]
#endif
#if WINDOWS_PHONE_APP
    [DataRow(15, "FizzBuzz", DisplayName = "15のときは「FizzBuzz」")]
#endif
    public void TestSay(int n, string expected)
    {
      CsTdd08App.FizzBuzzPlayer p = new CsTdd08App.FizzBuzzPlayer();
      Assert.AreEqual<string>(expected, p.Say(n));
    }

 これでテストを走らせてみると、Phone用のテストだけがRED(失敗)になります(次の画像)。

#ifディレクティブを使って片方のテストだけをRED(失敗)にした
#ifディレクティブを使って片方のテストだけをRED(失敗)にした

 製品コードも#ifディレクティブを使って、次のように修正します。これで再びALL GREENになります。

製品コード: 修正したSayメソッド
    public string Say(int number)
    {
      bool isMultipleOf3 = (number % 3 == 0);
      bool isMultipleOf5 = (number % 5 == 0);

      if (isMultipleOf3 && isMultipleOf5)
#if WINDOWS_APP
        return "Fizz Buzz";
#endif
#if WINDOWS_PHONE_APP
        return "FizzBuzz";
#endif

      if (isMultipleOf3)
        return "Fizz";

      if (isMultipleOf5)
        return "Buzz";

      return number.ToString();
    }

次のページ
まとめ

この記事は参考になりましたか?

C#で始めるテスト駆動開発入門連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/8093 2014/10/08 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー