VS Express で .NET Core の xUnit.net を使ったテストのデバッグを行う


.NET で 単体テストと言えば、いまや xUnit.net が事実上の標準となっている。
ASP.NET Core や .NET Core のドキュメントでも、単体テストは xUnit.net を使うように案内されている。

ところが Visual Studio の Express Edition 系列 の テストエクスプローラは、 xUnit.net に対応していない。
それでも Full .NET Framework や dnx では、そのままテストプロジェクトを「実行」してしまえば、とりあえずデバッグ実行はできていた。
しかし、 .NET Core + dotnet-test-xunit では、それすらもできなくなってしまい、 dotnet test コマンドの出力を確認するしかなくなってしまった。

デバッグ実行ができないのは流石に不便… ということで、デバッグ実行を行うハックを紹介しよう。

# ライセンス的に Visual Studio Community 使えるのなら、そちらを使うべき。
# ただ、たとえ Express ではなくても、 この方法を使うと xUnit.net の出力が文字化けする問題も防げるぞ。

エントリーポイントを作成し、コンソールプロジェクトにする

Getting started with xUnit.net (.NET Core / ASP.NET Core) > xUnit.net にも書かれているとおり、 テストプロジェクトは 通常 クラスライブラリとしてプロジェクトを作成するが、 Express でデバッグしたいときは エントリーポイント を作成して、コンソールプロジェクトとして作成する。

project.json:

{
  "version": "1.0.0-*",

  "buildOptions": {
    "emitEntryPoint": true
  },

  "testRunner": "xunit",

  "dependencies": {
    "xunit": "2.1.0",
    "dotnet-test-xunit": "1.0.0-rc2-build10025"
  },
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0-rc2-3002702"
        },
        "System.Text.Encoding.CodePages": "4.0.1-rc2-24027"
      },
      "imports": [
        "dnxcore50",
        "portable-net45+win8"
      ]
    }
  }
}

そして、 Visual Studio のプロジェクトの設定で、デバッグ時にプロジェクト自体が起動するように設定してやる。
160531_1

自分自身の DLL のパスを引数に、 Xunit Runner のメイン関数を呼ぶ

あとは、テストコードにもエントリーポイント作成して、 自分自身の DLL のパスを Xunit.Runner.DotNet.Program.Main の第一引数にしてやれば良い。
.NET Core での コンソールアプリの文字化けを直す で紹介したように、このまま実行すると 非Ascii 文字が文字化けしてしまうので、 ついでに CodePagesEncodingProvider を登録してしまおう。

using System.Linq;
using System.Text;
using Xunit;

namespace netcore_xunit_test_01 {
    public class Program {
        [Fact]
        public static void MethodTest() {
            Assert.True(true);
        }

        // entry point
        static int Main(string[] args) {
            // Unicode, ASCII, CodePage 28591 (西ヨーロッパ言語) 以外は規定ではサポートしていない
            // 初めて Console を使用する前に、 CodePagesEncodingProvider に登録する
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            var dllPath = System.Reflection.Assembly.GetEntryAssembly().Location;
            return Xunit.Runner.DotNet.Program.Main(new string[] { dllPath }.Concat(args).ToArray());
        }
    }
}

これで、デバッグ実行ができるようになった。
デバッグ時の引数に 任意の引数を設定してやれば、 dotnet test コマンドを実行した場合と同様、 テスト対象を クラスや名前空間に絞って行うことも可能だ。

コメントを残す

メールアドレスが公開されることはありません。