Tuesday, November 30, 2004

TestDriven.NET 1.0 is released on www.testdriven.net (MbUnit ships with TD.NET). Check out the brand new web site!   

You are a TD.NET user ? Use the link builder and add a cool image like this one on your blog or web site...TestDriven.NET

posted on Tuesday, November 30, 2004 8:49:00 AM UTC  #    Comments [14]
 Monday, November 29, 2004

The next version (greater than 1.0.903d) contains a bunch of decorators that will deny access to file, file dialog, sql client, oracle client, etc... The decorators are located in the MbUnit.Framework.1.1.dll in the MbUnit.Framework.Security namespace.

For example you can deny access to the SqlClient using the following:

using MbUnit.Core.Framework;
using MbUnit.Framework;
using MbUnit.Framework.Security;
[TestFixture]
public class MyFixture
{
    [Test]
    [DenySqlClient]
    public void AccessDatabase()
    {
        // access to SQL client will fail in this method.
    }
}
posted on Monday, November 29, 2004 8:49:00 AM UTC  #    Comments [11]

I have added 2 new improvements to MbUnit to avoid having tests blocked by assertions or timeouts:

  • Assertion dialog caused by Debug.Assert are automatically swallowed (by removing the default debug trace)
  • TimeOut (in minutes) can be set at the fixture level:
[TestFixture(TimeOut = 1)]
public class MyFixture{...}

Those changes will be available in release greater than 1.0.903

posted on Monday, November 29, 2004 8:24:00 AM UTC  #    Comments [3]
 Friday, November 26, 2004

Question: So you are using files in your application, how do you test easily how it behaves if the file access is denied ?
Answer: Use declarative permissions to deny all access on the files

Ok that's a rough introduction, let me develop the idea. When your application relies on using resources such as files, TcpChannels, registry, etc... you should test how it behaves when the access to those resources is refused. The resource denial can be caused by a lot of external factors (loss of connectivity, etc...), lack of physical resources, .... or by denied security permissions. In other words, security permissions is an easy way to simulate various situations such as file access error, etc... 

Let me illustrate this by implementing a test decorator for MbUnit that makes all file access diened.

Creating DenyFileIOAccess decorator

As all test decorators, we derive a new attribute class from MbUnit.Core.DecoratorPatternAttribute and a new IRunInvoker from DecoratorRunInvoker:

using System;
using System.Security.Permissions;
using System.Collections;
using MbUnit.Core.Invokers;
using MbUnit.Core.Framework;
namespace MbUnit.Framework.Security
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple  = false, Inherited =true)]
    public sealed class DenyFileIOAccessAttribute : DecoratorPatternAttribute
    {
        public override IRunInvoker GetInvoker(IRunInvoker invoker)
        {
            return new DenyFileIOAccessRunInvoker(invoker, this);
        }
        private sealed class DenyFileIOAccessRunInvoker : DecoratorRunInvoker
        {
            private DenyFileIOAccessAttribute attribute;
            public DenyFileIOAccessRunInvoker(
                IRunInvoker invoker,
                DenyFileIOAccessAttribute attribute)
                :base(invoker)
            {
                this.attribute = attribute;
            }
            [FileIOPermission(SecurityAction.Deny, AllFiles = FileIOPermissionAccess.AllAccess)]
            public override object Execute(Object o, IList args)
            {
                return this.Invoker.Execute(o, args);
            }
        }
    }
}

The important thing to notice in the snippet is the FileIOPermission attribute that tags the execute method. All the code executed inside that method will have file IO denied. So since Invoker.Execute calls the test method, we have what we are looking for.

DenyFileIOAccessAttribute in action

Let put the new decorator in action. The following snippet shows a simple test that tries to create a new file. The execution log using TestDriven.NET is outputed below. As one can see, a SecurityException was raised by the framework when trying to open the file.... it's magic.

using System;
using System.IO;
using MbUnit.Framework;
using MbUnit.Framework.Security;
namespace MbUnit.Demo
{
    [TestFixture]
    public class SecurityTest
    {
        [Test]
        [DenyFileIOAccess]
        public void SecureMethod()
        {
            using (StreamWriter writer = new StreamWriter("test.txt"))
            {
                writer.Write("we should not be here");
            }
        }
    }
}

-- output

------ Test started: Assembly: MbUnit.Tests.1.1.dll ------
Info: Test Execution
Info: Exploring MbUnit.Tests.1.1, Version=1.0.1791.9801, Culture=neutral, PublicKeyToken=null
Info: MbUnit 2.22.0.0 Addin
Info: Found 1 tests
Info: [failure] SecurityTest.SecureMethod
TestCase 'SecurityTest.SecureMethod' failed: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
 System.Security.SecurityException
 Message: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
 Source: mscorlib
 StackTrace:
 at System.Security.CodeAccessSecurityEngine.Check(PermissionToken permToken, CodeAccessPermission demand, StackCrawlMark& stackMark, Int32 checkFrames, Int32 unrestrictedOverride)
 at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
 at System.Security.CodeAccessPermission.Demand()
 at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
 at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
 at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
 at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
 at System.IO.StreamWriter..ctor(String path)
 \securitytest.cs(22,0): at MbUnit.Demo.SecurityTest.SecureMethod()
