Translate

Friday 30 April 2010

The Slim Framework

Agile is getting leaner and leaner or so the efforts around the world indicate! And keeping in tune, tools like Slim for .net attempt to reduce complexity in lifecyle activities thereby infusing more agility into the development process.

Slim is the all new Fitnesse-based Test System that has distinct advantages over its pre-decessor - Fitnesse. Fit is, even now, the default test runner in Fitnesse so if you want to use Slim, you need to indicate to fitnesse to use Slim's Test Runner with

!define TEST_SYSTEM {slim}

Then indicate the path of the assembly to test with,

!path c:\SlimGenome.dll (Change this to your .dll file and path)

Then define the command pattern

!define COMMAND_PATTERN {%m -r fitSharp.Slim.Service.Runner,c:\fitSharp\fitsharp.dll %p}

Finally, define the test runner.

!define TEST_RUNNER {c:\fitsharp\Runner.exe}

If you want to debug your script use the RunnerW.exe. This will open a new window that will wait till you press the "Go" button. Press it! Or it will seem that Fitnesse is running the tests over a long period of time!

The advantage with Slim is

1. You do not have to write a separate C# fixture to test the class' functionality.
2. You do not have to learn the "fit" way of writing a class fixture for a column fixture, a row fixture and know which class to inherit from. Slim or rather, fitSharp takes care of this for you.
3. I can now map my Decision Tables (a.k.a. Column Fixtures in Fitnesse) with Scenario Tables and hop on to the BDD wagon without changing my base development process or lifecycle!

Of course, when you need to test custom types, Slim will pose a few challenges but it is worthwhile for the basic usages like a Column Fixture as evident in the below script:

|slim genome series|AT < GC >,A <TA >|
|generategenomepattern?|
|ATGAT|
| ATGAA |
| ATCAT |
| ATCAA |

The first column in the table is the class name. Second column is passing the input to the constructor of the C# class. The next row indicates the Method Under Test. The other rows are the expected output from the test.

That is it. No need to break your head with the developer to know the methods and property names etc and no need for the developer to re-write a separate C# fixture with references to fit.dll and etc.

You can download Slim, fitSharp from

http://github.com/jediwhale/fitsharp/downloads


Happy Fitnesse Testing!

Unit & Mock Testing "New" and "Override" implementations

It has been quite a while since I posted to my blog because I didn't have anything interesting to publish. But now, here is an interesting challenge. Unit testing the "new" and "override" keyword implementation.

Since, the "new" keyword was introduced to hide a base class implementation there has been a lot of arguments on how to actually show the execution of these methods in a polymorphic perspective.

Below is an example that solidly tests the classes and generates the necessary result.

// Class Under Test

using System;
using NUnit.Framework;
namespace NewAndOverrideTest
{
public class BaseClass
{
protected BaseClass ob;
public BaseClass()
{

}
public virtual BaseClass OverrideMethod()
{
ob = new BaseClass();
Console.WriteLine("Virtual from Base Class");
return ob;
}
}
public class DerivedClass : BaseClass
{
public override BaseClass OverrideMethod()
{
ob = new DerivedClass();
Console.WriteLine("Override from DerivedClass Class");
return ob;
}
}
public class SecondDerivedClass : DerivedClass
{
public new BaseClass OverrideMethod()
{
ob = new SecondDerivedClass();
Console.WriteLine("New from SecondDerivedClass Class");
return ob;
}
}
public class ThirdDerivedClass : SecondDerivedClass
{
public BaseClass OverrideMethod()
{
ob = new ThirdDerivedClass();
Console.WriteLine("New from ThirdDerivedClass Class");
return ob;
}
}
}

// The NUnit Tests

