Thursday, June 17, 2004

I'm preparing a little Reflector Addin to be able to load and execute MbUnit fixtures inside Reflector. Since the fixture tree contains all the functionalities, it was just a matter of injecting it into Reflector.

Screenshot:

The source code is so short that I'm also publishing (note that I'm using the helper classes described here)

using System;
using System.Windows.Forms;
using Reflector.CodeModel;
using MbUnit.Forms;
namespace Reflector.Graph.Faulty
{ 
    // Reflector package
    public class MbUnitPackage : BasePackage
    {
        [ReflectorWindow("MbUnit")]
        [ReflectorCommandBar(CommandBarTarget.Assembly)]
        private MbUnitWindow MbUnit=new MbUnitWindow(); 
    }

    // Tree View
    public class MbUnitWindow : ReflectorTreeView
    {
        private ReflectorServices services =null;
        public MbUnitWindow()
        {
            this.Dock =DockStyle.Fill;
        }
        // needed to get reflector current element
        public ReflectorServices Services
        {
            get
            {
                return this.services;
            }
            set
            {
                if (this.services!=null)
                {
                    this.services.AssemblyBrowser.ActiveItemChanged-=new EventHandler(this.activeItem_Changed); 
                }
                this.services=value;
                if (this.services!=null)
                {
                    this.services.AssemblyBrowser.ActiveItemChanged+=new EventHandler(this.activeItem_Changed); 
                }
            }
        }
        private void activeItem_Changed(Object sender, EventArgs args)
        {
            this.RemoveAssemblies();
            IAssembly assembly = this.Services.ActiveAssembly;
            if (assembly!=null)
                this.Translate();
        }

        // populate tree with current assembly
        public void Translate()
        {
            IAssembly assembly =this.Services.ActiveAssembly;
            if (assembly==null)
                return;
            this.RemoveAssemblies();
            this.AddAssembly(assembly.Location);
            this.ThreadedPopulateTree();
        }
    }
}
posted on Friday, June 18, 2004 1:06:00 AM UTC  #    Comments [3]

MbUnit 2.1.5.1 Beta is ready for download.  See latest release page on this blog for the download links

Issues, feature requests, and other bugs: please do not post them on the blog. You have two options (please it's easier to track things)

We have a menu!

posted on Thursday, June 17, 2004 7:53:00 AM UTC  #    Comments [17]
 Wednesday, June 16, 2004

This is a preview of a new Addin in the next Reflector.Graph release: Type Tree Map.

A TreeMap is special 2D visualzation of a tree. Since, Reflector provides a tree (Assembly -> Module -> Namespace -> Type -> Members), I wondered if it was possible to visualize with a TreeMap. In .Net, there are 2 controls available that can render treemaps:

I decided to use the later for creating the addin.

Screenshot

Note (1): The nodes represent each part of the type tree from assembly to the class members. Each node is clickable and brings the tree focus to the clicked element.
Note (2): Look at the treemap, and image the nodes are you Namespace/TestFixture/TestCase hierachy. Failed test in red, successfull test in green. Just imagine, that would be the ultimate progress bar for MbUnit!
Note (3): Thanks to Jamie (NUnitAddin) for the idea sharing on this.

posted on Thursday, June 17, 2004 2:52:00 AM UTC  #    Comments [2]

Jamie Cansdale, NUnitAddIn man, pointed out to me that I was cited (very briefly) on .Net rocks.  Here's the summary

John and Barry talk with us about Test-Driven Development, Unit Testing, and other aspects of Extreme Programming that are being used today. We had given lip service to unit testing in past shows, but John and Barry were able to explain the benefits as well as the how-to of test-driven development

http://www.franklins.net/dotnetrocks/, number 67, at 1:27 or so. This deserves a couple beers for me.

posted on Thursday, June 17, 2004 2:36:00 AM UTC  #    Comments [7]
 Tuesday, June 15, 2004

This entry is a little tutorial on how to write your own Reflector Addin. For the past weeks, I have been playing a lot with those and Lutz Roeder was backing me up on MSN for quick questions, so it's my time to return him the favor and write a tutorial about it. So let's get started.A Reflector Addin is basically only a control that gets notified when the browser changes of active items. Of course, the tricky part is to "inject" your Addin into Reflector and to "clean" up when it is unloaded. Once, you're addin is injected, the control you provided takes care of the rest. I will not focus on writing controls here but rather on the procedure to load and unload packages.

Reflector API is rather big, so this tutorial is just the "immerged" part of the iceberg.

Quick Semantics

In Reflector, an Addin is called a Package (IPackage interface). Each package can add multiple Windows (IWindow), which are the control appearing on the right, can add CommandBar items (ICommandBarItem, ICommandBarButton) to the context menus, and attach listeners to the event trigerred when the AssemblyBrowser changes of ActiveItem (IAssemblyBrowser.ActiveItemChanged). The ActiveItem is the item selected in the reflection tree.

Building a simple package (hard way)

The IPackage interface is defined as follows:

public interface IPackage
{
   void Load(IServiceProvider serviceProvider);
   void Unload();
}

As may already know, the Reflector API is exposed through a set of interfaces. The actual implementations are obfuscated. The IServiceProvider instance is a "facade" against the implementations and can be used to retreive IAssemblyBrowser instance (and others). 

The Load method is where you will inject your Addin, while the Unload method is for cleaning. Implementing IPackage is rather boring and bug prone because you need to track all the window, menu item, etc.. that you inject to later remove them. Forgetting to remove a menu item is likely to happen often if you are in a rush. Moreover, using the serviceProvider is verbose in the sense that you access elements through a dictionary:

IAssemblyBrowser ab = (IAssemblyBrowser)serviceProvider.GetService(typeof(IAssemblyBrowser));

Let's implement a small package that displays a text box for assemblies. As mentionned above the steps are:

  • create your control and add it to the IWindowManager instance (retreive from serviceProvider),
  • add menu item and event handler,
  • set control to visible when menu is clicked,
  • add IAssemblyBrowser.ActiveItemChanged handler in your control
  • Don't forget to prepare cleaning up!

The control: this control display the name of the assembly, otherwise nothing.

public class AssemblyNameWindow : TextBox
{
    private IAssemblyBrowser assemblyBrowser=null;
    public AssemblyNameWindow()
    {
        this.Dock = DockStyle.Fill;
        this.Multiline=true; 
    }
    public IAssemblyBrowser AssemblyBrowser
    {
        get
        {
            return this.assemblyBrowser; 
        }
        set
        {
            if (this.assemblyBrowser!=null)
                this.assemblyBrowser.ActiveItemChanged -= new EventHandler(activeItemChanged);
            this.assemblyBrowser = value;
            if (this.assemblyBrowser!=null)
                this.assemblyBrowser.ActiveItemChanged += new EventHandler(activeItemChanged); 
        }
    }
    private void activeItemChanged(Object sender, EventArgs args)
    { 
        // testing if current item is an assembly
        IAssembly assembly = this.assemblyBrowser.ActiveItem as IAssembly;
        if (assembly!=null)
            this.Text=assembly.Name;
        else
            this.Text=null;
    }
}

And now the package, which creates a window, and some menu items:

public class AssemblyNamePackage : IPackage
{
    private IWindowManager windowManager=null;
    private ICommandBar assemblyMenu=null;
    private ICommandBarButton button=null;

    public void Load(IServiceProvider serviceProvider)
    {
        this.windowManager=(IWindowManager)serviceProvider.GetService(typeof(IWindowManager));
        IAssemblyBrowser assemblyBrowser = (IAssemblyBrowser)serviceProvider.GetService(typeof(IAssemblyBrowser ));

        // create window
        AssemblyNameWindow anw = new AssemblyNameWindow();
        anw.AssemblyBrowser=assemblyBrowser;
        // inject window into reflector
        this.windowManager.Windows.Add("AssemblyName",anw,"Assembly Name");

        // create menu item and attach handler
        ICommandBarManager cbm = (ICommandBarManager)serviceProvider.GetService(typeof(ICommandBarManager));
        // get assembly context menu
        this.assemblyMenu = cbm.CommandBars["Browser.Assembly"];
        // add button
        this.button = this.assemblyMenu.Items.AddButton("Assembly name",new EventHandler(button_Click));
    }

    public void Unload()
    {
        // remove window
        this.windowManager.Windows.Remove("AssemblyName");
        // remove button
        this.assemblyMenu.Items.Remove(this.button);
    }
    private void button_Click(Object sender, EventArgs args)
    {
        this.windowManager.Windows["AssemblyName"].Visible=true;
    }
}

That's it. You have built your first Reflector Addin:

Now this is a lot of code to get thigs up and moreover, it is quite errorprone, so let's us another easier method.

Building a simple package (easier way)

This solution uses a few classes that I have written in order to handle all the "load/unload" code. The new way is mainly based on custom attributes. [Update:]Firstly, you need to make your controls implement IServiceComponent where you can register to Reflector events:

public class AssemblyNameWindow : UserControl, IServiceComponent
{
    private ReflectorServices services = null;
    public ReflectorServices Services
    {
       get { return this.services;}
       set
       {
            if (this.services!=null)
            { ... (detach events)}
            this.services = value;
            if (this.services!=null)
            { ... (attach events)}
       }
    }
}

For example, the AssemblyPackage is rewritten as follows:

public class AssemblyPackage2 : BasePackage
{
    [ReflectorWindow(Caption="Assembly Name II")]
    [ReflectorCommandBar(CommandBarTarget.Assembly)]
    private AssemblyNameWindow assemblyName = new AssemblyNameWindow();
[Updated: no need to implement a property]
[Updated: no need to implement Load anymore]
}

This looks much nicer. BasePackage will self inspect and load all properties tag will ReflectorWindow attribute. For each one of those, it will add a menu entry to the corresponding menu using the information in ReflectorCommandBar attribute. A property can have multiple command bar targets and a package can have multiple windows. The example above gives as expected a new menu item:

Where's that package ?

The helper classes are not part of Reflector but you can get them from the MbUnit CVS (look in Samples/Reflector.Graph direcotry).

posted on Wednesday, June 16, 2004 12:12:00 AM UTC  #    Comments [6]
 Monday, June 14, 2004

This release was sick so I removed from the server...

There is a new release of MbUnit available for download at tigris. The main change in this release is the support for separate AppDomain (which was really painfull to get).

New Features:

 

posted on Monday, June 14, 2004 11:55:00 AM UTC  #    Comments [9]
 Sunday, June 13, 2004

In a previous post, I showed how you could use the IL graph to do static fault detection (at least for simple but recurrent faults). Since the code was using Reflector API, but it was more the job for FxCop rules. I started to port the code to FxCop.

As you can see on the screenshot below it is working, at least on my simple examples. In fact, it seems that FxCop decompiler is still a little buggy because it returns erroneous target offset for brtrue.s or brfalse.s IL instruction. Therefore, you will have to wait to play with this new toy :)

The figure below shows the FxCop rule applied to the test class showed in the previous post. As expected, ArgumentNotChecked fails, but the 2 others succeed the tests.

posted on Monday, June 14, 2004 4:09:00 AM UTC  #    Comments [0]
 Saturday, June 12, 2004

New features:

Warning: This release has been compiled agains .NET v1.1 (because System.Drawing is buggy in v1.0), therefore you must create a Reflector.exe.config file in the directory of Reflector and add the following:







About bug reports:

Please, DO NOT post bugs in the blog. It is much more easy for me to monitor bugs through the http://mbunit.tigris.org issue tracking system. :)

Download Now on www.dotnetwiki.org

posted on Sunday, June 13, 2004 2:55:00 AM UTC  #    Comments [16]

I've been reading lately about PreFast, a tool for detecting fault in applications based on static analyis. Sadly, PreFact is for C++, so I wondered: can we do the same in C# ?

The test fault:

So I started with simple fault: a method that uses nullable argument and that does not check for nullity -> the NullReferenceException fault (NRE). Here are three method that illustrate the problem:

public class MyClass
{
    public void ArgumentNotChecked(Object arg)
    {
        string s=arg.ToString(); // if arg is null, NRE
    }

    public void ArgumentChecked(Object arg)
    {
        if (arg==null)
            throw new ArgumentNullException("arg");
        string s=arg.ToString(); // ok, we know arg is not null
    }

    public void ArgumentGuarded(Object arg)
    {
        if (arg!=null)
        { 
            string s=arg.ToString(); // ok, we know arg is not null
        }
    }
}

Sketch of the solution

The solution (I found) to this problem can be understood as taking all the possible path in the IL graph, while keeping track of the current state of the argument: Null, NonNull or Uncertain. When starting, the argument is uncertain, it could be null or not. If a method instance of the argument is called 3 things can happen:

  1. the argument is Null: we have found a bug,
  2. the argument is Uncertain: we have a possible bug. If by design, you always check parameters, this is a bug,
  3. the argument is NonNull: that's ok :)

In terms of graph theory (and QuickGraph), we need to apply the EdgeDepthFirstSearch algorithm using a visitior (IEdgeColorizerVisitor) that the job  described above. More that words, let's explain this on schemas.

Checking the ArgumentNotChecked method

This methods is very simply. In IL, it looks like this:

ldarg.1
call Object.ToString()

The corresponding graph is the following (ColorCode: Orange=Uncertain, Red=Null, Green=NonNull)

The EdgeDepthFirstSearch has only one step: it explorezs the ldarg.1 -> ToString() edge. Since the ldarg.1 status when calling ToString is Uncertain, it should output a warning. So in Reflector I get:

Gotcha!

Checking the ArgumentChecked method

This method is already a bit more complicated since there is a branch. The IL is:

L_0000: ldarg.1 
L_0001: brtrue.s L_000e
L_0003: ldstr "arg"
L_0008: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string)
L_000d: throw 
L_000e: ldarg.1 
L_000f: callvirt instance string object::ToString()
L_0014: stloc.0 
L_0015: ret

and the IL graph looks like this:

The EdgeDepthFirstSearchAlgorithm starts by examining the ldargs.1 -> brtrue.s edge.

If we find a brtrue.s, we can easily check if it is applied to ldarg1. If yes, then we should update the argument state in the child edges. The "then" branch will be tagged Null, the "else" branch will be tagged NonNull  as depicted in the figure below: 

Now, when we encounter the ToString() call on the argument, it's state is set to NonNull, so that's ok. 

Now, in Reflector, the fault analysis on the method should not find any warnings:

It worked!

Conclusion

Fault analysis can be seen as a natural application of graph theory and QuickGraph is a good for doing this. Although Reflector is a great tool, I think fault detection needs to be implemented as FxCop rules.... so stay tuned for new adventures.

posted on Saturday, June 12, 2004 7:25:00 AM UTC  #    Comments [5]
 Friday, June 11, 2004

TypeGraph Addin:

This is the first preview of the next killer Reflector addin: Type Graph. The addin visualizes the type inherance thourgh a graph. If a namespace or a type is selected in the Reflector tree, the corresponding graph nodes are highlighted in green.

Why such an add-in ?

Besides outputing nice graphics, Type Graph has real software analysis potential (to my point of view). For example, it can be used to visualize Code Coverage: each day, your automated test automaton creates a big poster of the application, gray nodes are not covered, red have failed some tests and green are ok. You could even make a movie and play smart at the next TechEd :) And that's just the beginning...

Thanks to Jamie (NUnitAddin) suggested me the coverage application

Screenshot:

mscorlib graph with System.Reflection namespace highlighted

The algorithm are based on force directed layout which I found in Maxime Melchior final work (one of our student).

posted on Friday, June 11, 2004 11:44:00 AM UTC  #    Comments [14]

This is a new add-in related to the ILGraph addin for Reflector. Basically I use the IL graph to extract all the path to cover the entire graph (and get full coverage). Each path then generates an empty Unit Test Case (using Refly) that the user will have to write. Better than words, the schema below is straightforward:

The addin can generate Unit Test cases for methods, types, namespaces or even full assemblies! Since it is based on CodeDom, it supports output to any .NET language.

The output

posted on Friday, June 11, 2004 8:00:00 AM UTC  #    Comments [30]
 Wednesday, June 09, 2004

For those who want to play with a preliminary version of the PGF, here it goes:

Download PGF v1.0 (beta)

Update: the PGF is now part of TestFu.

posted on Thursday, June 10, 2004 4:37:00 AM UTC  #    Comments [6]

Yesterday, I started reading Using Production Grammar for Software Testing (UPGS) for Emin Sirer and N. Bershad (found on ModelBasedTesting site), the authors describes a method for generating test automaton based on "inversed" grammars. Following their ideas, I have designed a little framework, the Production Grammar Framework for .NET (PGF).

Introduction

In this blog, I will present a framework for defining and executing production grammars. The production grammars described in UPGS are very similar to classic "LALR" grammars, in terms of understanding and semantics. The difference is that production grammars reversed the work of grammar, since they are used to produce output instead of analyse input.

Production grammars can do anything, ranging form generating data, piloting your application and generating test case, ... Since we are looking at testing applications, here are a few application that we will be interrested on:

  • manipulate the Implementation Under Test (IUT),
  • generate test case that manipulate the IUT. In this case, the grammar is a code generator,
  • if you want to test IUT against input data, generate a wide range of possible inputs,
  • etc...

Oracle problem

"Production grammars are well-suited for test generation not only because they can create diverse test cases effectively, but also because they can provide guidance on how the test cases they generate ought to behave. It is often hard to determine the correct system behavior for automatically generated test cases -- a fundamental difficulty known as the oracle problem. In the worst case, automated test generation may require reverse engineering and manual examination to determine the expected behavior of the system on the given test input."  The authors propose two ways of dealing with the oracle problem:

  • comparing difference with another implementation,
  • generating verification code along with the test code.

Since the PGF is based .NET code, you can theoretically add any verification code and if available, compare with any other implementation. This will be illustrated in the example

What is a Production Grammar:

"A production grammar is a collection of non-terminal rules to terminal rules that resembles a regular parsing grammar, but is used “in reverse.” That is, instead of parsing a sequence of tokens into higher level constructs, a production grammar generates a stream of tokens from a set of non-terminals that specify the overall structure of the stream".

Let's see that on a simple example. Consider the following comma separated list of names:

John,Paul,Marc

An valid EBNF grammar to parse this stream would be ([A-Z] designs capital letters, [a-z] lower case letters, + one or more occurence, * zero or more occurence):

name := [A-Z] [a-z]+
names := name (',' name)*

In the case of production grammar, we want to create that list of name. In C#, a possible implementation of the production grammar would be as follows:

public class NamesGrammar
{
   public string Name()
   {
        int count = nextRandom(); // gets a random int
        return getUpper() + getLowerString(count); // getUpper return upper case, getLowerString returns lower cased string
   }
   public string Names()
   {
        int count = nextRandom();
        string names = Name();
        for(int i=0;i!=count;++i)
           names += ',' + Name();
        return names;
   }
}

The example will generate a list name when the Names method is called, we have production :). This is just a dummy example, it is 100% hard-coded and very difficult to maintain. 

Production Grammar Framework

Before starting to work on an example (guess which), let us define important notations/interfaces of the PGF:

  • a rule (IRule) is an object that produce something. A rule can be terminal, it does not have any sub-rules, or non-terminal. Example of non-terminal rule is the + operator, terminal rule would be writing a string to a stream.
  • a production (IProduction) represents a production process (you can think of it as batch). It is passed on between the rules and can be stored to transmit the context or finish production,
  • Each time a rule wants to produce, it asks the production for a production token (IProductionToken). If the request is succesfull, the production goes on; otherwise, the production finishes. Using this mechanism, you can easily design production that will stop on a finite number of rule production.
  • a grammar (IGrammar) encapsultates a start rule and is used to launch the production process,

Those 5 interfaces form the kernel of the PGF, the rest of the framework is built on top and around them to help the user implement grammars.

The working example: a Stack

In order to crystilase the ideas presented here, we will consider the problem of testing a Stack (as in Test Driven Developement in .NET). A simple unbounded stack can be formalized by the following interface:

public interface IStack
{
    void Push(Object);
    Object Pop();
    Object Peek(); // equivalent to Pop() in TDD
    bool IsEmpty {get;}
}

The grammar

Before writing down the grammar in C#, it is useful to formalize it in a "pseudo" EBNF-like notation. In this example, there are 3 terminals: Push, Pop, Peek (we omit IsEmpty for now):

push := stack.Push(...)
pop := stack.Pop()
peek := stack.Peek()

 Since Pop and Peek can throw if the stack is empty, we create a special non-terminal rule  that guards production agains a specific exception type. This gives us the 2 following non-terminal rules:

gardedPop := gard( pop, InvalidOperationException )
gardedPeek := gard( peek, InvalidOperationException )

Of course, we need to be able to decided wheter we want to execute the guarded rule or the non guarded. Again, we define a new non-terminal rule that works as a "if-then-else". This gives us 1 more non-terminal rule:

nonEmpty := push | pop | peek
empty := push | gardedPop | guardedPeek
stackRule := if(isEmpty) { empty } else { nonEmpty }

The final step is to decide how many execution we want. Since we can break the production at the IProduction level, we go for infinite:

stackGrammar := stackRule*

The full grammar can be summarized as

push := stack.Push(...)
pop := stack.Pop()
peek := stack.Peek()
gardedPop := gard( pop, InvalidOperationException )
gardedPeek := gard( peek, InvalidOperationException )
nonEmpty := push | pop | peek
empty := push | gardedPop | guardedPeek
stackRule := if(isEmpty) { empty } else { nonEmpty }
stackGrammar := stackRule*

At this point, we have define a grammar for piloting the stack written in a "pseudo"-EBNF language. The simplicity of the notation let us concentrate on the problem and not on the tool to solve it. However, as it is, the grammar is pretty much useless, since it is missing verification code. We will see that the verification code can be easily added while writing the grammar in C#.

Rewriting the grammar in C# with PGF

The PGF contains a bunch of built-in non-terminal rules and helpers that will help you translate a grammar into functional C# code. In this example, we will encapsulate the grammar in a StackFixture class that contains a stack field:

public class StackFixture 
{
    private Stack stack = new Stack();
}

Step 1: Creating the terminal methods

Following the way we constructed the grammar, we begin by defining the terminals. The easiests solution is to define one method for each terminal and then wrap it into a IRule. For example, the push terminal is implemented as follows:

public class StackFixture 
{
    private Stack stack = new Stack();
    private IRule push;

    public void Push()
    {
        this.stack.Push(null);
    }

    public void CreateGrammar()
    {
        this.push = Rules.Method(new DefaultMethodDelegate(this.Push));
    }
}

We have added 3 things: a IRule field member to store the "push" terminal, a Push method that actually pushes something on the tested stack and a CreateRules method that will be used to creates the grammar. The Rules.Method is a static helper class that encapsulate the call to a member method into a rule. The same operation can be repeated for pop and peek.

Step 2: Adding code for the Oracle problem

In order to be able to verify assertion on the fixture, we need to solve the Oracle problem. For this specifiy case, we can do the Comparaison testing approach where we execute the operations on another implementation and verify that outputs are different (NC, not NSC). 

public class StackFixture 
{
    private ArrayList list = new ArrayList();
    private Stack stack = new Stack();
    private IRule push;

    public void Push()
    {
        this.stack.Push(null);
        this.list.Add(null);
        Assert.AreEqual(list.Count==0, stack.IsEmpty);
        Assert.AreEqual(list[list.Count-1], stack.Peek());
    }
    ...
}

Step 3: Creating the non-terminal rules

From this step, the PGF provides the "classic" non-terminal rules and helper classes to create them (Rules) that makes the rest of the implementation straightforward:

public class StackFixture
{
    ...
    IRule push, pop, peek;
    IRule guardedPop, guardedPeek;
    IRule empty, nonEmpty;
    IRule stackRule;
    IRule stackGrammar;
    ...

    // returns true if stack is empty
    public bool IsEmpty()
    {
         return this.stack.IsEmpty;
    }

    public void CreateGrammar()
    {
        push = Rules.Method(new DefaultMethodDelegate(Push));
        pop = Rules.Method(new DefaultMethodDelegate(Pop));
        peek = Rules.Method(new DefaultMethodDelegate(Peek));

        guardedPop = Rules.Guard( pop, typeof(InvalidOperationException) ); // gard( pop, InvalidOperationException)
        guardedPeek = Rules.Guard( peek, typeof(InvalidOperationException) );// gard( pop, InvalidOperationException)

        nonEmpty = Rules.Alt( push, pop, peek); // push | pop | peek
        empty = Rules.Alt( push, guardedPop, guardedPeek);
 
        stackRule = Rules.If(new ConditionDelegate(IsEmpty), empty, nonEmpty); // if(IsEmtpy) empty else nonEmpty

        stackGrammar = Rules.Kleene(stackRule); // stackRule*
    }
}

Step 4: Creating a grammar and executing a production

In order to simplify our lives, we make StackFixture inherit from the Grammar class (which implement IGrammar) provided by the PGF. This class takes care of setting up the production factory and launching productions. Of course, this part of the framework can be easily customized and extended to plugin into your existing test automaton (MbUnit, NUnit, csUnit, ...).

public class StackFixture : Grammar
{
    public StackFixture()
    { 
        this.CreateRules();
    }
    public void CreateRules()
    {
        ...
        // required for Grammar
        this.StartRule = this.stackGrammar;
    }
}

A production can then be executed by launching the Produce method:

StackFixture fixture =new StackFixture();
fixture.Produce();

Conlusion

Production Grammar Framework is an effective tool to create and implement production grammar. Production grammar are used to model the complex behavior of application and automate the creation of complex test case. In fact, you could easily reuse your existing Unit Test cases with a production grammar! Of course, PGF will be part of MbUnit in the next release. Moreover, since the "hard" work is done by the machine, you can expect to get much better code coverage using Production Grammar (or MBT) than with classical unit tesing.

Future directions and the quizz

This post is already long so I will stop here. However, you can start to think about other interresting use of this technique:

  • database testing,
  • data generation for user input testing,
  • unit test case generation using CodeDom,
  • etc...

The quizz question: How does this relates to model based testing ?

posted on Thursday, June 10, 2004 1:54:00 AM UTC  #    Comments [15]
 Monday, June 07, 2004

With the growing need for a decent .NET wrapper of LAPACK and since there exists no free wrapper around it (commercial version here), I have decided to take a try at this adventure (working with managed C++ is always an adventure). To help me in the task, Lapack++ a C++ wrapper around LAPACK: simple and very well done, should speed up things... (to be continued)

posted on Monday, June 07, 2004 12:42:00 PM UTC  #    Comments [7]
 Sunday, June 06, 2004

Reflector.Graph is a Reflector 4.0.5.0 Add-in. (it is my new toy project). Actually, it contains 3 graph-based package for Reflector (more will come )

Don't forget to drop a line to tell me about the tool.

Go to Reflector.Graph v1.1

Hint: Click and move to zoom in/out of the graphs
Hint2: Make sure you download Reflector 4.0.5.0
Hint3: Load Reflector.Graph.dll assembly in the Addin dialog.