0 succeeded, 1 failed, 0 skipped, took 0.00 seconds.

---------------------- Done ----------------------

This methodology applies to the other types of permissions that can be found in the System.Security namespace.

Where can I get those ?

MbUnit will soon contain a few other of those attributes. Since it is a .Net 1.1 feature, they will be enclosed in the MbUnit.Framework.1.1.dll under the MbUnit.Security namespace.

posted on Friday, November 26, 2004 7:07:00 PM UTC  #    Comments [3]
 Tuesday, November 23, 2004

Reflector.CodeMetrics is a new Addin for Reflector that analyses and computes several code quality metrics on your assemblies. This addin uses the excellent Reflector API to compute classic metrics such as the cyclomatic complexity or more straightforward such as the number of local variables in a method. All results can be dumped to file (using DataSet.Save)

Download Reflector.CodeMetrics (look for Reflector.CodeMetrics.zip) For installation and usage instructions, please read the Readme.txt enclosed in the zip file.

Tip: when you explore the result, you can doubleclick on the border of the row to show the item in the decompiler

 

posted on Wednesday, November 24, 2004 4:21:00 AM UTC  #    Comments [14]
 Thursday, November 18, 2004

This is a preview of a new Reflector Addin that computes various CodeMetrics on .Net assemblies. The excellent Reflector API makes it very easy to do this kind of things. Here are the metrics that I plan to implement :

  • Counting metrics: Module/Assembly, Type/Module, Method/Type, etc...
  • IL counting metrics: IL/Method, LocalVariables/Method, ExceptionHandlers/Method, etc...
  • IL flow graph metrics: components, cyclomatic complexity,
  • Method graph: methodrank, callers, callees, components, distance from entry point,
  • Type graph: type rank, inherance level, etc...

I have not done an extensive research on the subject so I might forget a lot of them, suggestions and links welcome.

Note that this uses a plugin architecture so that anyone can write and use his own metric.

Screenshot:

posted on Thursday, November 18, 2004 10:50:00 AM UTC  #    Comments [18]
 Wednesday, November 17, 2004
posted on Thursday, November 18, 2004 6:55:00 AM UTC  #    Comments [0]
 Monday, November 15, 2004
 Wednesday, October 20, 2004

This new functionality enables you to specify a tabular list of test cases that are to be feeded to the test method. Let me illustrate that with the floating point division testing (as in the FIT framework Simple Example ):

numerator denominator quotient()
1000 10 100.0000
-1000 10 -100.0000
1000 7 142.85715
1000 .00001 100000000
4195835 3145729 1.3338196

You can now translate this directly to C# in MbUnit using the RowTestAttribute and the RowAttribute:

[TestFixture]
public class DivisionFixture
{
    [RowTest]
    [Row(1000,10,100.0000)]
    [Row(-1000,10,-100.0000)]
    [Row(1000,7,142.85715)]
    [Row(1000,0.00001,100000000)]
    [Row(4195835,3145729,1.3338196)]
    public void DivTest(double numerator, double denominator, double result)
    {
        Assert.AreEqual(result, numerator / denominator, 0.00001 );
    }
}

Of course, these tests are not very well targeted because we do not test the “special” floating point values such as 1,0,double.MaxValue, double.MinValue, NaN but you get the picture.

What if a test should throw ? In that case, you can specify the exception type as an additional parameter in the RowAttribute constructor:

    [Row(1,0,0, ExpectedException = typeof(ArithmeticException))]
    public void DivTest(double numerator, double denominator, double result)
    {...}

The final output of the tests is as follows where you can see that 5 tests (one per row) were generated and executed.

Info: Found 5 tests
Info: [assembly-setup] success
Info: [success] RowTestDemo.DivTest(0)
Info: [success] RowTestDemo.DivTest(1)
Info: [success] RowTestDemo.DivTest(2)
Info: [success] RowTestDemo.DivTest(3)
Info: [success] RowTestDemo.DivTest(4)
Info: [assembly-teardown] success
Info: [reports] generating HTML report
posted on Wednesday, October 20, 2004 9:30:00 PM UTC  #    Comments [7]
 Monday, October 18, 2004

I'm slowly catching up with putting some order in the MbUnit documentation. Therefore, MbUnit has now a Wiki (FlexWiki powered) part of the TestDriven.NET wiki. Feel free to contribute...

