Bot Framework と Microsoft Graph で DevOps その 2 : C# でのユニットテスト環境構築

前回は Bot Framework でユニットテストの考え方について紹介しましたが。今回は C# でユニットテストができる状態にまずしてみます。

プロジェクトの作成などもろもろ準備

まず基本的なセットアップをしてしまいます。

VSTS プロジェクト

VSTS にサインアップして、任意のプロジェクトを作成してください。

1. VSTS アカウントにサインイン、「New Porject」 からプロジェクト作成。

image

2. バージョン管理は Git にしてみます。

image

3. とりあえず Clone in Visual Studio をぽちっと。

image

4. 適当なフォルダにマップして完了。

image Visual Studio プロジェクト

1. Team Explorer から新しくソリューションを作ります。 New をぽちっと。

image

2. Bot Application テンプレートを選択して、作成。名前はお任せで。ここでは O365Bot と一旦。

image

3. ユニットテスト用のプロジェクトも追加します。ソリューションを右クリックして、プロジェクト追加。名前は O365Bot.UnitTests としました。

image

ユニットテストプロジェクトにテスト用コード追加

とりあえず今回必要最低限のソースを取ります。

1. BotBuilder GitHub よりソースを取得 (https://github.com/Microsoft/BotBuilder)

2. ユニットテストプロジェクトに、フォルダを追加。名前は何でもいいのですが、Helper としてみました。

3. Helper フォルダ内に、以下のファイルを追加します。

- BotBuilder-master\CSharp\Tests\Microsoft.Bot.Builder.Tests\ConversationTest.cs
- BotBuilder-master\CSharp\Tests\Microsoft.Bot.Builder.Tests\DialogTestBase.cs
- BotBuilder-master\CSharp\Tests\Microsoft.Bot.Builder.Tests\FiberTests.cs

また以下のクラスを削除します。

- ConversationTest.cs 内、ConversationTest クラス
- FiberTest.cs 内、FiberTests クラス

4. 以下 NuGet パッケージの追加と全パッケージの最新化

- BotBuilder と依存関係
- Moq

※ MSTest パッケージ類は 1.1.17 がうまく動作しなかったため、1.1.11 を利用。

5. System.Web の参照追加と、 O365Bot プロジェクト参照追加

6. ソリューションのビルドを実施して問題なくコンパイルできるか確認。

ユニットテストの追加と実行

では下準備が整ったところで、さっそくテスト追加してみましょう。

1. 以下のコードを UnitTest1.cs ファイルに張り付け。Namespace は自分のものに差し替えてください。

 using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Tests;
using Microsoft.Bot.Connector;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;
using Autofac;
using O365Bot.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Builder.Base;
using System.Threading;
using System.Collections.Generic;

namespace O365Bot.UnitTests
{
    [TestClass]
    public class SampleDialogTest : DialogTestBase
    {
        [TestMethod]
        public async Task ShouldReturnCount()
        {
            // テストしたいダイアログのインスタンス作成
            IDialog<object> rootDialog = new RootDialog();

            // Bot に送るメッセージを作成
            var toBot = DialogTestBase.MakeTestMessage();
            toBot.From.Id = Guid.NewGuid().ToString();
            toBot.Text = "hi!";

            // メモリ内で実行できる環境を作成
            Func<IDialog<object>> MakeRoot = () => rootDialog;
            using (new FiberTestBase.ResolveMoqAssembly(rootDialog))
            using (var container = Build(Options.MockConnectorFactory | Options.ScopedQueue, rootDialog))
            {
                // メッセージを送信して、結果を受信
                IMessageActivity toUser = await GetResponse(container, MakeRoot, toBot);

                // 結果の検証
                Assert.IsTrue(toUser.Text.Equals("You sent hi! which was 3 characters"));
            }
        }
              
        /// <summary>
        /// Bot にメッセージを送って、結果を受信
        /// </summary>
        public async Task<IMessageActivity> GetResponse(IContainer container, Func<IDialog<object>> makeRoot, IMessageActivity toBot)
        {
            using (var scope = DialogModule.BeginLifetimeScope(container, toBot))
            {
                DialogModule_MakeRoot.Register(scope, makeRoot);

                // act: sending the message
                using (new LocalizedScope(toBot.Locale))
                {
                    var task = scope.Resolve<IPostToBot>();
                    await task.PostAsync(toBot, CancellationToken.None);
                }
                //await Conversation.SendAsync(toBot, makeRoot, CancellationToken.None);
                return scope.Resolve<Queue<IMessageActivity>>().Dequeue();
            }
        }
    }
}

2. ソリューションをビルド。

3. テストエクスプローラより該当のテストを実施し、意図したとおり動作することを確認。

image

まとめ

まずユニットテストを実施する最低限の環境を作りました。次回は Microsoft Graph を呼べるようにしつつ、認証モジュールとして AuthBot を紹介します。ソリューションは VSTS にチェックインしておいてください。