Translate

Friday 28 August 2009

Unit Testing .Net 4.0 with TDD.Net

Hey,

Even if NUnit in its current form does not support .Net 4.0, there is a workaround with Test Driven.Net. Download, install and VS 2010 acknowledges Test Driven.Net and you can run your unit tests right inside VS 2010. It is as cool as NUnit.

Here is the code to test the RandomGenerator class:

using System;
using NUnit.Framework;
using RandomCalculator;
namespace ClassLibrary1
{
[TestFixture]
public class Class1
{
[Datapoints]
public int[] parametersForRandomGeneration = RandomCalculatorClass.GenerateRandomNumbers();
[Theory]
public void RandomNumbers(int x, int y, int z)
{
Assume.That(z > 0 && z <4);
if (z == 1)
{
Assert.That(x+y, Is.EqualTo(RandomCalculatorClass.add(x,y)));
}
else if (z == 2)
{
Assert.That(x * y, Is.EqualTo(RandomCalculatorClass.multiply(x, y)));
}
else if (z == 3)
{
Assert.That(x / y, Is.EqualTo(RandomCalculatorClass.divide(x, y)));
}
prevNumber = z;
}
}
}

Happy Unit Testing !:)

NUnit for .Net 4.0

Shucks! NUnit currently does not support .Net 4.0 assemblies or may be expectations are ahead !

Thursday 27 August 2009

Parallel.For XML Parsing

Another example using Parallel.For. Depending upon the cores in your machine, you will find the code returning different results. MaxDegreeOfParallelism sets the max number of cores to be used for running the parallel forloop.

class Program
{
static void Main(string[] args)
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load("e:\\JKTAgileAcademy_August2009\\cd_catalog.xml");
XmlNodeList title = xDoc.GetElementsByTagName("CD");
XmlNode xNode=null;
var options = new ParallelOptions { MaxDegreeOfParallelism = 2 };
Stopwatch sw=new Stopwatch();
sw.Start();
Parallel.For(0, title.Count, options, (j) => //() => title, (x, loop, xN) =>
{
xNode = title.Item(j);
Console.WriteLine("Inner XML from Nodelist" + xNode.InnerText);
j++;
}
);
sw.Stop();
Console.WriteLine("Time taken by parallel loop " + sw.ElapsedMilliseconds.ToString());
//sw.Reset();
sw.Start();
for (int i = 0; i < title.Count; i++)
{
xNode = title.Item(i);
Console.WriteLine(xNode.InnerText);
}
sw.Stop();
Console.WriteLine("Time taken by for loop " + sw.ElapsedMilliseconds.ToString());

Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}

Parallel Computing - .Net 4.0

Ah. I said, when i watched the TechEd cast in MSDN Tv, i can understand the difference between multi-threading and parallel computing correctly and the importance of cores in a CPU. But that is the only joy that you get from .Net 4.0!

I took the plunge, downloaded VS 2010 and wham !, the product literally explodes in your fingers (with a 2 GB dual core laptop)!! Context menus, intellisense menus fly in and out and the previous "system" and ctrl-space is now more polished with "sys" bringing up the menu! Ok, so fa so good!

I essayed into "paral.."ctrl-space and nothing appeared in the menu! You have to include System.Threading to be able to use the Parallel class. Ah, first step done! Next step that I was eager to try was the Parallel.For method. First, I thought of parsing a XML tree but then decided for a simpler approach - the traditional calculator! Here is the code:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
//sw.Reset();
sw.Start();
Parallel.For(0,225, (x)=>
{
Task t2 = new Task(() =>
{

int[] w=GenerateRandomNumbers();
Calculate(w[0], w[1], w[2]);
});//,TaskCreationOptions.PreferFairness);

t2.Start();
t2.Wait();
});
sw.Stop();
Console.WriteLine("Finished parallel task in (milliseconds) - {0}",sw.ElapsedMilliseconds);
//sw.Reset();
sw.Start();
for (int i = 0; i < 225; i++)
{
int[] w = GenerateRandomNumbers();
Calculate(w[0], w[1], w[2]);
}
sw.Stop();
Console.WriteLine("Finished task in (milliseconds) - {0}", sw.ElapsedMilliseconds);

Console.ReadLine();
}
static int[] GenerateRandomNumbers()
{
Random r = new Random();
Random r1 = new Random();
Random r2 = new Random();
return new int[] { r.Next(150), r1.Next(100), r2.Next(4) };
}
static int add(int a, int b)
{
return a + b;
}
static int multiply(int a, int b)
{
return a * b;
}
static int divide(int a, int b)
{
return a / b;
}
static void Calculate(int x, int y, int operation)
{
switch (operation)
{
case 1:
Console.WriteLine("Added two numbers {0} ",add(x,y));
break;
case 2:
Console.WriteLine("Product of two numbers {0} ",multiply(x,y));
break;
case 3:
Console.WriteLine("Divided two numbers {0} ",divide(x,y));
break;
}
}
}


Notes:
1. Increase the loop condition value so that you can see more random number combination.

2. Aside from Parallel, the code above also dwells in Task - a class that is part of the System.Threading.Tasks namespace. A task is like a thread but unlike a thread it has more sophisticated provisions like scheduling, creation options etc.

3. //,TaskCreationOptions.PreferFairness);

Uncomment the above statement and you will see a rather reluctant execution of the loop. The intellisense guide is below:

A hint to TaskScheduler to schedule this task as fairly as possible, meaning the tasks scheduled early will run early and those later will run later!!
Happy .Net 4.0 programming!

4. With the above commented, you see that the Parallel FOr loop runs faster than the normal for loop.