Unit Test Tool (nunit) Using Reflection and Custom Attributes)

Source: Internet
Author: User

Reflection is a major feature that distinguishes managed languages such as. NET and Java from traditional languages (such as C ++ and Delphi). Through reflection, we can dynamically create classes and call methods. After considering the nunit function, I thought I could use this feature to do it. So I made a manual exercise and basically achieved the effect. The nunit simulation framework is as follows:

// ================================================ =

Unitdll (simulate nunit. Framework)

[Attributeusage (attributetargets. Class)]
Public class testfixtureattribute: system. Attribute
{
Public testfixtureattribute ()
{
}
}

[Attributeusage (attributetargets. Method)]
Public class test: system. Attribute
{
Public test ()
{
}
}

// The preceding two attributes are used to identify the classes and methods to be tested.

/// <Summary>
/// Assert exception class, used to throw an Assert exception
/// </Summary>
Public class vassertexception: system. applicationexception
{

Private string m_expstr = "";

Public vassertexception ()
{
}

Public vassertexception (string ERR)
{
M_expstr = err;
}

Public String exceptionstr
{
Get {return m_expstr ;}
Set {m_expstr = value ;}
}
}

// The above is an exception class. When assert fails, an exception is thrown.

/// <Summary>
/// Assert class for unit test
/// </Summary>
Public class assert
{
Public assert ()
{
}

Public static void areequal (Object expected, object actual)
{
 
If (expected! = Actual)
{
String STR = "expected is:" + expected + "but actual is:" + actual;

Vassertexception E = new vassertexception (STR );
Throw E;
}
}
}

// The above provides the test method class, areequal, and assert class provided by nunit.

// ================================================ ==================================

Testdll: class for unit testing. Use the unitdll provided above.

/// <Summary>
//// Class for unit test
/// </Summary>
[Testfixture] // identifies the class to be tested
Public class vunittest
{
Public vunittest ()
{
System. Console. writeline ("Now the unit test class create ");
}

[Test]
Public void testmethod ()
{
System. Console. writeline ("this is a unit test method ");
Assert. areequal (1, 2); // use the assert class provided by unitdll for unit testing
}

// ==========================================

Unittest.exe simulates nunit.exe and provides a win form, which is displayed in Treeview mode.

The interface code is relatively simple and is not provided. It provides several key reflection and call codes:

Private void loaddll ()
{
This. treeview1.nodes. Clear ();
Rootnode = This. treeview1.nodes. Add (openfiledialog1.filename );

A = assembly. loadfrom (openfiledialog1.filename );

Type [] types = A. gettypes ();

Foreach (type in types)
{
Object [] attributes = type. getcustomattributes (false );

Foreach (Object OBJ in attributes)
{
// The class with the test information is obtained.
If (obj. GetType () = typeof (testfixtureattribute ))
{
// Add a class name
Treenode node = rootnode. nodes. Add (type. Name );

Methodinfo [] Methods = type. getmethods ();

Foreach (methodinfo method in methods)
{
Object [] methodattributes = method. getcustomattributes (false );

Foreach (Object objmehtodd in methodattributes)
{
If (objmehtodd. GetType () = typeof (TEST ))
{
Node. nodes. Add (method. Name );
}
}

}

}

}

}

This. treeview1.expandall ();

}
// The code above is relatively simple. Use reflection to obtain the classes and methods to be tested and display them in a Treeview.

Object OBJ = activator. createinstance (type );

Methodinfo method = type. getmethod (this. treeview1.selectednode. Text );
If (Method = NULL)
{
MessageBox. Show ("method mismatch ");
Return;
}

Object [] parameters = new object [0];
Method. Invoke (OBJ, parameters );

This. listbox1.items. insert (0, "OK ");
Setlabel (true );

}
Catch (system. reflection. targetinvocationexception ex)
{
String STR = ex. tostring ();

Exception exc = ex. innerexception;

If (EXC. GetType () = typeof (vassertexception ))
{
Vassertexception objex = (vassertexception) exc;

String SSTR = objex. exceptionstr;
This. listbox1.items. insert (0, SSTR );

This. listbox1.items. insert (0, exc. stacktrace );
This. listbox1.items. insert (0, Ex. stacktrace );

Setlabel (false );

}

// The above code is equivalent to run on the nunit interface and is also a core piece.

// Create the class to be tested (createinstance) and call invoke

// Determine whether the assertion fails (whether a custom exception is thrown out). If any, the test fails and the failure information is displayed on the interface.

// ================================================ ======================

Conclusion: The nunit effect can be basically achieved, but the business and interface code are mixed together, there is no good isolation,

A better way is to seal the reflection and provide an interface for interface response.

Thank you for your comments.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.