Friday, May 19, 2006

How to make your own test runner in NUnit

This isn't my cleanest piece of code, but it shows how you can write your own test runner in NUnit (V2.2.8). This is very dull if you don't do coding.

using System ;
using System.Reflection ;
using NUnit.Core.Builders ;
 
namespace NUnit.Core.Extensions
{
    [ AttributeUsage ( AttributeTargets.Method , AllowMultiple = false ) ]
    public class VagueExpectedExceptionTestAttribute : Attribute
    {
        protected Type _exceptionType ;
        public string _startsWith ;
        public string _endsWith ;
        public string _contains ;
 
        public Type ExceptionType
        {
            get { return _exceptionType ; }
            set
            {
                if ( !( value.IsSubclassOf ( typeof ( Exception ) ) ) )
                    throw new ArgumentException  
( "Type must be derived from Exception" ) ;
 
                this._exceptionType = value ;
            }
        }
 
        public string StartsWith
        {
            get { return _startsWith ; }
            set { _startsWith = value ; }
        }
 
        public string EndsWith
        {
            get { return _endsWith ; }
            set { _endsWith = value ; }
        }
 
        public string Contains
        {
            get { return _contains ; }
            set { _contains = value ; }
        }
    }
 
    [ TestCaseBuilder ]
    public class VagueExpectedExceptionTestBuilder : NUnitTestCaseBuilder
    {
        const string AttributeType =
"NUnit.Core.Extensions.VagueExpectedExceptionTestAttribute" ;
 
        public override bool CanBuildFrom ( MethodInfo method )
        {
            return Reflect.HasAttribute ( method , AttributeType , false ) ;
        }
 
        public TestCase Make ( MethodInfo method )
        {
            VagueExpectedExceptionTestAttribute testAttribute =
                ( VagueExpectedExceptionTestAttribute ) 
Reflect.GetAttribute ( method , AttributeType , false ) ;
            return
                new VagueExpectedExceptionTest (
method ,
testAttribute.ExceptionType ,
testAttribute.StartsWith ,
                                testAttribute.EndsWith ,
testAttribute.Contains
) ;
        }
 
        protected override TestCase MakeTestCase ( MethodInfo method )
        {
            return Make ( method ) ;
        }
    }
 
    public class VagueExpectedExceptionTest : TestMethod
    {
        private Type _exceptionType ;
        private string _startsWith ;
        private string _endsWith ;
        private string _contains ;
        private string _test = string.Empty ;
 
        public VagueExpectedExceptionTest (
MethodInfo method ,
Type exceptionType ,
string startsWith ,
string endsWith ,
                            string contains )
            : base ( method , exceptionType , null )
        {
            _exceptionType = exceptionType ;
            _startsWith = startsWith ;
            _endsWith = endsWith ;
            _contains = contains ;
        }
 
 
        protected override void ProcessException (
Exception exception ,
TestCaseResult testResult )
        {
            if ( exception.GetType ( ) == this._exceptionType )
                if ( TestMessage ( exception.Message ) )
                    testResult.Success ( ) ;
                else
                    testResult.Failure (
                        string.Format (
"Expected message to {0}, but actual message was {1}" ,
this.Test ,
                            exception.Message ) ,
null ) ;
            else
                testResult.Failure (
this._exceptionType + " was expected" ,
null ) ;
        }
 
        private string Test
        {
            get { return _test ; }
        }
 
 
        protected override void ProcessNoException ( TestCaseResult testResult )
        {
            testResult.Failure ( this._exceptionType + " was expected" , null ) ;
        }
 
        private bool TestMessage ( string message )
        {
            if ( !string.IsNullOrEmpty ( this._startsWith ) )
            {
                this._test = string.Format ( "start with '{0}'" , this._startsWith ) ;
                return message.StartsWith ( _startsWith ) ;
            }
            if ( !string.IsNullOrEmpty ( this._endsWith ) )
            {
                this._test = string.Format ( "end with '{0}'" , this._endsWith ) ;
                return message.EndsWith ( _endsWith ) ;
            }
            if ( !string.IsNullOrEmpty ( this._contains ) )
            {
                this._test = string.Format ( "contain '{0}'" , this._contains ) ;
                return message.Contains ( this._contains ) ;
            }
 
            return true ;
        }
    }
}


usage:

[VagueExpectedExceptionTest( ExceptionType=typeof(ArgumentNullException), StartsWith=DatasetResponseProcessor.LOG_DAL_NOT_SET)]
public void shouldThrowErrorWithoutDatasetDal ( )
{
    new DatasetResponseProcessor ( ).Process ( _response );
}

No comments: