Pex を使うクラスには、日本語を使わない方が良さそう…

pexwizard でテストケースを自動生成すると、日本語が無視される様です。
pex や pexwizard 何?って方は、前回の記事からどうぞ!Pex 楽しいよ! - お だ のスペース
次のクラスが含まれるアセンブリでは、pexwizard でエラーが起きました。

using System;

namespace ClassLibrary1
{
  public class 税処理
  {
    public decimal 外税計算(decimal 金額, decimal 税率)
    {
      if (税率 < 0)
      {
        throw new ArgumentOutOfRangeException("税率は 0以上");
      }
      try
      {
        return 金額 * 税率;
      }
      catch (OverflowException)
      {
        return decimal.Zero;
      }
    }
  }
}


では、生成されたコードを確認してみましょう。

_Test.cs

// <copyright file="_Test.cs">Copyright &#169;  2010</copyright>
using System;
using ClassLibrary1;
using Microsoft.Pex.Framework;
using Microsoft.Pex.Framework.Validation;
using NUnit.Framework;

namespace ClassLibrary1
{
    [PexClass(typeof(\u7a0e\u51e6\u7406))]
    [PexAllowedExceptionFromTypeUnderTest(typeof(InvalidOperationException))]
    [PexAllowedExceptionFromTypeUnderTest(typeof(ArgumentException), AcceptExceptionSubtypes = true)]
    [TestFixture]
    public partial class _Test
    {
        [PexMethod]
        public decimal _(
            [PexAssumeUnderTest]\u7a0e\u51e6\u7406 target,
            decimal _,
            decimal _
        )
        {
            decimal result = target.\u5916\u7a0e\u8a08\u7b97(_, _);
            return result;
        }
    }
}

※\u7a0e\u51e6\u7406 は「税処理」、\u5916\u7a0e\u8a08\u7b97 は「外税計算」の Unicode 表記です。
呼び出し元のクラス名や、メソッド名 (ここでは、税処理クラスや、外税計算メソッド) は、Unicode 表記で対応してくれるんですが、テストクラスのメソッドやパラメータは "_" に置き換えられているみたいです。


というわけで、対象のコードを修正します。

using System;

namespace ClassLibrary1
{
  public class 税処理
  {
    public decimal 外税計算(decimal arg1金額, decimal arg2税率)
    {
      if (arg2税率 < 0)
      {
        throw new ArgumentOutOfRangeException("arg税率は 0以上");
      }
      try
      {
        return arg1金額 * arg2税率;
      }
      catch (OverflowException)
      {
        return decimal.Zero;
      }
    }
  }
}

pexwizard して作成されたコードがこちら

_Test.cs

// <copyright file="_Test.cs">Copyright &copy;  2010</copyright>
using System;
using ClassLibrary1;
using Microsoft.Pex.Framework;
using Microsoft.Pex.Framework.Validation;
using NUnit.Framework;

namespace ClassLibrary1
{
    [PexClass(typeof(\u7a0e\u51e6\u7406))]
    [PexAllowedExceptionFromTypeUnderTest(typeof(InvalidOperationException))]
    [PexAllowedExceptionFromTypeUnderTest(typeof(ArgumentException), AcceptExceptionSubtypes = true)]
    [TestFixture]
    public partial class _Test
    {
        [PexMethod]
        public decimal _(
            [PexAssumeUnderTest]\u7a0e\u51e6\u7406 target,
            decimal arg1,
            decimal arg2
        )
        {
            decimal result = target.\u5916\u7a0e\u8a08\u7b97(arg1, arg2);
            return result;
        }
    }
}

今回は、パラメータの日本語が削除されていますね。ASCII 以外があると無視するけど空文字になる場合は、"_" にするルールなのかな?
次に、Pex を実行して生成されたテストケースのコードを見てみましょう。
コードは、reports フォルダの <実行日時:yyMMdd.HHmmss.ffff>.pex\Tests フォルダに入っています。

_Test_DecimalDecimal1.g.cs

// <auto-generated>This code was generated by a Microsoft Pex.
// 
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.</auto-generated>
using System;
using ClassLibrary1;
using Microsoft.Pex.Framework;
using Microsoft.Pex.Framework.Generated;
using NUnit.Framework;

namespace ClassLibrary1
{
    public partial class _Test
    {
        [Test]
        [PexGeneratedBy(typeof(_Test))]
        public void _110()
        {
            decimal d;
            \u7a0e\u51e6\u7406 s0 = new \u7a0e\u51e6\u7406();
            d = this._(s0, decimal.MaxValue, 2034639888M);
            PexAssert.AreEqual<decimal>(default(decimal), d);
            PexAssert.IsNotNull((object)s0);
        }

        [Test]
        [PexGeneratedBy(typeof(_Test))]
        public void _484()
        {
            decimal d;
            \u7a0e\u51e6\u7406 s0 = new \u7a0e\u51e6\u7406();
            d = this._(s0, default(decimal), default(decimal));
            PexAssert.AreEqual<decimal>(default(decimal), d);
            PexAssert.IsNotNull((object)s0);
        }

        [Test]
        [PexGeneratedBy(typeof(_Test))]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void _ThrowsArgumentOutOfRangeException257()
        {
            decimal d;
            \u7a0e\u51e6\u7406 s0 = new \u7a0e\u51e6\u7406();
            d = this._(s0, default(decimal), -76819052936496198642298613574e-19M);
        }
    }
}

一応問題無さそうですね。ただ、1クラスに日本語だけのメソッドが2つ以上あった場合や、1アセンブリ内に日本語だけのクラスが2つ以上あった場合はダメそうな感じ…。
実際試したところ、
・1クラスに日本語だけのメソッドが2つ以上あった場合は、2つめ以降のメソッドは、"_01"、"_02"という形でナンバリングされていたのでエラーが出ませんでした。
・1アセンブリ内に日本語だけのクラスが2つ以上あった場合は、pexwizard で「PexClass 属性が重複しています」というエラーが発生しました。


ただ全て体験談なので、pexwizard を使わずに実行する場合(Visual Studio のアドオン)や、pexwizard に渡すパラメータで回避出来るのかもしれません。
しかし、日本語を使うのに制限が掛かるのは嫌だな〜。