Monthly Archives: June 2008

Why Use Random Values For Unit Testing

On a previous post I introduced a library for generating random values for purposes of unit testing.

I received a few comments and questions on my blogs [^][^][^][^].

Simon says that he’d “generally want every instance of the test I run to be repeatable on *every* run” and he’d “inclined to use the data source functionality in VSTS Unit Tests”. I couldn’t agree more.

Hugo pointed me to Pex. Looks nice. I’ll have to take a deeper look at it.

Other commenters were worried that in the case of a test failing to pass they were unable to reproduce the conditions of the test and thus would be unable to understand why the test had failed. As I see it, all data used in a failed test should be in the test output (at least, the data that made the test fail). Being it predictable data or random data.

I guess that most of the comments “against” my idea were due to the fact that I didn’t explain it well. I’ll try to do a better job now.

I use these random values when the value itself is not important, what’s important is its uniqueness.

Imagine you have  Costumer class where it’s enough to tell that the costumer is the same in any two given instances if the costumer ID is the same. In order to test the comparison code, I don’t need any particular reproducible set of values. I just need them to be different or the same depending on the test.

Imagine I have some code that needs to access the database with the connection string in a specific connection string settings element. I don’t care what the connection string is because I won’t be really accessing the database (this is really easy to accomplish with Isolator).

I hope I’ve explained myself better this time.

Replacing Loaded Assemblies

Recently I’ve been asked if it would be possible to replace the assemblies loaded by a .NET Windows Service application while it was running like with ASP.NET. Like with ASP.NET, an application start and end events where needed.

The solution is quite simple. The Windows Service application is just a loader that has no references to the loaded assemblies that might change have an assembly with an entry point that acts as the start event. This assembly must be loaded in a new AppDomain with ShadowCopyFiles set. The end event is handled by handling the DomainUnload event of the AppDomian where the running assembly is loaded.

If you want to have the running assembly and its referenced assemblies unloaded and reloaded whenever a change occurs in the assembly files, a FileSystemWatcher could be used, although I would prefer to override such behavior in ASP.NET, not copy it.

An assembly loader can be as simple as this:

class Program
{
    private static Thread thread = null;
    private static AppDomain appDomain = null;

    static void Main(string[] args)
    {
        while (true)
        {
            Console.WriteLine();
            Console.WriteLine("Options:");
            if (appDomain == null)
            {
                Console.WriteLine("    L - Load");
            }
            else
            {
                Console.WriteLine("    U - Unload");
            }
            Console.WriteLine("    X - Exit");

            switch (Console.ReadKey().KeyChar)
            {
                case 'l':
                case 'L':
                    thread = new Thread(Load);
                    thread.Name = "Runner";
                    thread.Start(args);
                    while (appDomain == null) ;
                    break;
                case 'u':
                case 'U':
                    Unload();
                    break;
                case 'x':
                case 'X':
                    Unload();
                    return;
            }
        }
    }

    private static void Load(object obj)
    {
        string[] args = obj as string[];

        AppDomainSetup appDomainSetup = new AppDomainSetup();
        appDomainSetup.ApplicationBase = args[0];
        appDomainSetup.PrivateBinPath = args[0];
        appDomainSetup.ShadowCopyFiles = "true";

        appDomain = AppDomain.CreateDomain("Runner", AppDomain.CurrentDomain.Evidence, appDomainSetup);

        appDomain.ExecuteAssemblyByName("ConsoleApplication", AppDomain.CurrentDomain.Evidence, new string[0]);
    }

    private static void Unload()
    {
        AppDomain.Unload(appDomain);
        appDomain = null;
        thread = null;
    }
}

The loader receives the path for the assembly to run and its name and loads it.

And the assembly to run as simple as this:

class Program
{
    static readonly DateTime dateTime = DateTime.Now;

    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.DomainUnload += delegate
        {
            Console.WriteLine();
            Console.WriteLine("Unloading: {0}", dateTime);
        };

        System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();

        Console.WriteLine("Loading: {0}", dateTime);
        Console.WriteLine("Assembly: {0}", assembly.FullName);
        Console.WriteLine("Location: {0}", assembly.Location);

        FileInfo fileInfo = new FileInfo(assembly.Location);
        Console.WriteLine("Location Dates: CreationTime={0}, LastWriteTime={1}, LastAccessTime={2}",
            fileInfo.CreationTime, fileInfo.LastWriteTime, fileInfo.LastAccessTime);

