特集
» 2013年04月10日 07時41分 公開

Windowsアプリの受け入れテストを自動化しよう特集:受け入れ検査の自動化手法の考察(3/5 ページ)

[石川達也,株式会社Codeer]

WCFを使ってAPIを実装する

 WCF(Windows Communication Foundation)は、マイクロソフトが.NETでサポートする通信手段の1つで、これを使えば簡単にインターフェイスを公開できる。WCFの詳細に関しては「Windows Communication Foundation概説」などを参照願いたい。

●テスト対象アプリの変更

 WCFを使う手法では、テスト対象アプリのコードも変更が必要である。変更の目的は、ビジネス・ロジックであるManagementSystemクラスを(WCFサービス経由で)外部から操作できるようにすることである。これは以下の実装で可能となる。

  • WCFサービスとして公開用のインターフェイスを定義
  • ManagementSystemクラスで、そのインターフェイスを実装するように変更
  • 外部からの要求でインターフェイスを公開

using System.ServiceModel;
……省略……

// WCFサービス公開用インターフェイスの定義。
[ServiceContract]
public interface IManagementSystem
{
  [OperationContract]
  bool Add(string name, string ageString, string post);

  [OperationContract]
  EmployeeData Find(string name);
}

// ManagementSystemクラスの定義を次のように変更する。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ManagementSystem : IManagementSystem
{
  ……実装は変更なし……
}

// 外部からの要求でインターフェイスを公開。説明しやすいように、ここに記述しているが、MainFormクラスはファイルの先頭に記述しないと、Windowsフォーム・デザイナでエラーが出るので注意してほしい。
public partial class MainForm : Form
{
  ……もともとの処理はそのまま……

  // 以下が追加コード。
  ServiceHost wcfHost = null;
  public const int WM_OPEN_SERVER = 0x8000;
  public const string WcfAddresses =
      "net.pipe://localhost/EmployeeManagement.ManagementSystem";

  // メッセージを受けると公開。
  protected override void WndProc(ref Message m)
  {
    if (m.Msg == WM_OPEN_SERVER)
    {
      wcfHost = new ServiceHost(system);
      wcfHost.AddServiceEndpoint(typeof(IManagementSystem),
        new NetNamedPipeBinding(), WcfAddresses);
        wcfHost.Open();
        m.Result = new IntPtr(1);
    }
    base.WndProc(ref m);
  }

  // 画面を閉じるときにはWCFサービスも閉じる。
  protected override void OnClosed(EventArgs e)
  {
    if (wcfHost != null)
    {
      wcfHost.Close();
      wcfHost = null;
    }
    base.OnClosed(e);
  }
}

リスト3 WCFによりManagementSystemクラスを外部プロセスに公開する(MainForm.cs)
System.ServiceModelアセンブリへの参照を追加する必要がある。

●APIの実装

 次に、先ほどWCFサービス経由で公開したインターフェイスを使ってManagementSystemクラスを操作するためのAPI(=EmployeeManagementAppクラス)を、クラス・ライブラリのプロジェクト内に実装する(ここでは、ソリューション内に「EmployeeManagementAPI」という名前のクラス・ライブラリ・プロジェクトを追加した)。

 具体的には次のコードのように、Windowsフォームの社員管理アプリ(=EmployeeManagement.exeファイル)のWCFサービスに要求を出してインターフェイスを公開させ、それを取得して使うという手順になる。

using System;
using EmployeeManagement;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.ServiceModel;
using System.Threading;

namespace EmployeeManagementAPI
{
  public class EmployeeManagementApp : IDisposable
  {
    // 開始。
    public static EmployeeManagementApp Start()
    {
#if DEBUG
      string path = Path.GetFullPath("../../bin/Debug/EmployeeManagement.exe");
#else
      string path = Path.GetFullPath("../../bin/Release/EmployeeManagement.exe");
#endif
      return new EmployeeManagementApp(Process.Start(path));
    }

    IManagementSystem managementSystem;
    int processId;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

    // コンストラクタ。
    public EmployeeManagementApp(Process process)
    {
      processId = process.Id;

      // メインウィンドウが完成するまで待つ。
      while (process.MainWindowHandle == IntPtr.Zero)
      {
        process = Process.GetProcessById(process.Id);
        Thread.Sleep(10);
      }

      // インターフェイス公開要求。
      SendMessage(process.MainWindowHandle, MainForm.WM_OPEN_SERVER, IntPtr.Zero, IntPtr.Zero);

      // インターフェイス取得。
      managementSystem = new ChannelFactory<IManagementSystem>
          (new NetNamedPipeBinding(), MainForm.WcfAddresses).CreateChannel();
    }

    // 終了。
    public void Dispose()
    {
      Process.GetProcessById(processId).CloseMainWindow();
    }

    // 登録。
    public bool Add(string name, string age, string post)
    {
      return managementSystem.Add(name, age, post);
    }

    // 検索。
    public EmployeeData Find(string name)
    {
      return (EmployeeData)managementSystem.Find(name);
    }
  }
}

リスト4 WCFでAPIを実装する(EmployeeManagementApp.cs)
EmployeeManagementプロジェクト/System.ServiceModelアセンブリ/System.Windows.Formsアセンブリへの参照を追加する必要がある。

 あとは、ソリューションに単体テスト・プロジェクト(ここでは「TestProject」とする)を新規追加して、そこに「リスト1 シンプルな受け入れテストのテスト・シナリオ(AcceptanceTest.cs)」で示したファイルを作成すれば完成だ(このプロジェクトには、EmployeeManagementプロジェクト/EmployeeManagementAPIプロジェクトへの参照を追加する必要がある)。Visual Studioの[テスト エクスプローラー]などを使ってテストを実行すると、受け入れテストが実施される。

 次にUIオートメーションを使う方法を説明しよう。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。