Visual Studio 2010 (たぶん 2012 も) の MSTest の delta を指定する Assert.AreEqual には下記のようなバグがある。
バグの原因はソースを見れば明らかで、NaN を考慮していないため。
[Assert.AreEqual のソース (ILSpy)]
Assert.AreEqual が含まれるアセンブリの配置場所は
%VS のディレクトリ%\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
[修正済み Assert.AreEqual のソース (ILSpy)]
が、VS2010 をインストールしている場合、修正されたアセンブリ「Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll」(以降、UnitTestFramework.dll)が使われないケースがある。
[確認できた発生条件]
かつ、VS2010 の UnitTestFramework.dll (.NET 4.0) と VS2013 の UnitTestFramework.dll (.NET 2.0) のバージョン番号「10.0.0.0」が同じであるため。(公開キーは MS 製品なので同じ)
※他にバージョン番号「10.1.0.0」の UnitTestFramework.dll も存在するが、設定で参照されないようになっている
VS2010 と VS2013 をインストールした環境の GAC は下記の状態になる。
そして、CLR 4 の実行アプリは CLR 4 の GAC を優先するため、バグ有りの方の UnitTestFramework.dll が参照されることになる。(参考:GAC 内のアセンブリ検索方法)
公開キーが一緒なのは仕方ないとして、バージョン番号さえ変えとけば、こんな事態は回避できた・・・
%windir%\Microsoft.NET\assembly\GAC_MSIL\Microsoft.VisualStudio.QualityTools.UnitTestFramework\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
副次的な効果として、VS2010 のテストプロジェクトからも修正された UnitTestFramework.dll が使用されるようになる。
// delta を指定する場合
Assert.AreEqual(1.0, double.NaN, 1.0); // 成功
// delta を指定しない場合
Assert.AreEqual(1.0, double.NaN); // 失敗
// 失敗するのが正しい動作なので、delta を指定する方はバグっている
バグの原因はソースを見れば明らかで、NaN を考慮していないため。
[Assert.AreEqual のソース (ILSpy)]
public static void AreEqual(double expected, double actual, double delta, string message, params object[] parameters)
{
if (Math.Abs(expected - actual) > delta)
{
string message2 = FrameworkMessages.AreEqualDeltaFailMsg((message == null) ? string.Empty : Assert.ReplaceNulls(message), expected.ToString(CultureInfo.CurrentCulture.NumberFormat), actual.ToString(CultureInfo.CurrentCulture.NumberFormat), delta.ToString(CultureInfo.CurrentCulture.NumberFormat));
Assert.HandleFail("Assert.AreEqual", message2, parameters);
}
}
// 比較条件に NaN が含まれると false になるので if の中に入らない
Assert.AreEqual が含まれるアセンブリの配置場所は
%VS のディレクトリ%\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
Visual Studio 2013 では修正されているが・・・
このバグは VS2013 では修正されている。- .net - Why does Assert.AreEqual(1.0, double.NaN, 1.0) pass? - Stack Overflow
- VS2010 & VS2013 SxS Customer Impacting issue | Microsoft Connect
[修正済み Assert.AreEqual のソース (ILSpy)]
public static void AreEqual(double expected, double actual, double delta, string message, params object[] parameters)
{
if (double.IsNaN(expected) || double.IsNaN(actual) || double.IsNaN(delta))
{
string message2 = FrameworkMessages.AreEqualDeltaFailMsg((message == null) ? string.Empty : Assert.ReplaceNulls(message), expected.ToString(CultureInfo.CurrentCulture.NumberFormat), actual.ToString(CultureInfo.CurrentCulture.NumberFormat), delta.ToString(CultureInfo.CurrentCulture.NumberFormat));
Assert.HandleFail("Assert.AreEqual", message2, parameters);
}
if (Math.Abs(expected - actual) > delta)
{
string message3 = FrameworkMessages.AreEqualDeltaFailMsg((message == null) ? string.Empty : Assert.ReplaceNulls(message), expected.ToString(CultureInfo.CurrentCulture.NumberFormat), actual.ToString(CultureInfo.CurrentCulture.NumberFormat), delta.ToString(CultureInfo.CurrentCulture.NumberFormat));
Assert.HandleFail("Assert.AreEqual", message3, parameters);
}
}
// 引数のいずれかが NaN の場合、テスト失敗
が、VS2010 をインストールしている場合、修正されたアセンブリ「Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll」(以降、UnitTestFramework.dll)が使われないケースがある。
[確認できた発生条件]
- VS2010 と VS2013 インストール済 (インストール順序は関係ない)
- .NET 4.0 以上のテストプロジェクト
原因
VS2010 は GAC に .NET 2.0 と 4.0 の UnitTestFramework.dll (バグ有り) をインストールするが、VS2013 は .NET 2.0 の UnitTestFramework.dll (修正済み) しかインストールしないため。かつ、VS2010 の UnitTestFramework.dll (.NET 4.0) と VS2013 の UnitTestFramework.dll (.NET 2.0) のバージョン番号「10.0.0.0」が同じであるため。(公開キーは MS 製品なので同じ)
※他にバージョン番号「10.1.0.0」の UnitTestFramework.dll も存在するが、設定で参照されないようになっている
VS2010 と VS2013 をインストールした環境の GAC は下記の状態になる。
CLR 2.0 | %windir%\assembly | 修正済み |
---|---|---|
CLR 4 | %windir%\Microsoft.NET\assembly | バグ有り |
そして、CLR 4 の実行アプリは CLR 4 の GAC を優先するため、バグ有りの方の UnitTestFramework.dll が参照されることになる。(参考:GAC 内のアセンブリ検索方法)
公開キーが一緒なのは仕方ないとして、バージョン番号さえ変えとけば、こんな事態は回避できた・・・
解決手段
上記リンクでも説明されてるけど、CLR 4 の GAC の実ファイルを移動または削除すればOK。%windir%\Microsoft.NET\assembly\GAC_MSIL\Microsoft.VisualStudio.QualityTools.UnitTestFramework\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll
副次的な効果として、VS2010 のテストプロジェクトからも修正された UnitTestFramework.dll が使用されるようになる。
0 件のコメント:
コメントを投稿