The AssemblyTester

The AssemblyTester uses the PropertyTester and ConstructorTester and can remove much of the coding previously required to use them by applying these tests to all the types in an assembly, subject to exclusions that you can specify.

How it works

To test an assembly simply create an instance of the AssemblyTester passing it the name of the Assembly to test.

AssemblyTester tester = new AssemblyTester("TheJoyOfCode.QualityTools");

Now you can call the AssemblyTesters TestAssembly method which looks like this:

     public void TestAssembly(bool testProperties, bool testConstructors)

The testProperties and testConstructors parameters should be fairly self explanatory!

The example below aims to test both constructors and properties in the "TheJoyOfCode.QualityTools.Tests.DummyProject" assembly.

     AssemblyTester tester = new AssemblyTester("ExampleAssembly");
     tester.TestAssembly(true, true);

The AssemblyTester will throw an exception with a detailed description of errors encountered when testing an assembly. Here's an example:

AssemblyTesterTest.AssemblyTester_PassWithExclusions : FailedTheJoyOfCode.QualityTools.AssemblyTestException: 
Testing the assembly TheJoyOfCode.QualityTools.Tests.DummyProject produced the following errors:
The get value of the 'Dummy4' property on the type 'TheJoyOfCode.QualityTools.Tests.DummyProject.WithErrors.IncorrectProperties' 
did not equal the set value (in: '', out: 'fe6faacc-3ea8-45a0-8c5c-dc2e0021065b')

The value of the 'Dummy1' property did not equal the value set with the 'dummy1' 
constructor parameter (in: 'cf04ca44-73dc-4147-bb3e-2a1a0d2c52b3', out: '819e635d-4dc6-4e6c-b141-75f0212cb242')

The type TheJoyOfCode.QualityTools.Tests.DummyProject.WithErrors.GenericClass`1 is an open 
Generic Definition (e.g. Class<T>. Only closed generic types Class<int> are currently supported.

Cannot create an instance of TheJoyOfCode.QualityTools.Tests.DummyProject.WithErrors.GenericClass`1[T] 
because Type.ContainsGenericParameters is true. 

Not all types in an assembly qualify for automatic testing of constructors or properties. Looking at the errors produced above it is clear that the two first errors are should be fixed (A property which is not mapped correctly and a constructor which does not map correctly to the corresponding property). The last two errors indicates that the AssemblyTester can not test this particular type because it contains generic parameters.


To still use the AssemblyTester on this module we can skip these last two issues. This can be done in two ways, specifying one or more types to exclude or specifying a namespace to exclude.

Excluding a type

The example excludes the class which is not qualified for automatic testing to the AssemblyTester.

     AssemblyTester tester = new AssemblyTester("TheJoyOfCode.QualityTools.Tests.DummyProject");
     tester.TestAssembly(AssemblyTester.TestTarget.Properties | AssemblyTester.TestTarget.Constructors);

When running the test again the AssemblyTester only produces the following errors.

TheJoyOfCode.QualityTools.AssemblyTestException: Testing the assembly 
TheJoyOfCode.QualityTools.Tests.DummyProject produced the following errors:
The get value of the 'Dummy4' property on the type 'TheJoyOfCode.QualityTools.Tests.DummyProject.WithErrors.IncorrectProperties' 
did not equal the set value (in: '', out: '1e5101b5-e9e9-4d69-b13c-83863f70a7b6')

The value of the 'Dummy1' property did not equal the value set with the 'dummy1' 
constructor parameter (in: '2bf2002e-b505-4413-a8f9-97036c40f720', out: '8a447a00-2f17-4d27-bb25-1fc66bf2c39d')

The errors above are errors which the AssemblyTester has been designed to detect; errors in mapping properties to fields and mapping values to constructors. So to make the test pass we need to fix those errors!

Excluding a namespace

The example below excludes all types in the namepace "ExampleAssembly.SomeNamespace" namespace but does not exclude types in any sub namespaces.

     tester.Exclusions.AddNamespace("ExampleAssembly.SomeNamespace", false);

We could specify that all types within a numespace and sub-namespaces are excluded like so:

     tester.Exclusions.AddNamespace("ExampleAssembly.SomeNamespace", true);

For example, this would also exclude any type in the "ExampleAssembly.SomeNamespace.SomeSubNamespace" too.

You can have as many exclusions as you like and can combine type exclusions with namespace exclusions. Easy peasy.

If you need to exclude a type from an assembly test because of one funky property or constructor you can always target that type directly with the PropertyTester or ConstructorTester and exclude the property/type specifically. Best of both worlds.

Adding your own exclusion rules

It's easy to extend the exclusion policies available in the AssemblyTester by creating your own class that inherits from TestExclusion. Imagine you want to be able to exclude any class that starts with the letter 'S'. First we need a new

private class StartsWithSExclusion : TestExclusion
    public override bool IsExcluded(Type type)
        return type.Name.StartsWith("S");

Now we just have to add that type to the Exclusions as follows:

     tester.Exclusions.Add(new StartsWithSExclusion());

... and any types whose name starts with an S won't be tested.


Q: It's nice that I can exclude whole types and namespaces using the AssemblyTester but why can't I specify a single property on a type that should be excluded.
A: This feature is deliberately not included to date. The practice in this case is to exclude the type from the assembly test like so:

AssemblyTester tester = new AssemblyTester("MyType, MyAssembly");
tester.TestAssembly(true, true);

Now, add another test to target that class using the PropertyTester directly:

PropertyTester tester = new PropertyTester(new TypeWithUntestableProperty));

Last edited Jan 9, 2008 at 3:19 PM by molmorg, version 5


No comments yet.