TestCaseSourceAttribute
TestCaseSourceAttribute indicates the source to be used to
provide test cases for a test method.
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Builders;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace NUnit.Framework
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class TestCaseSourceAttribute : NUnitAttribute, ITestBuilder, IImplyFixture
{
private NUnitTestCaseBuilder _builder = new NUnitTestCaseBuilder();
private const string SourceMustBeStatic = "The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.";
private const string ParamGivenToField = "You have specified a data source field but also given a set of parameters. Fields cannot take parameters, please revise the 3rd parameter passed to the TestCaseSourceAttribute and either remove it or specify a method.";
private const string ParamGivenToProperty = "You have specified a data source property but also given a set of parameters. Properties cannot take parameters, please revise the 3rd parameter passed to the TestCaseSource attribute and either remove it or specify a method.";
private const string NumberOfArgsDoesNotMatch = "You have given the wrong number of arguments to the method in the TestCaseSourceAttribute, please check the number of parameters passed in the object is correct in the 3rd parameter for the TestCaseSourceAttribute and this matches the number of parameters in the target method and try again.";
public object[] MethodParams { get; set; }
public string SourceName { get; set; }
public Type SourceType { get; set; }
public string Category { get; set; }
public TestCaseSourceAttribute(string sourceName)
{
SourceName = sourceName;
}
public TestCaseSourceAttribute(Type sourceType, string sourceName, object[] methodParams)
{
MethodParams = methodParams;
SourceType = sourceType;
SourceName = sourceName;
}
public TestCaseSourceAttribute(Type sourceType, string sourceName)
{
SourceType = sourceType;
SourceName = sourceName;
}
public TestCaseSourceAttribute(Type sourceType)
{
SourceType = sourceType;
}
public IEnumerable<TestMethod> BuildFrom(IMethodInfo method, Test suite)
{
foreach (TestCaseParameters item in GetTestCasesFor(method)) {
yield return _builder.BuildTestMethod(method, suite, item);
}
}
private IEnumerable<ITestCaseData> GetTestCasesFor(IMethodInfo method)
{
List<ITestCaseData> list = new List<ITestCaseData>();
try {
IEnumerable testCaseSource = GetTestCaseSource(method);
if (testCaseSource != null) {
int num = method.GetParameters().Length;
{
foreach (object item in testCaseSource) {
ITestCaseData testCaseData = item as ITestCaseData;
if (testCaseData == null) {
object[] array = item as object[];
if (array != null) {
if (array.Length != num)
array = new object[1] {
item
};
} else if (item is Array) {
Array array2 = item as Array;
if (array2.Rank == 1 && array2.Length == num) {
array = new object[array2.Length];
for (int i = 0; i < array2.Length; i++) {
array[i] = array2.GetValue(i);
}
} else
array = new object[1] {
item
};
} else {
array = new object[1] {
item
};
}
testCaseData = new TestCaseParameters(array);
}
if (Category != null) {
string[] array3 = Category.Split(new char[1] {
','
});
foreach (string value in array3) {
testCaseData.Properties.Add("Category", value);
}
}
list.Add(testCaseData);
}
return list;
}
}
return list;
} catch (Exception exception) {
list.Clear();
list.Add(new TestCaseParameters(exception));
return list;
}
}
private IEnumerable GetTestCaseSource(IMethodInfo method)
{
Type type = SourceType ?? method.TypeInfo.Type;
if (SourceName == null)
return Reflect.Construct(type, null) as IEnumerable;
MemberInfo[] member = type.GetMember(SourceName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
if (member.Length == 1) {
MemberInfo memberInfo = member[0];
FieldInfo fieldInfo = memberInfo as FieldInfo;
if (fieldInfo != (FieldInfo)null) {
if (!fieldInfo.IsStatic)
return ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.");
if (MethodParams != null)
return ReturnErrorAsParameter("You have specified a data source field but also given a set of parameters. Fields cannot take parameters, please revise the 3rd parameter passed to the TestCaseSourceAttribute and either remove it or specify a method.");
return (IEnumerable)fieldInfo.GetValue(null);
}
PropertyInfo propertyInfo = memberInfo as PropertyInfo;
if (propertyInfo != (PropertyInfo)null) {
if (!propertyInfo.GetGetMethod(true).IsStatic)
return ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.");
if (MethodParams != null)
return ReturnErrorAsParameter("You have specified a data source property but also given a set of parameters. Properties cannot take parameters, please revise the 3rd parameter passed to the TestCaseSource attribute and either remove it or specify a method.");
return (IEnumerable)propertyInfo.GetValue(null, null);
}
MethodInfo methodInfo = memberInfo as MethodInfo;
if (methodInfo != (MethodInfo)null) {
if (!methodInfo.IsStatic)
return ReturnErrorAsParameter("The sourceName specified on a TestCaseSourceAttribute must refer to a static field, property or method.");
if (MethodParams != null && methodInfo.GetParameters().Length != MethodParams.Length)
return ReturnErrorAsParameter("You have given the wrong number of arguments to the method in the TestCaseSourceAttribute, please check the number of parameters passed in the object is correct in the 3rd parameter for the TestCaseSourceAttribute and this matches the number of parameters in the target method and try again.");
return (IEnumerable)methodInfo.Invoke(null, MethodParams);
}
}
return null;
}
private static IEnumerable ReturnErrorAsParameter(string errorMessage)
{
TestCaseParameters testCaseParameters = new TestCaseParameters();
testCaseParameters.RunState = RunState.NotRunnable;
testCaseParameters.Properties.Set("_SKIPREASON", errorMessage);
return new TestCaseParameters[1] {
testCaseParameters
};
}
}
}