http://www.testdriven.net/wiki/default.aspx/MyWiki.MbUnit

posted on Monday, October 18, 2004 7:36:00 PM UTC  #    Comments [12]
 Sunday, October 17, 2004

MbUnit has now a basic support for loading fixture and tests based on their names, such fixture are called Naked Fixtures . Although this may look like a step backward in functionality, this can be handy in particular situations. For example, if you don't want to reference any test framework, this is a good solution because it does not require any type or attribute.

Naming rules

  • class name must end with “Fixture“
  • fixture setup method must be named “TestFixtureSetUp“
  • fixture teardown method must be name “TestFixtureTearDown“
  • setup method must be named “SetUp”
  • teardown method must be named “TearDown”
  • test methods must end with “Test”
  • all rules are case sensitive

Limitations

  • [Update: decorators are supported].
  • no combinatorial tests

QuickStart

 Below are two fixture. The first uses attributes and should be familiar to you. The second is it's naked equivalent:

[TestFixture]
public class ClassicFixture
{
    [TestFixtureSetUp]
    public void TestFixtureSetUp()
    {
        Console.WriteLine("TestFixtureSetUp");
    }
    [SetUp]
    public void SetUp()
    {
        Console.WriteLine("SetUp");
    }
    [Test]
    public void First()
    {
        Console.WriteLine("Test1");
    }
    [Test]
    public void SecondTest()
    {
        Console.WriteLine("Test1");
    }
    [TearDown]
    public void TearDown()
    {
        Console.WriteLine("TearDown");
    } 
    [TestFixtureTearDown]
    public void TestFixtureTearDown()
    {
        Console.WriteLine("TestFixtureTearDown");
    }
}

Naked version:

public class NakedFixture
{
    public void TestFixtureSetUp()
    {
        Console.WriteLine("TestFixtureSetUp");
    }
    public void SetUp()
    {
        Console.WriteLine("SetUp");
    }
    public void FirstTest()
    {
        Console.WriteLine("Test1");
    }
    public void SecondTest()
    {
        Console.WriteLine("Test1");
    }
    public void TearDown()
    {
        Console.WriteLine("TearDown");
    }
    public void TestFixtureTearDown()
    {
        Console.WriteLine("TestFixtureTearDown");
    }
}
posted on Sunday, October 17, 2004 12:43:00 PM UTC  #    Comments [1]
 Friday, October 15, 2004

TestDrivent.NET, which contains MbUnit, QuickGraph, TestFu and Refly, has gone RC2 .

See http://www.testdriven.net/wiki/default.aspx/MyWiki.DownLoad

 

posted on Friday, October 15, 2004 4:37:00 PM UTC  #    Comments [4]

Check out this new Reflector addin that creates diffs. Very cool...

http://codingsanity.blogspot.com/2004/10/reflector-diff.html

posted on Friday, October 15, 2004 7:14:00 AM UTC  #    Comments [7]
 Saturday, October 09, 2004

PDFizer: A XHTML to PDF converter: with this library, you can transform simple XHTML pages to nice and printable PDF files. This project is based on the excellent webzine article "Pdfizer, a dumb HTML to PDF converter, in C#" written by Jonathan de Halleux.

Cool, my PDFizer project has been resurected. If you are looking for an easy way to convert HTML pages into PDF, you might well be interrested by that one.

posted on Saturday, October 09, 2004 11:12:00 AM UTC  #    Comments [3]
 Tuesday, October 05, 2004

MutantBuild is the back bone behind TestDriven.NET / MbUnit compilation. Jamie Cansdale has published an installer that will let you play with it. Anybody automating VS.NET solution should have a look at this.

posted on Wednesday, October 06, 2004 3:14:00 AM UTC  #    Comments [4]
 Monday, October 04, 2004

Sometimes, a unit test does not fail but does not succeed entirely: making it fail is too extreme and on the other hand, letting him succeed would make you miss the issue. Therefore, MbUnit now supports warnings:

  • A warning can be emited in any test case using Assert.Warning methods,
  • A warning does not make test fail,
  • Warnings are recorded in the test report (in the Html report, they are displayed right after the fixture summary),
  • Multiple warnings can be outputed per test

QuickStart

This fixture shows 2 tests with warnings:

using System;

using MbUnit.Core.Framework;

using MbUnit.Framework;

namespace MbUnit.Demo

{

[TestFixture]

public class WarningTest

{

[Test]

public void Warning()

{

Assert.Warning("Be wary");

}

[Test]

public void Warning2()

{

Assert.Warning("Something weird happened");

}

}

}

The corresponding html report looks like this:

posted on Tuesday, October 05, 2004 12:42:00 AM UTC  #    Comments [3]
 Sunday, October 03, 2004

