Wednesday, April 28, 2004

Let's consider a simple fixture with a unit test that must throw. In this case, we use the ExpectedExceptionAttribute to tell the framework that the method should throw:

[TestFixture]
public class MyFixture
{
    [Test]
    [ExpectedException(typeof(Exception))]
    public void ThisMethodThrows()
    { ... }
}

ExpectedExceptionAttrribute is called a Decorator attribute because it decorates and alter the behavior of a test. Another commonly used decorator is IgnoreAttribute to ignore a test.

In MbUnit, other decorators are available. Here I describe two of those: RepeatAttribute and ThreadedRepeatAttribute. RepeatAttribute will make the execution of the test repeated the desired number of times in the same thread while ThreadedRepeatAttribute will launch simultaneously a desired number of threads that will execute the method. RepeatAttribute create a sequence of execution, ThreadedRepeatAttribute create a parallel execution.

    [Test]
    [Repeat(10)] // this will make the RepeatedTest executed 10 times
    public void RepeatedTest()
    { ... }


    [Test]
    [ThreadedRepeat(10)] // this will make the RepeatedTest executed in 10 concurent threads
    public void AmIThreadSake()
    { ... }

Decorators are chained internally in the order that they are defined, therefore declaration order is important if you want to combine them. For example, the two following test methods have different signification:

  • RepeatAndThrow means: repeat test 10 times, test should throw at each execution
  • ThrowWhileRepeating: repeat test 10 times, one of the test should throw during the repetition
    [Test]
    [Repeat(10)]
    [ExpectedException(typeof(Exception))]
    public void RepeatAndThrow()
    { ... }

    [Test]
    [ExpectedException(typeof(Exception))]
    [Repeat(10)]
    public void ThrowWhileRepeating()
    { ... }

posted on Thursday, April 29, 2004 12:51:00 AM UTC  #    Comments [2]
 Tuesday, April 27, 2004

NDoc is an extensible application: you can easily provide your own "documentation renderer", usually called documenter. I have used this feature to integrate NLiterate within NDoc and take advantage the built-in functions of the GUI. Here is the detailled procedure to create the NLiterate documenter.

1) Create the project:

Create an assembly project named NDoc.Documenter.*** where you replace *** with the name of your documenter. It is important to have your assembly named like this otherwise it will not be loaded by NDoc. Add the reference to NDoc.Core.dll.

2) Create the documenter config object:

The config class will be attached to the property grid control in the NDoc gui. This way we can easily define the different parameters of the documenter. The config class must implement IDocumenterConfig interface, however it is easier to inherit from BaseDocumenterConfig:

public class LiterateDocumenterConfig : BaseDocumenterConfig
{
    private string outputFile;
    public LiterateDocumenterConfig()
    :base("Literate")
    {
        this.OutputFile =String.Format(".{0}doc{0}compile-log.txt",Path.DirectorySeparatorChar);
    }

    public string OutputFile
    {
        get
        {
            return this.outputFile;
        }
        set
        {
            this.outputFile = value; 
            this.SetDirty();
        }
    }
}

Note that when OutputFile is modified, we notify NDoc using the protected method SetDirty.

3) Create the documenter class

The documenter class is the main class, it renders the documentation. This class must implement IDocumenter but again, it is easier to use the abstract base class BaseDocumenter:

public class LiterateDocumenter : BaseDocumenter
{ 
    public LiterateDocumenter()
    :base("Literate") // this is the name that will appear in the NDoc list box
    {
        this.Clear();
    }
    #region IDocumenter
    public override void Build(Project project)
    {
        // step one, load snippets
        loadSnippets(project);
        // step two, compile the snippets
        compileSnippets(project);
        // step three, create the report
        compileReport(project);
    }
    public override void Clear()
    {
        this.Config=new LiterateDocumenterConfig();
    }
    public override DocumenterDevelopmentStatus DevelopmentStatus 
    {  
        get
        {
            return DocumenterDevelopmentStatus.Alpha;
        }
    }
    public override string MainOutputFile
    {
        get
        {
            return ((LiterateDocumenterConfig)this.Config).OutputFile;
        }
    }
    #endregion
}

4) Adding progress notification

In the code above, we have not notified NDoc about the progress of the documentation rendering. This can be done through two functions: OnDocBuildingStep and OnDocBuildingProgress. For example:

    public override void Build(Project project)
    {
        // step one, load snippets
        OnDocBuildingStep(0, "Start loading snippets");
        loadSnippets(project);

        // step two, compile the snippets
        OnDocBuildingStep(40, "Start loading snippets");
        compileSnippets(project);
        // step three, create the report
        OnDocBuildingProgress(40); // increasing progress percentage of 40%
        compileReport(project);
    }

5) Copy the assembly

The last step is to copy your assembly into the NDoc bin folder. When launched, NDoc looks for assemblies named "NDoc.Documenter...." and loads by reflection that documenter they are containing. That's it.

posted on Tuesday, April 27, 2004 10:59:00 PM UTC  #    Comments [0]

I have added a new fixture, ProcessTestFixture, that implements the process testing presented by Marc Clifton in http://www.codeproject.com/csharp/autp3.asp.

A process is an ordered sequence of unit tests.  As long as one test passes, the next test is run. Due to the structure of MbUnit, this was straightforward to implement (I'll about this later in the blog). The syntax of the fixture is similar to Marc Clifton example but I have merge Test, Sequence(...) to TestSequence(...):

[ProcessTestFixture]
public MyProcess
{
    [TestSequence(1)]
    public void Hello()
    {...}
    [TestSequence(2)]
    public void World()
    {...}
    ...
}

The implementation of the fixture was done by the following steps:

  1. Create TestSequenceAttribute, a simple class inherited from TestPatternAttribute that stores the order,
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=true)]
    public sealed class TestSequenceAttribute : TestPatternAttribute
    {
        private int order;
      
        public TestSequenceAttribute(int order)
          {
            this.order = order;
        }
    
        public int Order
        {
            get
            {
                    return this.order;
            }
            set
            {
                this.order = value;
            }
        }
    }
  2. Create ProcessMethodRun, which implements IRun. This is where the "process" logic is created, more specifically in the Reflect method: since this method builds the tree of IRunInvoker instance, creating a process is just a matter of creating a sequence of MethodRunInvoker:
    public class ProcessMethodRun : IRun
    {
        ...
        public virtual void Reflect(
    			        RunInvokerTree tree, 
    			        RunInvokerVertex parent, 
            Type t
        )
        {
            // first gather all methods, with order.
            ArrayList methods = new ArrayList();
            foreach(MethodInfo mi in 
                    TypeHelper.GetAttributedMethods(t,this.AttributeType))
            {
                // get sequence attribute
                TestSequenceAttribute seq = 
                    (TestSequenceAttribute)TypeHelper.GetFirstCustomAttribute(mi,typeof(TestSequenceAttribute)); 
                methods.Add( new OrderedMethod(mi, seq.Order) ); 
            }
    
            // sort the methods
            QuickSorter sorter = new QuickSorter();
            sorter.Sort(methods);
    
            // populate execution tree.
            RunInvokerVertex child = parent;
            foreach(OrderedMethod om in methods)
            {
                IRunInvoker invoker = InstanceInvoker(om.Method);
                child = tree.AddChild(child,invoker);
            } 
        }
    
        protected IRunInvoker InstanceInvoker(MethodInfo mi)
        {
            IRunInvoker invoker = new MethodRunInvoker(this,mi);
            return DecoratorPatternAttribute.DecoreInvoker(mi,invoker);
        }
    
        #region OrderedMethod
        private class OrderedMethod : IComparable
        {
            private MethodInfo method;
            private int order;
       
            public  OrderedMethod(MethodInfo method, int order)
            {
                this.method = method;
                this.order = order;
            }
    
    
            public MethodInfo Method
            {
                get
                {
                    return this.method;
                }
            }
            public int Order
            {
                get
                {
                    return this.order; 
                }
            }
            public int CompareTo(OrderedMethod obj)
            {
                return this.order.CompareTo(obj.order);
            }
       
            int IComparable.CompareTo(Object obj)
            {
                return this.CompareTo((OrderedMethod)obj);
            }
        }
        #endregion
    	}
  3. Create ProcessTestFixtureAttribute, a class that inherits from TestFixturePatternAttribute and defines the fixture execution pipe:
    public class ProcessTestFixtureAttribute : TestFixturePatternAttribute 
    {
        public override IRun GetRun()
        {
            SequenceRun runs = new SequenceRun();
       
            OptionalMethodRun setup = new OptionalMethodRun(typeof(SetUpAttribute),false);
            runs.Runs.Add( setup );
       
            ProcessMethodRun test = new ProcessMethodRun(typeof(TestSequenceAttribute));
            runs.Runs.Add(test);
       
            OptionalMethodRun tearDown = new OptionalMethodRun(typeof(TearDownAttribute),false);
            runs.Runs.Add(tearDown);
       
            return runs;      
        }
    }