posted on Monday, June 07, 2004 12:08:00 AM UTC  #    Comments [21]

After a number of requests, QuickGraph assemblies have been merged. Here is the new layout:

 

posted on Sunday, June 06, 2004 11:27:00 PM UTC  #    Comments [5]
 Saturday, June 05, 2004

This is a new experimental Reflector Add-In that will be part of the upcoming Reflector.Graph addin (see Assembly Grapher and Il Grapher). The objective of this addin is to rank methods using a method similar to google.

The graph

Consider a graph where the vertices are the methods of the classes, and each edge represents the fact that the source method calls the target method. For example, take the following dummy class:

public class Test
{
   public void Hello()
   {...}
   public void HelloWorld()
   {
       this.Hello();
   }
}

The method graph from this class will contain

  • 2 vertices: Test.Hello and Test.HelloWorld
  • 1 edge: Test.HelloWorld -> Test.Hello.

PageRank, The Algorithm

PageRank, which is the algorithm that Google uses to rank pages, is a well known and easy to implement algorithm (it is implemented in QuickGraph). The idea behing is very simple and elegant: important pages are reference by other important pages. So basically, PageRank algorithms can help you order the vertices of your graph by order of importance.

PageRank and MethodRank

Contrary to Google, where the vertices are pages and edges are the hyperlinks, the vertices are methods. However, the PageRank idea translates naturally to the method graph: important methods are called by other important methods. Why would we need to know which are the important vertices ? Here are my intuition (not tested) about this:

  • if a important method contains a bug, it is likely that a lot of test cases will fail, (this a BIG assumption)
  • using the previous point, it is clear that important methods are a good target for mutation testing,
  • if you have to start testing, it can give you a "test writting" order,
  • it's fun

The AddIn

for the pleasure of the eyes

posted on Saturday, June 05, 2004 10:55:00 AM UTC  #    Comments [10]
 Friday, June 04, 2004

This post is just a small remainder of the meta-physical questions I'm asking myself, specially because testing is basically trying to solve an unsolvable problem (Halting theorem)

  1. What is a bug ? (I like this one)
  2. Are there family of bugs ? (see Mutation Testing) Can we detect them statically (i.e. using Metadata only)
  3. Is there a way to get an a-priori estimation on the location of the bugs ?
  4. Can we apply Risk Managment technology to source code ? Automatically ?
  5. How can you effectively test a database ? By effectively I mean: not restricted to transactions, not database reconstruction for each test,
  6. How can you effectively test a GUI ? By effectively I mean, without having to actually record and program user interfaction,
  7. Should you test the code that does the testing ? If yes, should you test the code that tests code that does the testing... and so on,
  8. You are facing an untested application, you don't have the time to test all the code. Where should you start ?

 

posted on Saturday, June 05, 2004 4:24:00 AM UTC  #    Comments [2]

I have attended yesterday to a presentation about SharePoint by Patrick Tissegem and Inge De Neef (?could not find her blog?). Inge, sorry for the question :). Patrick was presenting through a VPN and doing live stuff on this SharePoint site (Inge also did live manipuation). It did not crash, amazing. This was my first contact with SharePoint and it looked like a terrific product for creating intranet, but it also appeared to me that it could quickly become a mess if you start tweaking it!

I also met a lot of fellow belgian bloggers. Since I'm not good with names, I must have forgotten many but here are the people I saw and spoke to: Jan Tiellens, Tom Mertens (MSDN content manager I think), Thomas Delrue (who will be doing an internship at Microsft as SDE/T this summer), and I forgot the other... Make yourself heard :)

There was also a surprise from the MSDN team before the presentation where Tom said:

"We have two .Net gurus in the room[...] I would like you to give a warm applause to Jonathan de Halleux and Thomas Delrue[...]".

I must say I was not easy with that, but he then said:

"Microsoft has a gift for both of them[...] bottles of champagne[...]"

Then I was much more relax :) :) :)

posted on Saturday, June 05, 2004 4:05:00 AM UTC  #    Comments [0]

That's another graph-based Reflector Add-In. It creates and displays the dependency graph between the assemblies that are loaded in Reflector.

ps: Thanks to Lutz who wrote the AssemblyGrapher application to make it a Reflector add-in.

posted on Friday, June 04, 2004 9:28:00 PM UTC  #    Comments [15]
 Wednesday, June 02, 2004

I have received an interresting post from Kent Boogaart on the CodeProject article that pointed out a major limitation of Composite Unit Testing:

I'm a little unsure how this tests all an interface's members. Take ICollection, for example. Your CollectionTest implementation would receive an instance of ICollection manufactured via an appropriate factory.

Say you wanted to test that ICollection.Count was returning the correct value. How would you test this without knowledge of the factory method called?

Thanks,
Kent

There he has a point. You cannot test ICollection.Count using Composite Unit Testing as it is now. You could test it through the IList test interface, but that's not the point.

A way of overcoming the limitation would be the ability for the user to give a "gold" instance along with the test instance. The gold instance would be mock of the interface as it "should" be and could be used to do the ICollection.Count test. For each factory method, the framework would look for it's mock counter part, if found, it is feeded to the test method. Let's illustrate that on ICollection:

The gold instance class (mock):

// the mock
public class CollectionMock : ICollection
{
    private int count=0;
    ...
    public int Count
    { 
        get{ return count;}
        set{this.count=value;}
    }
    ...
}
The tested instance factory
public class ArrayListFactory
{
    // provider for empty arraylist
    [Factory] // new attribute, tells the framework it is a factory method
    public ArrayList Empty
    {
        get
        {
            return new ArrayList();
        }
    }
    [MockFactory] // tells the framework it is a mock method
    public MockCollection EmptyMock // name is important must be "Method"+Mock
    {
        get
        {
            MockCollection col = new MockCollection();
            return col;
        }
    }
    // 1 provider + mock
    [Factory]
    public ArrayList One
    {
        get
        {
            return Empty.Add(null);
        }
    }
    [MockFactory]
    public MockCollection OneMock // name is important must be "Method"+Mock
    {
        get
        {
            MockCollection col = new MockCollection(); 
            col.Count=1;
            return col;
        }
    }
}
The test fixture:
[TypeFixtue(typeof(ICollection)]
[ProviderFactory(typeof(ArrayListFactory),typeof(ICollection))] public class CollectionTest { [Test] public void CountTest(ICollection tested, ICollection mock) { Assert.AreEqual(mock.Count,tested.Count,"ICollection.Count"); } }
The framework would detect if a mock is available and automatically feed it to the method. Any comments ?
posted on Wednesday, June 02, 2004 10:57:00 PM UTC  #    Comments [4]

I have been facing a silly bug related to AppDomain, so stupid that it is worth mentionned in a blog.

The symptoms

Load an assembly in a separate AppDomain, create an instance of a type. Things work correctly. Then unload the domain, and recreate the type. Somehow, strange bugs (Custom Attributes not detected, the debugger messed up) arise.

How-to recreate it:

Assume that we have the Assembly MbUnit.Core.dll, MbUnit.Framework.dll (that references Core) and Test.dll that references both. Core defines an abstract Custom Attribute TestPatternFixtureAttribute,

public abstract TestFixturePatternAttribute :Attribute{...}
that is inherited in Framework as TestFixtureAttribute
public class TestFixtureAttribute : TestFixturePatternAttribute{...}
and TestFixtureAttribute is used in Test to tag fixture classes
[TestFixture]
public class MyTest{...}
At last, Core contains RemoteTestTree a serializable class that takes care of loading assemblies, extracting fixtures (class taged with TestPatternFixtureAttribute) and launching tests.

  1. Create a separate AppDomain using AppDomain.CreateDomain,
  2. Create an instance of RemoteTestTree using AppDomain.CreateInstanceFromAndUnWrap
  3. Load Test.dll in the domain and find fixtures. At this point, everything works and we found the fixtures.
  4. Unload the separate AppDomain using AppDomain.UnLoad,
  5. Re-Create an instance of RemoteTestTree (at this point, weird things happen because the debugger seems to tell: RemoteTestTree is not initialized)
  6. Load Test.dll in the domain and find fixtures. This time, no fixture is found because the framework seems to tell that TestFixtureAttribute does not inherit from TestPatternAttribute.

The fix

In point 2,5, I have been using AppDomain.CreateInstanceFromAndUnWrap, this is the error. I should have been using AppDomain.CreateInstanceAndUnWrap. The difference is subtle, 4 letters.

The explanation

I'm still unsure of the explanation.... so I'm waiting for someone to come up with a relevant explanation :)

posted on Wednesday, June 02, 2004 8:37:00 PM UTC  #    Comments [9]
 Monday, May 31, 2004

With the kind help of Lutz Roeder, I have recompiled the IL Grapher into a Reflector Add-in...

posted on Tuesday, June 01, 2004 1:37:00 AM UTC  #    Comments [15]
 Sunday, May 30, 2004

In a near future, MbUnit will support storing of the test results in a SQL database (SQL server supported). The database structure is done and the BLL/DAL is finished. Here's a snapshot of the database schema.

 

posted on Sunday, May 30, 2004 3:21:00 PM UTC  #    Comments [1]

I have added the possibility to sort fixture by importance (or severity): Critical, Severe, Default, NoOneReallyCaresAbout.

[TestFixture]
[Importance(TestImportance.Critical)]
public SomeFixture
{...}

posted on Sunday, May 30, 2004 12:45:00 PM UTC  #    Comments [2]

A number of new assertions classes have been added to MbUnit since the latest post on this topic.  The new helper classes involve Arrays, collection, compiler, serialization, web...

ArrayAssert

This helper class contains method to compare arrays:

byte[] expected = ...;
byte[] actual = ...;
ArrayAssert.AreEqual(expected,actual);

The method compares the rank, the length and makes element-wize comparaison.

ColAssert

This class provides several methods to compare two ICollection instance:

ICollection expected = ...;
ICollection actual = ...;

ColAssert.IsSynchronized(actual);
ColAssert.AreCountEqual(expected,actual);
ColAssert.AreEqual(expected,actual);

The class also provides method to test the collection count, syncroot, synchronization, etc...

SerialAssert

This class contains various methods to test the "serializability" of objects.

SerialAssert.IsXmlSerializable(typeof(MyClass));

WebAssert

This class contains assertions on the properties of web control and web pages.

CompilerAssert

This class contains assertions to check that snippets are compilable:

String source = ...; // C# code to compile
// verify that source compiles
CompilerAssert.Compiles(CompilerAssert.CSharpCompiler, source);

What about your assertions ?

There is also a CodeSmith template that can let you build "strongly-typed" assertion classes out of existing types. See in the templates directory.

posted on Sunday, May 30, 2004 11:48:00 AM UTC  #    Comments [8]
 Friday, May 28, 2004

I just came back from Microsoft, Redmond where I attented interviews for SDE/T in the CLR team. (Interviews at Microsoft is a unique experience on its own). It looks like it worked because I'm moving in October to Redmond. :) I would like to thank Michael Corning, Harry Robinson and Holly Barbacovi for their support on this adventure.

Me and Michael Corning at Building 44 in Redmond.

Don't be fooled by the bad quality of the photo, it was pooring rain (the famous Redmond weather).

 

posted on Friday, May 28, 2004 3:25:00 PM UTC  #    Comments [9]
 Saturday, May 22, 2004

I've been recently interrested into Mutation Testing, a funny way of measure the quality of tests. This blog presents the first snapshot of a toy application that mutates any .Net program.

Mutation testing is the action of inserting "articifial" faults into the Instance Under Test and look if the tests catch this fault. The idea is that the tests are adequate if they detect all the faults. For example, a typical mutation is to negate the condition expression in a if statement:

//original
if (condition)
   DoSomething();
// mutated
if (!condition)
   DoSomething();

Jester implements Mutation testing for JUnit (there is a nice article here about Jester). In his Thesis (that Lutz Roeder kindly pointed out to me), A Multation Testing Tool for Java Programs, Matthias Bybro defines an entire framework for generating and executing mutants. In this blog, I will not focus on the theory of mutation testing but I'll show how you can get it implemented in .NET

The tools we need

As usual, before attacking the problem we can review what functionalities we need and what we have on our tool set. In this case, we need the ability to load an assembly, explore and alter the IL, and execute or write the mutated assembly. Got any idea....

RAIL! Runtime Assembly Instrumentation Library, that's exactly what we need. With RAIL, you can load an assembly, explore and alter the IL and execute or write the mutated assembly. You can even substitute types or entire functions. In fact, the powerpoint presentation of RAIL, the author shows how to play with IL.

Let's code

The AssemblyScrambler application is designed as follows: a ScramblerEngine instance contains a collection of IScrambler instances. An IScrambler instance contains a method to scramble IL code (I started this application before knowing about mutation testing. So Scrambler should be named mutators, etc...):

public interface IScrambler
{
    void Scramble(ScrambleTrace trace,RMethodDef method);
}

where trace is used to log mutations, and method is an instance of Rail.Reflect.RMethodDef which represents a method. The scramblers are used as follows in ScramblerEngine:

public void Scramble(string fileName)
{
    this.assembly = RAssemblyDef.LoadAssembly(fileName);
    foreach(RTypeDef t in this.assembly.RModuleDef.GetTypes())
    {
        foreach(RMethodDef method in t.GetMethods())
        {
            foreach(IScrambler scrambler in this.Scramblers)
            {
                scrambler.Scramble(trace,method);
            }
        }
    }
}