using System;
using NUnit.Framework;
namespace NewAndOverrideTest
{
public class UnitTestOfNewAndOverride
{
[TestFixture]
public class TestNewOverride
{
private BaseClass baseClassObject;
private DerivedClass derivedClassObject;
private SecondDerivedClass secondDerivedClassObject;
[SetUp]
public void InitializeCUTObject()
{
}
[Test]
public void TestTheObjectCallingTheBaseMethod()
{
baseClassObject = new DerivedClass();
Assert.That(baseClassObject.OverrideMethod(), Is.InstanceOf(typeof(DerivedClass)));
}
[Test]
public void TestTheObjectCallingTheSecondDerivedMethod()
{
derivedClassObject = new SecondDerivedClass();
Assert.That(derivedClassObject.OverrideMethod(), Is.InstanceOf(typeof(SecondDerivedClass)));
}

The 2nd test, "TestTheObjectCallingTheSecondDerivedMethod" fails because the instance is pointing to SecondDerivedClass whose "OverrideMethod" is actually a "new" implementation. This causes the execution engine not to look for polymorphic behavior but to call the object instance type's implementation, ie, the DerivedClass OverrideMethod.

The test will pass if Assert statement is changed to query for "InstanceOf(typeof(DerivedClass)".

Below is the same test with Rhino Mock. I have used Rhino Mock just to demonstrate mock testing, with Rhino Mock, in the unit tests. It is a rather contrived example but it serves its purpose.

Rhino Mock 2.6, NUnit 2.5 and .net 2.0 are required to execute the tests and the code.


// The Interface

using System;

namespace NewAndOverrideTest
{
public interface INewOverride
{
void NewMethod();
Object OverrideMethod();
}
}

// The NUnit Test Class
using System;
using NUnit.Framework;
using Rhino.Mocks;
namespace NewAndOverrideTest
{
[TestFixture]
public class TestNewOverride
{
private BaseClass baseClassObject;
private DerivedClass derivedClassObject;
private SecondDerivedClass secondDerivedClassObject;
private ThirdDerivedClass thirdDerivedClassObject;
private MockRepository mockObject;
private INewOverride interfaceObject;
[SetUp]
public void InitializeCUTObject()
{
mockObject = new MockRepository();
interfaceObject = (INewOverride)mockObject.CreateMock(typeof(INewOverride));
}
[Test]
public void TestTheObjectCallingTheBaseMethod()
{
Expect.Call(interfaceObject.OverrideMethod()).Return(typeof(DerivedClass) as object);
mockObject.Record();
baseClassObject = new DerivedClass();
baseClassObject.NewMethod();
mockObject.ReplayAll();
Assert.That(interfaceObject.OverrideMethod(), Is.InstanceOf(typeof(object)));
mockObject.Verify(interfaceObject);
}
[Test]
public void TestTheObjectCallingTheSecondDerivedMethod()
{
Expect.Call(interfaceObject.OverrideMethod()).Return(typeof(SecondDerivedClass) as object);
mockObject.Record();
derivedClassObject = new SecondDerivedClass();
derivedClassObject.NewMethod();
mockObject.Replay(interfaceObject);
Assert.That(interfaceObject.OverrideMethod(), Is.InstanceOf(typeof(object)));
mockObject.Verify(interfaceObject);
}
[Test]
[ExpectedException(typeof(NullReferenceException))]
public void TestTheObjectCallingTheThirdDerivedMethod()
{
Expect.Call(interfaceObject.OverrideMethod()).Throw(new NullReferenceException());
mockObject.Record();
thirdDerivedClassObject = new ThirdDerivedClass();
//thirdDerivedClassObject.NewMethod();
mockObject.Replay(interfaceObject);
Assert.That(interfaceObject.OverrideMethod(), Is.InstanceOf(typeof(Object)));
mockObject.Verify(interfaceObject);
}
}
}

// The CUT (Class Under Test)
using System;

namespace NewAndOverrideTest
{
public class BaseClass:INewOverride
{
protected BaseClass ob;
public BaseClass()
{

}
public void NewMethod()
{
ob = new BaseClass();
Console.WriteLine("Base Class");
}
public Object OverrideMethod()
{
Console.WriteLine("Virtual from Base Class");
return ob as object;
}
}
public class DerivedClass : BaseClass
{
public void NewMethod()
{
ob = new DerivedClass();
Console.WriteLine("DerivedClass Class");
}
public Object OverrideMethod()
{
Console.WriteLine("Override from DerivedClass Class");
return ob as object;
}
}
public class SecondDerivedClass : DerivedClass
{
public void NewMethod()
{
ob = new SecondDerivedClass();
Console.WriteLine("SecondDerivedClass Class");
}
public new Object OverrideMethod()
{
Console.WriteLine("Override from SecondDerivedClass Class");
return ob;
}
}
public class ThirdDerivedClass : SecondDerivedClass
{
public void NewMethod()
{
ob = new SecondDerivedClass();
Console.WriteLine("ThirdDerivedClass Class");
}
public Object OverrideMethod()
{
Console.WriteLine("Override from ThirdDerivedClass Class");
return ob as object;
}
}
}