This is the last entry on my dev box before I pack it and send to the US Do not expect much responsivness during the 2 next weeks until I get it back.

posted on Monday, October 04, 2004 3:29:00 AM UTC  #    Comments [3]
 Friday, October 01, 2004

As you may have already understood it, MbUnit as well as QuickGraph, TestFu and Refly source code have been moved to the TestDriven.NET source control server. This means that the source in the Tigris CVS are outdated!

The reasons why...

There are 4 main reasons for moving to Jamie Cansdale servers. Subversion, TestDriven.NET integration and Continuous integration

1. Subversion

This is not a major reason for leaving tigris, but Subversion is much more handy to use that CVS.

2. TD.NET integration

When developing the MbUnit addin for TestDriven.NET, we faced problems of versioning. This usually meant loosing time synchronizing TD.NET and MbUnit source, etc... Having both sources in the same repository has considerably simplified things.

3. Continuous Integration

This is by far the most important reason for moving MbUnit. The build setup currently running on TD.NET servers uses CC.NET, MSBuild and Wix to compile, execute tests and produce an installer each build. As soon as Jamie fixes his ftp problems , the installer will be uploaded on the web server on each build.

This means that release time for MbUnit will considerably shorten while benefiting from the quality ensurance of continuous integration. Image that you file a bug, it is corrected and you have an updated installer within the day!

 

posted on Saturday, October 02, 2004 12:55:00 AM UTC  #    Comments [18]

MbUnit has been released as part of the new TestDriven.NET build. Please check Jamies blog for the links to the downloads. MbUnit is now compiled using a complex build setup that is described on Jamie's blog.

Change log

  • Assembly loading had problems in the previous version. All should be fixed now,
  • RollbackAttribute is back in a separate assembly (MbUnit.Framework.1.1.dll) compiled against .NET 1.1
  • Added Assembly Dependencies and Fixture dependencies
  • Better TD.NET integration

 

posted on Friday, October 01, 2004 11:29:00 AM UTC  #    Comments [2]
 Thursday, September 30, 2004
I have stumbled on this web site: http://iv.slis.indiana.edu/index.html It has amazing examples of data visualization!
posted on Friday, October 01, 2004 1:46:00 AM UTC  #    Comments [1]

FlexWiki is an evolved WikiWikiWeb implementation for .NET. It has an extensible internal language, called WikiTalk, that can be used to extend the framework with new behaviors. I'm currently exploring this framework with some nifty ideas... here's a first snapshot: a behavior that renders the graph of the pages (all the nodes are clickable)

 

posted on Thursday, September 30, 2004 1:30:00 PM UTC  #    Comments [7]

Following the idea of Fixture dependency, I have added Assembly dependencies as well: execute tests from child assembly only if parents were successful.

Similarly, we use the AssemblyDependsOnAttribute to specify the parent assemblies:

[assembly: MbUnit.Core.Framework.AssemblyDependsOn("AnotherAssembly")]
posted on Thursday, September 30, 2004 1:24:00 PM UTC  #    Comments [1]

MbUnit now supports setting dependencies between fixtures, similarly to NAnt/MSBuild task dependencies.

How-to

The logic is simple. You can tag a fixture with the DependsOnAttribute to specify a "parent" fixture that should be run before the current fixture. If the parent fixture fails, the current fixture is not run:

[TestFixture]
public class Parent
{...}

[TestFixture]
[DependsOn(typeof(Parent))]
public class Child
{...}

The Child fixture is executed if the Parent fixture executed successfully.

Why do we need dependencies between fixtures ?

Image that you are testing a database. At first, you create a fixture that tests that the connection is correct:

[TestFixture]
public class ConnectionTest
{ ... }

If one of the tests of ConnectionTest fails, then it is likely that all the tests that rely on a database connection will fail and, therefore, should not be executed. Using the DependsOnAttribute, you can specify the dependency of such fixture to the ConnectionFixture.

[TestFixture]
[DependsOn(typeof(Connection))]
public class DALTest
{...}

An example

The following example defines 4 fixture. Child depends on Parent and SickParent, GrandChild depends on Child. Since SickParent has a failed test, Child and GrandChild should not be executed...

[TestFixture]
[CurrentFixture]
public class Parent
{
    [Test]
    public void Success()
    {}
}

[TestFixture]
[CurrentFixture]
public class SickParent
{
    [Test]
    public void Failure()
    {
        throw new Exception("boom");
    }
}

[TestFixture]
[CurrentFixture]
[DependsOn(typeof(Parent))]
[DependsOn(typeof(SickParent))]
public class Child
{
    [Test]
    public void Success()
    {
    }
}

[TestFixture]
[CurrentFixture]
[DependsOn(typeof(Child))]
public class GrandChild
{
    [Test]
    public void Success()
    {}
}

The report result is shown below and one can see that Child and GrandChild fixture have failed without being executed.

posted on Thursday, September 30, 2004 9:00:00 AM UTC  #    Comments [10]
 Wednesday, September 29, 2004
After 4 years working in CESAME, I finally graduated as Doctor in Applied Mathematics :)
posted on Thursday, September 30, 2004 12:42:00 AM UTC  #    Comments [23]
 Friday, September 24, 2004

MbUnit has now the ability of re-executing the failed tests cases and ignoring the successful tests.  A test case filter loads the previous XML result from a file and filters all the fixture that have not failed.

QuickStart example

This is the main function of MbUnit.Demo. We use the AutoRunner to make an assembly that is self-executable and we set the special filter (FailureRunPipeFilter). This filter will try to load the previous report. If it finds it, it will use the information to ignore successfull tests.

public static void Main(string[] args)

{

using (AutoRunner auto = new AutoRunner())

{

// creating the report name

string reportName = Path.GetFullPath(String.Format("{0}.xml", auto.GetReportName()));

 

FailureRunPipeFilter filter = new FailureRunPipeFilter(reportName);

auto.Domain.RunPipeFilter = filter;

 

auto.Run();

auto.ReportToHtml();

auto.ReportToXml(false);

}

}

Results:

I have executed twice MbUnit.Demo (don't be afraid about the number of failures, they are intentional, it's a demo!) The first report shows the first run result and second shows the second run report... Abracadadra, only failed tests remain

posted on Saturday, September 25, 2004 4:31:00 AM UTC  #    Comments [1]
 Thursday, September 23, 2004

This is a preview of a new language for Reflector that outputs to Refly (Refly is wraps up and simplifies the use of CodeDom).

What does the language do ?

The language creates Refly code. If the Refly code is executed it will generate the original code. This is particularly usefull to rapidely design CodeDom template: write the expected output, Reflectorize-it and get the Refly code. In the figure below, we see the code "cycle of life" with a decompiler and how it is modified if we add the "Refly" language.

A preview example

There is still a lot of work to do on the language but it can already generate the outline of classes. Let's see that on a simple class:

public class Original

{

private string name;

public Original()

{}

public string Name

{

get { return this.name;}

set { this.name = value;}

}

public void Run(string someParamter)

{

Console.WriteLine("{0}: someParameter");

}

public event EventHandler Click;

protected virtual void OnClick(EventArgs e)

{

if (this.Click != null)

this.Click(this, e);

}

}

After compiling and  loading in Reflector, the Refly language is outputting:

NamespaceDeclaration _dragAndDropUnitTesting = new NamespaceDeclaration("Original");

 

ClassDeclaration _original = _dragAndDropUnitTesting.AddClass("Original");

 

// Fields

FieldDeclaration name = _original.AddField(typeof(System.String), "name");

FieldDeclaration Click = _original.AddField(typeof(System.EventHandler), "Click");

 

// Events

EventDeclaration _click = _original.AddEvent(typeof(System.EventHandler), "Click");

 

// Constructor and Methods

ConstructorDeclaration ctor0 = _original.AddConstructor();

ctor0.Attributes |= System.CodeDom.MemberAttributes.Assembly;

ctor0.Attributes |= System.CodeDom.MemberAttributes.Family;

MethodDeclaration _run = _original.AddMethod("Run");

_run.Attributes |= System.CodeDom.MemberAttributes.Assembly;

_run.Attributes |= System.CodeDom.MemberAttributes.Family;

ParameterDeclaration _runsomeParamter = _run.Signature.Parameters.Add(typeof(System.String), "someParamter");

MethodDeclaration _onClick = _original.AddMethod("OnClick");

_onClick.Attributes |= System.CodeDom.MemberAttributes.Family;

ParameterDeclaration _onClicke = _onClick.Signature.Parameters.Add(typeof(System.EventArgs), "e");

 

// Properties

PropertyDeclaration _name = _original.AddProperty(typeof(System.String), "Name");

 

That's pretty ugly but not as much if you had to write CodeDom for that. We can compile and generate the code using the following instruction:

CodeGenerator gen = new CodeGenerator();
gen.GenerateCode(".", _dragAndDropUnitTesting);

Finally, the output of the execution is as follows:

using System;

/// <summary />

/// <remarks />

public class Original

{

/// <summary />

/// <remarks />

private string _name;

/// <summary />

/// <remarks />

private System.EventHandler _click;

/// <summary />

/// <remarks />

Original()

{

}

/// <summary />

/// <remarks />

public virtual string Name

{

}

/// <summary />

/// <remarks />

public event System.EventHandler Click;

/// <summary />

/// <remarks />

void Run(string someParamter)

{

}

/// <summary />

/// <remarks />

void OnClick(System.EventArgs e)

{

}

}

Of course, the result is far from behing perfect. Visibility handling sucks, statements are not reflected, etc... But sounds very promising to me :)

posted on Friday, September 24, 2004 2:30:00 AM UTC  #    Comments [11]
Just sent the manuscript of the my thesis to the printer... One last step (public presentation) and I'm free!
posted on Thursday, September 23, 2004 10:17:00 PM UTC  #    Comments [6]
 Wednesday, September 22, 2004

Reflector.Graph has been updated for Reflector 4.1.6.0.

Download available at www.dotnetwiki.org

posted on Wednesday, September 22, 2004 8:32:00 PM UTC  #    Comments [6]
 Tuesday, September 21, 2004

This is the first release candidate for MbUnit 2.21.1.0. This release also contains QuickGraph (+NGraphviz), Refly and TestFu.

Acknowledgment
I'd like to give a special thanks to Jamie Cansdale (TestDriven.NET) which has been the main architect of the new MbUnit compilation scripts,  installers and TestDriven.NET intergration.

Installing MbUnit 2.21.1.0 RC1

[Update: follow the instructions at http://www.testdriven.net/wiki/default.aspx/MyWiki.DownLoad]

Where is MbUnit installed ?

The MbUnit assemblies are located in Program Files/TestDriven.NET/MbUnit.

New features

 

posted on Tuesday, September 21, 2004 11:49:00 PM UTC  #    Comments [22]
 Monday, September 20, 2004

Sorry, I can' resist putting little animation of the new design-time support in MbUnit. This sample shows how you can easily set up monitoring on a few PerformanceCounter inside a fixture component. (Demo solution at http://blog.dotnetwiki.org/downloads/DragAndDropUnitTesting.zip )

How-to

The procedure to monitor a PerformanceCounter is as follows:

  1. Add any PerformanceCounter to the component (drag and drop from the Toolbox),
  2. Make sure they are set up,
  3. For each PerformanceCounter, add a PerformanceCounterChecker and associate it a PerformanceCounter instance in the property pane
  4. Add the desired tests

For each of the test, the PerformanceCounterChecker will monitor the value of it's associated counter and it will assert if the value goes out of the specified bounds. In the report, a little summary of the counter values is shown (in the Console.Out view of the report).

posted on Monday, September 20, 2004 10:58:00 AM UTC  #    Comments [6]
 Sunday, September 19, 2004

I've recently discovered Context in .Net while reading the Programming .Net Components book (Chapter 11). This is an amazing piece of technology that I definitely needed to try. A first try was to make a Caching context:

Caching context

Image that you have methods that perform long computation, such as querying a database etc..., and return a result. Usually, the result does not change much over time, so typically you would like to cache the results in order to improve the efficiency of the application. Now imagine that there exists a Caching context that would take care of caching method calls. For example, we would like to write something like this:

[Caching]
public class CachedClass : ContextBoundObject
{
    [Cached]
    public string ReturnBigObject()
    { 
        Console.WriteLine("miss");
        Thread.Sleep(1000);
        return DateTime.Now.ToString(); 
    }
}

In that sample, we would like the output of ReturnBigObject to be cached. For example, the sample method below shows the desired behavior. The first call to ReturnBigObject is a cache miss and then, the remaining calls are cached.

miss
c.ReturnBigObject(): 5/10/2004 19:31:31
c.ReturnBigObject(): 5/10/2004 19:31:31
c.ReturnBigObject(): 5/10/2004 19:31:31

Let's see the steps to take to create the caching context:

Building the context (1): CachingAttribute

The CachingAttribute has to inherit from ContextAttribute and override two methods. The main task of the attribute is to add a IContextProperty implementation to the context properties (GetPropertiesForNewContext method). 

[AttributeUsage(AttributeTargets.Class,AllowMultiple =false,Inherited =true)]
public class CachingAttribute : ContextAttribute
{
    public CachingAttribute():base("Chaching")
    {}
    public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
    {
        IContextProperty property =
            new CachingContextProperty(ctorMsg.ActivationType);
        ctorMsg.ContextProperties.Add(property);
    }
    public override bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
    {
        return false;
    }
}

Building the context (1.1): CachedAttribute

The CachedAttribute is used to tag method to be cached. It contains several parameters to set up the HttpRuntime.Cache object.

Building the context (2): CachingContextProperty

The task of this class is to install a server IMessageSink in the message flow that will cache the message calls. Therefore, this class implements IContextProperty, IContributeServerContextSink.

public class CachingContextProperty : 
    IContextProperty, IContributeServerContextSink
{
    private Type activationType;
    ...
    public IMessageSink GetServerContextSink(IMessageSink nextSink)
    {
        CachingSink cachingSink = new CachingSink(nextSink, activationType);
        return cachingSink;
    }
}

Building the context (3): CachingSink

This is where the real work occurs. This class filters the call to the method (IMethodMessage) and looks in a Cache (HttpRuntime.Cache) if it is stored, if stored it returns the value, otherwize it calls the next sink and store the value in the Cache. (This part of the code is a little bit more technical because a part of the IMethodReturnMessage has to be "copied").

The heart of this class is as follows:

public IMethodReturnMessage SyncProcessMessage(IMethodMessage msg)
{
    // creating unique hash value out of method, instance and paramteres
    string hash = Hash(msg);
    // looking in the cache
    IMethodReturnMessage returnMessage = HttpRuntime.Cache[hash] as IMethodReturnMessage;
    if (returnMessage != null) // cache hit
        return returnMessage;
    
    returnMessage = this.Parent.NextSink.SyncProcessMessage(msg) 
        as IMethodReturnMessage;

    // caching returned information
    CachedMethodReturnMessage cachedMessage= new CachedMethodReturnMessage(returnMessage);

    // storing in cache
    HttpRuntime.Cache.Add(hash, cachedMessage,
        this.cachedAttribute.Dependencies,
        this.cachedAttribute.AbsoluteExpiration,
        this.cachedAttribute.SlidingExpiration,
        this.cachedAttribute.Priority,
        null);
    IMethodReturnMessage r = HttpRuntime.Cache[hash] as IMethodReturnMessage;
    return returnMessage;
}

Downloads

The full source is available on www.dotnetwiki.org

 

posted on Monday, September 20, 2004 6:50:00 AM UTC  #    Comments [12]

I've recently discovered Context in .Net while reading the Programming .Net Components book (Chapter 11). This is an amazing piece of technology that I definitely needed to try. A first try was to make a Caching context:

Caching context

Image that you have methods that perform long computation, such as querying a database etc..., and return a result. Usually, the result does not change much over time, so typically you would like to cache the results in order to improve the efficiency of the application. Now imagine that there exists a Caching context that would take care of caching method calls. For example, we would like to write something like this:

[Caching]
public class CachedClass : ContextBoundObject
{
    [Cached]
    public string ReturnBigObject()
    { 
        Console.WriteLine("miss");
        Thread.Sleep(1000);
        return DateTime.Now.ToString(); 
    }
}

In that sample, we would like the output of ReturnBigObject to be cached. For example, the sample method below shows the desired behavior. The first call to ReturnBigObject is a cache miss and then, the remaining calls are cached.

miss
c.ReturnBigObject(): 5/10/2004 19:31:31
c.ReturnBigObject(): 5/10/2004 19:31:31
c.ReturnBigObject(): 5/10/2004 19:31:31

Let's see the steps to take to create the caching context:

Building the context (1): CachingAttribute

The CachingAttribute has to inherit from ContextAttribute and override two methods. The main task of the attribute is to add a IContextProperty implementation to the context properties (GetPropertiesForNewContext method). 

[AttributeUsage(AttributeTargets.Class,AllowMultiple =false,Inherited =true)]
public class CachingAttribute : ContextAttribute
{
    public CachingAttribute():base("Chaching")
    {}
    public override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg)
    {
        IContextProperty property =
            new CachingContextProperty(ctorMsg.ActivationType);
        ctorMsg.ContextProperties.Add(property);
    }
    public override bool IsContextOK(Context ctx, IConstructionCallMessage ctorMsg)
    {
        return false;
    }
}