Et voilà!

posted on Tuesday, April 27, 2004 7:39:00 PM UTC  #    Comments [2]
 Monday, April 26, 2004

It is very easy to compute the code coverage of the Unit tests using MbUnit and NCover.

  1. Install the latest version of NCover (from gotdotnet: http://www.gotdotnet.com/Community/Workspaces/Workspace.aspx?id=3122ee1a-46e7-48a5-857e-aad6739ef6b9 )
  2. Create a test assembly and compile it in debug mode. NCover needs the symbol files to work (.mdb)
  3. Launch NCover as follows:
    NCover.Console.exe /c "MbUnit.Cons.exe" "MyTestAssembly.dll" /a "TheAssemblyToComputeTheCoverageOn"

    where MyTestAssembly.dll is the unit test assembly, TheAssemblyToComputeTheCoverageOn is the name of the assembly to compute the code coverage on (without the .dll extension)

  4. That' it.
 

You can launch multiple test assembly by providing multiple assembly names. And you can monitor multiple assembly, by providing a ;-separated list of assemblies.

 

posted on Monday, April 26, 2004 9:03:00 AM UTC  #    Comments [6]

I will be presenting MbUnit at the end of May on a BENUG meeting. BENUG stands for Belgian User Group, http://www.benug.be .

posted on Monday, April 26, 2004 8:06:00 AM UTC  #    Comments [4]
 Thursday, April 22, 2004

NDoc is truly an amazing library.

You can easily define your own documentation renderer (Documenter) class by implementing the NDoc.Core.IDocumenter interface (inheriting from BaseDocumenter will help). Once this is done, put the assembly ( named NDoc.Documenter.YourRenderer.dll) into the directory where NDocGUI.exe is and it will be loaded by Reflection where the GUI opens.

Since NLiterate is one way of looking at documentation, it deserved it's own documenter. The task was surprinsgly easy... maybe this could be my 2cents for NDoc :)

posted on Friday, April 23, 2004 4:31:00 AM UTC  #    Comments [1]

I have published a new article on CodeProject about NLiterate ( http://www.codeproject.com/useritems/nliterate.asp )... don't forget to vote :)

 

posted on Thursday, April 22, 2004 11:56:00 PM UTC  #    Comments [0]
 Wednesday, April 21, 2004

Literate programming ( http://www.literateprogramming.com  ) is a way of describing algorithms and programs invented by the the mythical D. Knuth (famous CWEB application). The nice thing about CWEB is that both code and documentation live in the same document. To compile the code, the tool reassembles the code snippets and compiles it. Therefore, you can verify that all the examples in your documentation are compilable. Sadly, the (excellent) C# documentation does not support literate programming... well now it does.

NLiterate is a small application that parses the XML documentation file, reassembles code section and compiles them. This gives you an automated way of testing all your documentation examples. I'll be posting the source soon.

posted on Thursday, April 22, 2004 6:50:00 AM UTC  #    Comments [0]
 Tuesday, April 20, 2004
I have released an article on using XML scripts to pilot SQLpp. Unfortunately, SQLpp is written in C++ and uses template meta-programming which makes compilation time explode. Therefore, the XML script should make it more "user friendly". The full article is at http://www.codeproject.com/useritems/xmlsqlpp.asp
posted on Wednesday, April 21, 2004 1:21:00 AM UTC  #    Comments [0]

I have been wondering if IDataReader was suited for remoting. The answer is obviously no since it derives from IMarshalByRef and therefore, all calls to the interface create a round-trip to the server.

Check out this article for more details.

posted on Tuesday, April 20, 2004 10:47:00 PM UTC  #    Comments [1]
 Sunday, April 18, 2004
This little add-in makes Reflector spit out source code from an entire assembly. Scary and efficient.
posted on Monday, April 19, 2004 2:00:00 AM UTC  #    Comments [0]
This little add-in makes Reflector spit out source code from an entire assembly. Scary and efficient.
posted on Monday, April 19, 2004 2:00:00 AM UTC  #    Comments [1]
 Saturday, April 17, 2004

Consider the simple and tedious task of wrapping C++ classes into Managed C++ (MC++). The classic approach is to make a proxy around an instance of the C++ class allocated on the heap:

// the C++ class
class A {...};

// the MC++ wrapper
public __gc class MA
{
    A* a;
public:
    MA() { a = new A();}
    ~MA() { delete a;}
}

This works well for individual classes (although it is a tedious work) but it fails when it comes to map inherance. Let's add a second class to our example:

class A 
{
public:
    virtual void method();   
};

class B : public A
{
public:
    virtual void method();
}   

The proxies for A,B should map the inherance the original classes, therefore I would expect to have something like this:

public __gc class MB : MA
{
  ???
}
Now, the question is: where should I instanciate B, where should I store the pointer without making ugly casts all over-the-place. The answer is simple: Stop MC++ and wait C++/CLR announced in a near future. 
posted on Saturday, April 17, 2004 9:39:00 PM UTC  #    Comments [0]
 Friday, April 16, 2004

Working on a database application, the urge for testing of database has appeared. Unfortunaltely, there are no real framework that can tackle this problem (real means with specialized assertion and fixtures). Unit test framework like NUnit are too simplistic to provide such functionality.

A little hope: I have run into this nice article which gives an introduction about database testing. The author gives a good methodology to set up a test framework for database:

    1. Separate production database from test database
    2. The test fixture must empty the tables of the test db befure launching the runs 
    3. do small unit tests using the business objects.

 There is one big gotcha about this: usually database are run in an "heavy" multithreaded environment and, in testing, we would like to detect locks and so on. The Unit test approach is too gentle :). I'll come back on this problem later (with somes solutions hopefully).

posted on Saturday, April 17, 2004 3:22:00 AM UTC  #    Comments [2]

NDoc, the best and free documentation compiler for C# has lately released v1.3. This version adds a very interresting new feature: custom tags.Basically, you just need to provide the XSLT templates to NDoc and it use them to render you tags: simple, efficient and highly customizable.

In the NCollection project, we needed a way to easily document the complexity of methods (average and worst). A custom tag was the perfect solution for that: (hint: I'm using brackts intead of minus/greater)

/// [complexity worst="n" average="1" /]
public void Method()
{...}

Starting from the NDoc example, the XSLT stylesheet to render this tag is:

[xsl:template mode="remarks-section" match="complexity">
[H4 class=dtH4>Complexity[/H4]
    [UL]
        [LI]Average: O([xsl:value-of select="@average"][/xsl:value-of])
        [LI]Worst-case: O([xsl:value-of select="@worst"])[/LI]
    [/UL]
    [xsl:apply-templates select="*"/]
[/xsl:template]

Et voilà!

posted on Saturday, April 17, 2004 2:34:00 AM UTC  #    Comments [1]
 Thursday, April 15, 2004

I have upgraded my WikWikiWeb module for DotNetNuke 2.0 along with some new features:

  • RSS feads,
  • Email notifications,
  • Some bug improbements.

Download is available at www.dotnetwiki.org .

posted on Friday, April 16, 2004 6:45:00 AM UTC  #    Comments [1]

CodeSmith is a well-known freeware code generator that I highly recommend to any developper, no matter the language.

I will be using CodeSmith to create templates for strongly-typed AdjacencyGraph classes of QuickGraph.

posted on Friday, April 16, 2004 6:11:00 AM UTC  #    Comments [0]

Highly promising refactoring project featuring

  • code instrumentation,
  • type substitution,
  • method prologue/epilogue decoration,
  • etc...

More at http://rail.dei.uc.pt/

posted on Friday, April 16, 2004 5:59:00 AM UTC  #    Comments [1]
This is my first test entry.
posted on Thursday, April 15, 2004 11:27:00 PM UTC  #    Comments [0]