SHOEISHA iD

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

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

特集記事

Visual Studio 11 betaの単体テスト機能を使ってみよう!

単体テストエクスプローラーと、Fakes Frameworkの使い方を紹介

  • X ポスト
  • このエントリーをはてなブックマークに追加

async/awaitのテスト方法

 C# 5で導入されたasync/awaitキーワードにより、Taskクラスを使った非同期メソッド(以降、「asyncメソッド」と呼びます)の記述が簡潔に書けるようになりました。

【製品コード】AsyncSample.cs:テスト対象のコード
public class AsyncSample
{
    public static async Task<string> SampleMethodAsync()
    {
        await Task.Run(() => Thread.Sleep(3000));
        return "非同期実行完了!";
    }
}

 このコードは、3秒ほど掛かる処理(実態はSleep())を非同期で実行します。処理が完了すると、"非同期実行完了!"という文字列を返します。

新しいMSTestでの書き方

 このように記述するasyncメソッドのテストには、VS2010のMSTestでは次のように書いていました。

【テストコード】AsyncSampleTest_MSTest.cs:VS2010での書き方
[TestMethod()]
public void SampleMethodAsyncTest_MSTest_従来の書き方()
{
    var task = AsyncSample.SampleMethodAsync();
    // 返値のTask<string>を受け取って…

    task.Wait(); // 非同期実行が終わるまで、待機する。

    var result = task.Result;  // 非同期実行の結果を取りだし
    Assert.AreEqual<string>("非同期実行完了???", result);
    // このテストは、予想通り RED になる。
    // テストの実行時間も、予想通り3秒ほど掛かる。
}

 これを、VS11betaのMSTestでは次のようにasync/awaitを使って簡潔に記述できます。ポイントは、テストメソッドの返値をTaskクラスにすることです。

【テストコード】AsyncSampleTest_MSTest.cs:VS11betaでの新しい書き方
[TestMethod()]
public async Task SampleMethodAsyncTest_MSTest_正しい書き方()    // 返す型が Task
{
    var result = await AsyncSample.SampleMethodAsync();
    Assert.AreEqual<string>("非同期実行完了???", result);
    // このテストは、予想通り RED になる。
    // テストの実行時間も、予想通り3秒ほど掛かる。
}

 ここで、メソッドの型をTaskではなく従来通りにvoidと書いてしまうと、MSTestのテストランナーは非同期の完了を待ちません。そのためawait後のAssertが実行されず、すべてのテストがGREEN(成功)になってしまいます(下の画像中のSampleMethodAsyncTest_MSTest_間違い())。なお、必ず一度RED(失敗)を確認してから実装に手を加えてGREENにする、というテストファーストの習慣を守っていれば、そのようなミスも防ぐことができます。

asyncメソッドのテスト
asyncメソッドのテスト

NUnitでの書き方

 NUnitでは従来通りに記述します。ただし、.NET 4.5で追加された機能を使って、少し簡潔に書けるようになりました。

【テストコード】AsyncSampleTest_NUnit.cs:NUnit 2.6での書き方
[TestCase()]
public void SampleMethodAsyncTest_NUnit_正しい書き方1()
{
    var result = AsyncSample.SampleMethodAsync().GetAwaiter().GetResult();
    // .GetAwaiter().GetResult() で、非同期実行の完了を待つ。
    // この場合、非同期実行中の例外はそのまま送り出されてくる。

    Assert.AreEqual("非同期実行完了???", result);
    // このテストは、予想通り RED になる。
    // テストの実行時間も、予想通り3秒ほど掛かる。
}

次のページ
単体テストエクスプローラーでNUnitを統合する

修正履歴

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

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

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6491 2012/04/12 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング