Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Test Data in Attribute

0.00/5 (No votes)
28 Jul 2013 1  
Attached the test data with method for regression testing by declaring ref type in attribute

Introduction

Test data is attached with method for regression testing and I have also declared the reference type in method custom attribute. For passing the reference type, type is declared in method custom attribute as a JSON object string and then I have parsed & converted the JSON object to actual entity object.

If you want to create the unit test project, you need to put in efforts for creating the unit test code for each and every test scenario. And also, if there is any change in the actual method signature, we have to refactor the test method. I hope the below solution will address this issue to reduce the effort of writing test method and is easy to maintain and make changes in test data as on when changes in method signature instead of creating the separate project for unit test code.

Background

My requirement is to pass the test data through method custom attribute and validate it against to the attached method. I am declaring test data for all possible test cases in method custom attribute and there are some cases where you need to pass reference object. But, System allows to declare all primitive type in .NET attribute and throws an exception if trying to pass the reference type.

For example:

[TestData("PositiveNo", 12, new ParamValue(FirstParam:10, SecondParam=2))]
public int AddNumber(int iParama, int iiParam)
{
     return iParama + iiParam;
} 

In this case, System throws a compilation error as attribute metadata generated while compiling the application and cannot allocate the memory space for reference type at compile time.

To solve this issue, pass reference type as JSON object string in method custom attribute and convert it as .NET entity object when reading metadata by using .NET reflection.

Define Attribute

Define the custom attribute by inheriting from .NET attribute type and set target as method declaration alone. This attribute has three properties given below for passing the test data.

  1. Scenario – what is the scenario name for unit testing
  2. Expected Result – what would be the expected result as executing the method
  3. Input values – Method parameter values are passed through JSON object for getting the actual result. This is passed as JSON object string when calling the constructor and then converted as .NET entity object by using JSON converter.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class TestData : Attribute
{
   private string _scenario;
   private int _exResult;
   private ParamValue _paramInput;

   public string Scenario { get { return _scenario; } set { _scenario = value; } }
   public int ExpectedResult { get { return _exResult; } set { _exResult = value; } }
   public ParamValue ParamInput { get { return _paramInput; } set { _paramInput = value; } }

   public TestData(string tScenario, int expectedResult, string paramInput)
   {
      this._scenario = tScenario;
      this._exResult =  expectedResult;
      this._paramInput = JsonConvert.DeserializeObject<paramvalue>(paramInput);
   }
}

ParamValue type is used to pass the method’s parameter value for getting the actual result. This is declared in custom attribute as JSON object and later on convert it as actual .NET entity object.

public class ParamValue
{
   private int _frtParama;
   private int _sndParam;

   public int FirstParam { get; set; }
   public int SecondParam { get; set; }
}

Test Data Declaration

Declare the test data input such expected result and input parameter value for generating the actual result in method custom attribute against the method.

[TestData("PositiveNo", 12, "{'FirstParam':10,'SecondParam':2}")]
[TestData("FailCase", -3, "{'FirstParam':-8,'SecondParam':4}")]
public int AddNumber(int iParama, int iiParam)
{
    return iParama + iiParam;
}

Parse Method Attribute

Get all declared methods in the given class and then read the custom attribute of method by using .NET Reflection.

public List<testdata> GetTestData<t>(T baseType)
{
    List<testdata> testList = null; 
    Type typeTest = typeof(T);

    foreach (MethodInfo mInfo in typeTest.GetMethods(BindingFlags.DeclaredOnly))
    {
        testList = ((TestData[]) mInfo.GetCustomAttributes(typeof(TestData), false)).ToList();
    }
    return testList;
}

Evaluate Test Data

We get the actual result by passing the test data to input parameter and then compare with expected result. Finally, it returns the result as Boolean.

testData.ExpectedResult.Equals(new AttributeData().
     AddNumber(testData.ParamInput.FirstParam, testData.ParamInput.SecondParam)));

Point of Interest

JSON object is passed through method custom attribute and convert it into actual entity object using reflection. This is one of the solutions for passing the reference type through attribute.

Test data can be attached with declared method of class and used the same for regression testing as similarly executing in stored procedure.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here