私は、ユーザーが華氏、摂氏、ケルビンの 3 つの温度スケールの異なる値の間で変換できるようにする小さな Windows フォーム アプリケーションを開発しました。初心者のテスターである私は、NUnit に手を出し始め、このフレームワークを学習する良い方法は、このプログラムにテスト コードを追加することだと思いました。作業の大部分を処理するクラスは次のとおりです:-
public static class TemperatureConverter
{
public static ConversionFormula CelciusToFahrenheit = t => ((t * 1.8) + 32);
public static ConversionFormula CelciusToKelvin = t => (t + 273);
public static ConversionFormula FahrenheitToCelcius = t => ((t - 32) * 5/9);
public static ConversionFormula FahrenheitToKelvin = t => (t + 459.67)/1.8;
public static ConversionFormula KelvinToCelcius = t => (t - 273);
public static ConversionFormula KelvinToFahrenheit = t => (t * 9/5 - 459.67);
public static double ConvertTemperature(double temperatureValue, ConversionFormula conversionFormula)
{
return conversionFormula(temperatureValue);
}
}
個々の温度値が正しく変換されていることを単純にテストすることから始めました。最終的にこれは面倒になり、多くの反復コードが必要になるため、値ごとに 1 つのテストを記述するのではなく、NUnit の「Range」属性と「Values」属性を使用して、10 個のバッチでテストできるようにしました。テスト方法の例は次のとおりです。
[TestFixture]
public class Class1
{
private ConversionFormula _fahrenheitToCelcius;
[SetUp]
public void Init()
{
_fahrenheitToCelcius = TemperatureConverter.FahrenheitToCelcius;
}
#region Fahrenheit To Celcius Positive Values
[Test, Sequential]
public void ConvertFahrenheitToCelciusRange_0_To_10_RoundedTo2DP([Range(0, 10, 1)]double temperature,
[Values(-17.78, -17.22, -16.67, -16.11, -15.56, -15, -14.44, -13.89, -13.33, -12.78, -12.22)]double expected)
{
double actual = TemperatureConverter.ConvertTemperature(temperature, _fahrenheitToCelcius);
Assert.AreEqual(expected, actual, 1);
}
範囲値はテストする温度で、この場合は 0 から 10 です。values 属性には、各テストの予想される結果が含まれます。NUnit 2.6.2 と Resharper Test Runner を使用しています。1 つのクラス ファイルにほぼ同じテスト メソッドを追加し、温度範囲を 10 の値に上げました。たとえば、次のテストは次のようになります:-
[Test, Sequential]
public void ConvertFahrenheitToCelciusRange_11_To_20_RoundedTo2DP([Range(11, 20, 1)]double temperature,
[Values(-11.67, -11.11, -10.56, -10, -9.44, -8.89, -8.33, -7.78, -7.22, -6.67)]double expected)
{
double actual = TemperatureConverter.ConvertTemperature(temperature, _fahrenheitToCelcius);
Assert.AreEqual(expected, actual, 1);
}
各テストが追加された後、それを実行して、成功したかどうかを確認しました。最終的に、範囲 0 から 150 までテストすることになったので、クラスごとに合計 15 のテスト メソッドがありました。ここで問題が発生します。Resharper テスト ランナーと NUnit テスト ランナーの両方がランダムに報告します
NUnit System.OverflowException: 算術演算でオーバーフローが発生しました
System.OverflowException...
Server stack trace:
at NUnit.Framework.RangeAttribute..ctor(Int32 from, Int32 to, Int32 step)
at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
at System.Reflection.CustomAttribute.CreateCaObject(RuntimeModule module, IRuntimeMethodInfo ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeParameterInfo parameter, RuntimeType caType)
at NUnit.Core.Reflect.GetAttributes(ICustomAttributeProvider member, Boolean inherit)
at NUnit.Core.Reflect.HasAttribute(ICustomAttributeProvider member, String attrName, Boolean inherit)
at NUnit.Core.Builders.ValueSourceProvider.HasDataFor(ParameterInfo parameter)
at NUnit.Core.Extensibility.DataPointProviders.HasDataFor(ParameterInfo parameter)
at NUnit.Core.Builders.CombinatorialTestCaseProvider.HasTestCasesFor(MethodInfo method)
at NUnit.Core.Extensibility.TestCaseProviders.HasTestCasesFor(MethodInfo method)
at NUnit.Core.Builders.NUnitTestCaseBuilder.BuildFrom(MethodInfo method, Test parentSuite)
at NUnit.Core.Extensibility.TestCaseBuilderCollection.BuildFrom(MethodInfo method, Test suite)
at NUnit.Core.Builders.NUnitTestFixtureBuilder.BuildTestCase(MethodInfo method, TestSuite suite)
at NUnit.Core.Builders.NUnitTestFixtureBuilder.AddTestCases(Type fixtureType)
at NUnit.Core.Builders.NUnitTestFixtureBuilder.BuildSingleFixture(Type type, Attribute attr)
at NUnit.Core.Builders.NUnitTestFixtureBuilder.BuildFrom(Type type)
at NUnit.Core.Extensibility.SuiteBuilderCollection.BuildFrom(Type type)
at NUnit.Core.TestFixtureBuilder.BuildFrom(Type type)
at NUnit.Core.Builders.TestAssemblyBuilder.GetFixtures(Assembly assembly, String ns)
at NUnit.Core.Builders.TestAssemblyBuilder.Build(String assemblyName, Boolean autoSuites)
at NUnit.Core.Builders.TestAssemblyBuilder.Build(String assemblyName, String testName, Boolean autoSuites)
at NUnit.Core.TestSuiteBuilder.BuildSingleAssembly(TestPackage package)
at NUnit.Core.TestSuiteBuilder.Build(TestPackage package)
at NUnit.Core.SimpleTestRunner.Load(TestPackage package)
at NUnit.Core.ProxyTestRunner.Load(TestPackage package)
at NUnit.Core.ProxyTestRunner.Load(TestPackage package)
at NUnit.Core.RemoteTestRunner.Load(TestPackage package)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at NUnit.Core.TestRunner.Load(TestPackage package)
at NUnit.Util.TestDomain.Load(TestPackage package)
at NUnit.Core.ProxyTestRunner.Load(TestPackage package)
at NUnit.Util.RemoteTestAgent.AgentRunner.Load(TestPackage package)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [1]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at NUnit.Core.TestRunner.Load(TestPackage package)
at NUnit.Core.ProxyTestRunner.Load(TestPackage package)
at NUnit.Util.ProcessRunner.Load(TestPackage package)
at NUnit.Util.TestLoader.LoadTest(String testName)
何度テストを再実行しようとしても、同じエラーが発生します。それだけでなく、完全に正常に動作していたアセンブリ内の他のすべてのテスト ファイルで、同じ問題が報告されるようになりました。最初は、Values または Range 属性に渡された値に問題があると思っていましたが、これをテストするために、新しいアセンブリを作成し、NUnit への参照を追加し、元のアセンブリからテストをコピーして貼り付けました。新しいものに。やあ、テストはすべて正常に実行されます。新しいアセンブリのテスト ファイルに変更を加えず、時々テストを実行すると、最終的に同じエラーが発生します。それだけでなく、他のすべてのテスト クラスも再び壊れます。これを回避する唯一の方法は、新しいアセンブリを作成し、古いテスト ファイルをコピー アンド ペーストすることです。そのうちまた壊れてしまうので良くありません。