Building the context (1.1): CachedAttribute

The CachedAttribute is used to tag method to be cached. It contains several parameters to set up the HttpRuntime.Cache object.

Building the context (2): CachingContextProperty

The task of this class is to install a server IMessageSink in the message flow that will cache the message calls. Therefore, this class implements IContextProperty, IContributeServerContextSink.

public class CachingContextProperty : 
    IContextProperty, IContributeServerContextSink
{
    private Type activationType;
    ...
    public IMessageSink GetServerContextSink(IMessageSink nextSink)
    {
        CachingSink cachingSink = new CachingSink(nextSink, activationType);
        return cachingSink;
    }
}

Building the context (3): CachingSink

This is where the real work occurs. This class filters the call to the method (IMethodMessage) and looks in a Cache (HttpRuntime.Cache) if it is stored, if stored it returns the value, otherwize it calls the next sink and store the value in the Cache. (This part of the code is a little bit more technical because a part of the IMethodReturnMessage has to be "copied").

The heart of this class is as follows:

public IMethodReturnMessage SyncProcessMessage(IMethodMessage msg)
{
    // creating unique hash value out of method, instance and paramteres
    string hash = Hash(msg);
    // looking in the cache
    IMethodReturnMessage returnMessage = HttpRuntime.Cache[hash] as IMethodReturnMessage;
    if (returnMessage != null) // cache hit
        return returnMessage;
    
    returnMessage = this.Parent.NextSink.SyncProcessMessage(msg) 
        as IMethodReturnMessage;

    // caching returned information
    CachedMethodReturnMessage cachedMessage= new CachedMethodReturnMessage(returnMessage);

    // storing in cache
    HttpRuntime.Cache.Add(hash, cachedMessage,
        this.cachedAttribute.Dependencies,
        this.cachedAttribute.AbsoluteExpiration,
        this.cachedAttribute.SlidingExpiration,
        this.cachedAttribute.Priority,
        null);
    IMethodReturnMessage r = HttpRuntime.Cache[hash] as IMethodReturnMessage;
    return returnMessage;
}

Downloads

The full source is available on www.dotnetwiki.org

 

posted on Monday, September 20, 2004 6:50:00 AM UTC  #    Comments [12]
 Saturday, September 18, 2004

Following the example of drag and drop unit tests. I have added support for the classic ExpectedException behavior as well as the four Setup, TearDown, FixtureSetUp, FixtureTearDown methods (sorry another screen grad).

 

posted on Sunday, September 19, 2004 6:15:00 AM UTC  #    Comments [5]

Following the example of drag and drop unit tests. I have added support for the classic ExpectedException behavior as well as the four Setup, TearDown, FixtureSetUp, FixtureTearDown methods (sorry another screen grad).

 

posted on Sunday, September 19, 2004 6:15:00 AM UTC  #    Comments [5]
 Friday, September 17, 2004

Reflector.Graph release for Reflector 4.1.5.0 available at www.dotnetwiki.org

[Update] Changed Reflector.Graph back to an assembly

New addins:

 

 

posted on Friday, September 17, 2004 8:12:00 PM UTC  #    Comments [8]

Reflector.Graph release for Reflector 4.1.5.0 available at www.dotnetwiki.org

[Update] Changed Reflector.Graph back to an assembly

New addins:

 

 

posted on Friday, September 17, 2004 8:12:00 PM UTC  #    Comments [8]
 Thursday, September 16, 2004

Image that you could open the designer, drag and drop a few test case, and run them with minimal writing... now take a look at this:

(Download a demo solution at http://blog.dotnetwiki.org/downloads/DragAndDropUnitTesting.zip )

posted on Friday, September 17, 2004 4:52:00 AM UTC  #    Comments [20]

Image that you could open the designer, drag and drop a few test case, and run them with minimal writing... now take a look at this:

(Download a demo solution at http://blog.dotnetwiki.org/downloads/DragAndDropUnitTesting.zip )

posted on Friday, September 17, 2004 4:52:00 AM UTC  #    Comments [20]

Introduction

Have you ever wondered how you could animate armies of thousands of soldiers ? flocks of hunderds of fish ? etc... Well, you use what they call Autonomous Agents: agents that have a local behavior that creates interresting global behaviors. The first example of autonomous agents was brought in 1984 by Craig Reynolds which developped a small application to simulation flocks: the boids application was born.

Since then, Reynolds has published an excellent paper in 99 on the subject: Steering behavior for Autonomous Characteres. If you never had a look at this, check out his web site and look at the java demo, it is just splendid!

Previous try

During my Phd, I monitored the course of C/C++ for third year Engineer students. The autonomous agents theme was very appealing and students got very involved into that project. (If you are looking for something fun for teaching software engineering, this theme is great!). At that time, they received a mini drawing library that could render agents in real time in OpenGL and Glut. If you want to give it a try, you can download it from www.dotnetwiki.org (look for Autonomous.binaries.zip in the download section) Of course, I tested the project on myself and built an application that looked as follows:

 

On the picture, you can see 151 agent (green dots) that are moving toward the little black dot. They are avoiding themselves, avoiding obstacles (big gray circle). The little lines between agents show that there is a "flocking" interaction,i.e. they are avoiding themselves.

During that project, we could see a lot of interresting properties of such flocks. For example, the system has a self-organization property. If you let the simulation go long enough, agents will organize themselves in a perfect triangular tiling as show below:

We could also see waves where the agents stopped going in reverse direction from the direction of the flock (In PDE theory, those are called shocks). In fact, it is the same phenomenon that occurs in traffic jam when a wave a "zero" velocity is travelling along the highway. When you stand back in your car, just look at the way you will start run a few hundred meters and the stop, and again and again. This behavior is predicted by the hyperbolic PDE theory :) In the figure below, the agents are moving left toward the little black dot. You can visualize the waves going right. The gray lines denote flock which means that agents are stopping in order to avoid each other.

NSteer

The code C++ was written using Tempate Meta Programming. In NSteer, I'll try to build gradually a framework for C#

posted on Thursday, September 16, 2004 11:16:00 PM UTC  #    Comments [8]