Translate

Wednesday, 29 September 2010

Agile Tour 2010 - Noida Links to photos

Agile Tour 2010 Noida Photos - http://tinyurl.com/35ltoha

Tuesday, 8 June 2010

Making NUnit 2.5.5+ work with .Net 4.0

It seems that many have found NUnit 2.5.5 not working with DLLs compiled with .net 4.0. NUnit 3.x has been designated to work with .net 4.0; till that time make a modification to the NUnit config file and add this startup element under the main configuration element :

<startup>
<requiredRuntime="v4.0.30319"/>
</startup>

   

Monday, 31 May 2010

BDD + UADD

This is a cool way of satisfying most of the stakeholders in the development process as well as automating, to a large extent, the scenarios and the acceptance criteria of the tester, without burdening the software development process with too many artifacts or overheads.

In fact, you can accomplish both BDD (Business ("B" for Business or Behavior? I will be exploring this in the upcoming Agile NCR 2010) Driven Development) as well as UADD (User Acceptance Driven Development) with the help of Slim without burdening the underlying development model.

The Scenario tables do not do anything by themselves but when combined with Script or Decision tables they help in maintaining a level of automation in the SDLC that help the business analyst understand that his requirements are visibly satisfied. This can be understood as a BDD approach with the acceptance criteria being defined by the "business" in the Scenario table itself. Of course, there is a maturity level and sense of responsibility to be assumed by the "business" in this approach.

The same acceptance criteria can be defined in Decision tables, which will come at a functional/acceptance test phase that can be identified as a UADD approach. In this form, the tester writes the acceptance criteria after the "Dev completed" swimlane is achieved.

More tools like "Trinidad" (for Java developers) ensures that the developer, too, is able to understand how the acceptance tests are working by running the fitnesse tests right from within JUnit!

Of course, ultimately the goal is the same - to deliver working software at the end of a timebox; the only difference is in how you want to drive the software development process. It is just the packaging that is different!

Thursday, 6 May 2010

Decision & Scenario Tables in Slim

There are two exciting features in Slim - the Decision Table and the Scenario Table. Below are the screen shots of both:


A Scenario table, as in the above image, does not by itself do anything and that is why the Scenario does not show green but, when combined with the Decision table, you get the desired test behavior as in the below image.


Every scenario described in the scenario table gets executed when a Decision table contains the exact name of the Scenario. Here, it is a Script table that helps Slim knows that it has to execute the Scenario script and not the fixture code.

More about the script and the code in a later post.

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;
}
}
}