We are now ready to start implementing scramblers. There is currently only one implemented that swithes brtrue -> brfalse and brfalse -> brtrue. RMethodDef contains a MethodBody that contains a Code instance. Code is a mutable collection of instructions:

for(int i = 0;i<method.MethodBody.Code.InstructionCount;++i)
{
    Instruction il = method.MethodBody.Code[i];
    // selecting instruction
    if (il.OpCode.OperandType != OperandType.InlineBrTarget 
    && il.OpCode.OperandType != OperandType.ShortInlineBrTarget)
        continue;
    // il is ILBranch
    ILBranch branch = (ILBranch)il;
    // check if is brfalse
    if (il.OpCode.Name == OpCodes.Brfalse.Name)
    {
        // subtitute with brtrue
        method.MethodBody.Code[i]=new ILBranch(OpCodes.Brtrue,branch.Target);
    }
    else ...

Switching brtrue and brfalse is as simple as that. Note that here, 99% percent of the work is done by the excellent RAIL library.

Small example

Let's apply the scrambler to a small method:

public void IsTrue(bool isTrue)
{
    Console.Write("Expected: {0}, ",isTrue);
    if (isTrue)
        Console.WriteLine("Actual: true");
    else
        Console.WriteLine("Actual: false");
}

The IL code for this method is the following (using Reflector):

.method public hidebysig instance void IsTrue(bool isTrue) cil managed
{
// Code Size: 42 byte(s)
.maxstack 2
L_0000: ldstr "Expected: {0}, "
L_0005: ldarg.1 
L_0006: box bool
L_000b: call void [mscorlib]System.Console::Write(string, object)
L_0010: ldarg.1 
L_0011: brfalse.s L_001f
L_0013: ldstr "Actual: true"
L_0018: call void [mscorlib]System.Console::WriteLine(string)
L_001d: br.s L_0029
L_001f: ldstr "Actual: false"
L_0024: call void [mscorlib]System.Console::WriteLine(string)
L_0029: ret 
}

You can see that instruction at index 0011 is what we target. We have a small console application that calls this method. The code and results are:

Sandbox sandbox = new Sandbox();
sandbox.IsTrue(true);
sandbox.IsTrue(false);
-- output
Expected: True, Actual: true
Expected: False, Actual: false

After mutation

The above method is passed into the AssemblyScrambler machine, the IL code of the mutated application now looks like this:

.method public hidebysig instance void IsTrue(bool isTrue) cil managed
{
// Code Size: 42 byte(s)
.maxstack 3
L_0000: ldstr "Expected: {0}, "
L_0005: ldarg.1 
L_0006: box bool
L_000b: call void [mscorlib]System.Console::Write(string, object)
L_0010: ldarg.1 
L_0011: brtrue.s L_001f
L_0013: ldstr "Actual: true"
L_0018: call void [mscorlib]System.Console::WriteLine(string)
L_001d: br.s L_0029
L_001f: ldstr "Actual: false"
L_0024: call void [mscorlib]System.Console::WriteLine(string)
L_0029: ret 
}

Take a look now at L_0011, it is now brtrue.s.... the method is mutated. In fact, the output of the snippet gives:

Expected: True, Actual: false
Expected: False, Actual: true

You can download the source at http://www.dotnetwiki.org/DesktopDefault.aspx?tabid=121. Don't forget that you need the RAIL assemblies.
posted on Sunday, May 23, 2004 2:25:00 AM UTC  #    Comments [5]
 Friday, May 21, 2004

In the post Fun with Graphs (3): Creating the graph of a database structure, I have presented a small application that creates the graph of a database. We are now going to improve the output by adding the different fields, primary keys, etc.. in the graph.

GraphvizRecordCell

Graphviz supports a type of vertex shape that is drawed as nested tables. This shape is called Record. NGraphviz comes with a class wrapper (GraphvizRecordCell) that lets you easily create such records. Some remarks on cells:

  • A GraphvizRecordCell can also contain other nested cells,
  • By default, Graphviz starts to arrange the cells horizontally and swith direction (vertical/horizontal) at each level 

Let's take the formatVertex event handler and adapt it to create records:

private void formatVertex(Object sender, FormatVertexEventArgs e)
{
    TableSchemaVertex v = (TableSchemaVertex)e.Vertex;
    GraphvizRecord record = new GraphvizRecord();
    e.VertexFormatter.Shape = GraphvizVertexShape.Record;
    e.VertexFormatter.Record = record;
    GraphvizRecordCell table = new GraphvizRecordCell();
    record.Cells.Add(table);

    GraphvizRecordCell name = new GraphvizRecordCell();
    name.Text = v.Table.Name;
    table.Cells.Add(name);
    ...

Here's a sample result on the MbUnit database:

posted on Saturday, May 22, 2004 2:56:00 AM UTC  #    Comments [1]

Over the last few days, I have started to prepare MbUnit to support loading of test assemblies into separate domain. This feature is very important for a number of reasons:

  • test assemblies are shadow copied,
  • test assemblies can be unloaded. This means that MbUnit can detect when you have recompile the test assembly and reload it.The assembly unloading feature is very important if you plan to do Test Driven Development (test, code, test, code...).
  • it is easier to control the AssemblyResolve event,

Of course, executing the tests in separate AppDomain has a big drawback: test results and notifications is transmitted by Remoting, and this cost cpu cycles. Currently there is a big performance hit (twice slower) for using separate AppDomain. A possible explanation is that there too much event notification that need to cross Remoting channel.

To be continued...

posted on Friday, May 21, 2004 9:02:00 PM UTC  #    Comments [4]
 Thursday, May 20, 2004

Sorting the fixture using the namespace/type is nice... but like always, there situations when you would like to sort fixture using other criteras. For example, you might want to sort the test by authors, categories, importance, etc...

While preparing for AddDomain remoting, I have totally refactored the way MbUnit populates the tree to make it totally extensible: now you can populate the anyway you like!

FixtureCategoryAttribute

This is a new attribute that can tag fixture to sort them by categories. You can describe a nested category by separting the names by dots (like a namespace) and you can tag a fixture with multiple categories (a single fixture can be part of multiple categories). For example:

[CompositeFixture(typeof(EnumerableTest))]
[ProviderFactory(typeof(ArrayListFactory),typeof(IEnumerable))]
[ProviderFactory(typeof(HashtableFactory),typeof(IEnumerable))]
[Pelikhan] -> author
[FixtureCategory("Important.Tests.Should.Be.Here")] -> categories
[FixtureCategory("A.Test.Can.Be.In.Multiple.Categories")]
[FixtureCategory("A.Test.Can.Be.In.Multiple.Categories2")]
public class CompositeTest
{
}

Screenshot

Here's a snapshot of the latest MbUnit snapshot: as you can see the tests are sorted by namespace, authors and categories.

posted on Friday, May 21, 2004 12:34:00 AM UTC  #    Comments [3]
 Wednesday, May 19, 2004

This article will try to give an rough overview of the MbUnit vision of tests, and consequently it's architecture. It's contains some material of a previous CodeProject article.

Why MbUnit ?

Unit testing is a great tool for ensuring an application quality and frameworks like NUnit or csUnit have made it very simple to implement. However, as the number of tests begins to grow, the need for more functionalities begin to show up. The above frameworks are based on the Simple Test Pattern which is basically the sequence of SetUp, Test, TearDown actions. Although highly generic, this solution lets a lot of work to be done by the test writer. Sadely, there is no easy way to derive and include a new "fixture" type in those frameworks.

MbUnit is simply born from the fact that I wanted a new fixture and integrating it into existing frameworks was nearly impossible (I was also resting from a knee surgery at hospital with nothing else to do than coding).

Illustrating example

In order to make things clear, I will refer to an example while explaining how MbUnit works. Let me consider the Simple Test Pattern which is implemented by most test unit framework available. This is the classic way of writing unit test as described in the figure below. A TestFixture attribute tags the test class, one SetUp method, tests are done in the Test tagged method and clean up is performed in TearDown tagged method. This is illustrated in the left of the figure.

Attribute -> Run -> Invoker

The kernel of MbUnit is  composed of different components that work in a serial way. The first component is the fixture attribute

The fixture attribute is used to tag the classes that contain unit tests (TestFixtureAttribute is a fixture attribute). The new thing in MbUnit is that each fixture attribute contains the execution logic of the fixture which is returned at run-time under the form of a Run (IRun interface). In the case of the example, the TestFixtureAttribute is defined as a sequence of SetUp, Test and TearDown:

public class TestFixtureAttribute : TestFixturePatternAttribute 
{
     public override IRun GetRun()
     {
          SequenceRun runs = new SequenceRun();
            
          // setup
          OptionalMethodRun setup = new
                              OptionalMethodRun(typeof(SetUpAttribute),false);
          runs.Runs.Add( setup );
            
          //tests
          MethodRun test =new MethodRun(typeof(TestPatternAttribute),true,true);
          runs.Runs.Add(test);
            
          // tear down
          OptionalMethodRun tearDown = new
                           OptionalMethodRun(typeof(TearDownAttribute),false);
          runs.Runs.Add(tearDown);
            
          return runs;                        
     }
}

where

  • TestFixturePatternAttribute is the abstract base class for all new fixture attribute in MbUnit,
  • the GetRun method is called by the MbUnit core to know what is the execution path of the fixture. The fixture can use built-in basic attributes to build it's execution path.
  • An IRun instance can represent the call to a method, or to a sequence of methods, etc...
  • SequenceRun is a sequence of IRun's,
  • MethodRun is a IRun instance that wraps a call to a method tagged by a predefined attribute.
  • OptionalMethodRun is inherited from MethodRun and describes optional methods.

The IRun object will create an execution tree  by exploring the tagged type. Each node of the tree contains a RunInvoker (IRunInvoker interface). The RunInvoker is in charge for calling the method, garding the execptions, loading data, etc... On our sample fixture, there are two tests that the Run will extract:

When the tree is built, we just extract all the possible path from the root node to the leaves to extract the different possible tests. Each of these path is called a Pipe (RunPipe class).

In the GUI, the RunPipe instances are attached to the TreeNode nodes so you can easily select and execute separately the tests. This ensures that the test execution are isolated.

This architecture brings a lot of flexibility (and complexity) on the kind of fixtures that can be defined. Any user can define it's own fixture and use MbUnit to execute it.

posted on Thursday, May 20, 2004 1:22:00 AM UTC  #    Comments [4]

As most of you should know by now, PageRank is the ranking system used by Google to estimate the importance of a page (you can see it in the Google toolbar). Of course, since the basic idea of the algorithm was published they may have been some significant modifications. In this blog, I'll how we can use QuickGraph to compute the PageRank of a graph...

PageRank

The idea behind PageRank is simple and intuitive: pages that are important are referenced by other important pages, page importance is distributed to out-edges. There is an important literature on the web that explains PageRank:

The PageRank is computed by using the following iterative formula:

PR(A) = (1-d) + d (PR(T1)/C(T1) + ... + PR(Tn)/C(Tn)) 

where PR is the PageRank, d is a damping factor usually set to 0.85, C(v) is the number of out edges of v.

PageRank can also be expressed in terms of matrix algebra where it is shown that it is equivalent to finding the eigen values of a sparse matrix (see http://citeseer.ist.psu.edu/kamvar03extrapolation.html). And in fact, the above formula is equivalent to the Power Method (a slow method for finding eigen values).

Where's my LAPACK ?

Until C# (and .Net) has a real and free wrapper around LAPACK, we cannot attack PageRank using matrix algebra. As mentionned above, the formula is equivalent to the Power Method, which is a slow (potentially very slow) method for computing eigen values (convergence rate is |la_1 / la_2| where la_1 is the largest eigen value, la_2 is the second largest eigen value). There are other faster methods (like model reduction) that we could use to speed up things if we had LAPACK (I'm throwing a bottle in the .Net sea here).

Implementation in QuickGraph

Since we have no matrix algebra, the implementation is very basic and unefficient (I'm almost ashamed). This is almost a disclaimer: do not use this algorithm for big graphs, it is potentially slow. The main loop looks like this:

// temporay rank dictionary
VertexDoubleDictionary tempRanks = new VertexDoubleDictionary();
// create filtered graph that removes dangling links
FilteredBidirectionalGraph fg = new FilteredBidirectionalGraph(
    this.VisitedGraph,
    Preds.KeepAllEdges(),
    new InDictionaryVertexPredicate(this.ranks)
    ); 

int iter = 0;
double error = 0;
do
{
    // compute page ranks
    error = 0;
    foreach(DictionaryEntry de in this.Ranks) 
    {
        IVertex v = (IVertex)de.Key;
        double rank = (double)de.Value;

        double r = 0;
        foreach(IEdge e in fg.InEdges(v))
        {
            r += this.ranks[e.Source] / fg.OutDegree(e.Source);
        }
        // add sourceRank and store
        double newRank = (1-this.damping) + this.damping * r;
        tempRanks[v] = newRank;
        // compute deviation
        error += Math.Abs(rank - newRank);
    } 
    // swap ranks
    VertexDoubleDictionary temp = ranks;
    ranks = tempRanks;
    tempRanks = temp; 
    iter++;
// iterate until convergence, or max iteration reached
}while( error > this.tolerance && iter < this.maxIterations);

where ranks is the PR method, damping is the d factor. Note that because we use enumerators, we cannot modify the ranks as we iterate the dictionary, otherwize the enumerator would be invalidated, therefore we use 2 dictionaries and swap between them as we go along.

The results

As usual, we use GraphvizAlgorithm to output the results. Here are some graph sample with each corresponding page rank:

posted on Wednesday, May 19, 2004 11:22:00 PM UTC