        while (true)
        {
            Console.Write('.');
            Thread.Sleep(100);
        }
    }
}

With this “system” you can replace the running assembly and load or unload it whenever you want to.

Using Random Values For Unit Testing

When writing my unit tests I don’t like to use hard coded fixed values because I either end up using the same values or, because of that, tests may succeed by coincidence.

Over time, I have developed an helper class to generate random values for testing.

namespace PauloMorgado.VisualStudio.TestTools.UnitTesting
{
    public static class RandomGenerator
    {
        public static bool Boolean();
        public static string String();
        public static string String(string prefix);
        public static short Int8();
        public static short Int8(short maxValue);
        public static short Int8(short minValue, short maxValue);
        public static short Int16();
        public static short Int16(short maxValue);
        public static short Int16(short minValue, short maxValue);
        public static int Int32();
        public static int Int32(int maxValue);
        public static int Int32(int minValue, int maxValue);
        public static TEnum Enum<TEnum>();
        public static TEnum EnumFlagsWith<TEnum>(TEnum flagsToAdd);
        public static TEnum EnumFlagsWithout<TEnum>(TEnum flagsToRemove);
        public static TEnum Enum<TEnum>(int maxValue);
        public static TEnum Enum<TEnum>(int minValue, int maxValue);
        public static System.Guid Guid();
    }
}

This is something that I would like to find on mock frameworks (like Typemock Isolator, Rhino.Mocks or MoQ).

It’s still a work in progress, but if you want to try it, it’s on my MSDN Code Gallery: Random Generator For Unit Testing

More On ASP.NET Validators And Validation Summary Rendering of Properties

On previous posts [^][^] I mentioned the size of ASP.NET validators and validation summary rendering and the fact that expando attributes are being used to add properties. Mohamed also mentions this issue.


Besides the fact that custom attributes aren't XHTML conformant, Firefox differs from Internet Explorer in the way it handles these attributes.


On Internet Explorer, these attributes are converted in string properties of the HTML element. On Firefox, on the other hand, these attributes are only accessible through the attributes collection.


I wonder why I don’t like client-side JavaScript development.

Testing With Multiple Versions Of Internet Explorer

On a previous post I mentioned IETester.

Jorge Moura mentioned TredoSoft’s MultipleIEs and a list of web browsers.

Windows Home Server Power Pack 1 Release Candidate Available For Public Testing

The Windows Home Server Power Pack 1 Release Candidate has been made available for public testing. Read all about it here.

DebugBar, Companion.JS And IETester


Some days ago a colleague of mine pointed out to me this tool (IETester) that allows testing the different rendering and JavaScript engines of Internet Explorer (5.5, 6, 7 and 8beta1) side by side with the installed version.


I haven’t tested IETester yet, but I found two other tools in the site that caught my attention: DebugBar and Companion.JS.


DebugBar is like other tools I use [^] with a few differences. DebugBar is an explorer bar (and docks on the left side of IE) and can’t be undocked but has a JavaScript console and tracks only the HTTP/HTTPS traffic that belongs to the visible web browser tab (IE 7). DebugBar can also spy on other instances of IE like Document Explorer or FeedDemon.


Companion.JS is a Firebug-like tool and was the one that liked the most because it gave me something that I hadn’t: something that kills those annoying scripting error dialogs.


Both DebugBar and Companion.JS claim to be JavaScript debuggers but I couldn’t find any way for setting breakpoints or running scripts step by step. Probably because I have Visual Studio installed on this machine.

Microsoft Tech-Ed EMEA 2008 – Registration Open

Microsoft Tech-Ed EMEA 2008 is open for registration.

Do notice that, this year, the event for IT Professionals happens before the event for Developers.

Microsoft Source Analysis for C# (aka StyleCop)

I’ve learned from a fellow GASPer of the release of Microsoft Source Analysis for C# (aka StyleCop).

It’s still a work in progress but it’s already very useful.

Windows Live Writer Technical Preview

Today Windows Live Writer released a technical preview that includes new and improved features.

From what I’ve seen so far, I like:

  • Revised main toolbar: Blog selection, help and colorize are now on the right.
  • Excel like tabs for view switching. No more selecting a drop down menu to select a view.
  • Improved category control with search/filtering.

I don’t like:

  • Having a predefined set of languages for spell checking. And Portuguese is not one of them.
  • It’s still a pain to change the the language for spell checking.
  • There’s no predefined language setting for each account.