3302

A TraceListener For Tests

In my code, I make extensive use of debug assertions (see System.Diagnostics.Debug.Assert). These assertions are very helpful while debugging because you don’t need to step into every line of code to see if all pre-conditions are met. As soon as a pre-condition fails, an assertion failed window will pop up and will allow us to either abort, ignore or go to the assertion instruction (retry).


Imagine you have this code:

private void IKnowForSureThatANullStringWillNeverBePassed(string text)
{
System.Diagnostics.Debug.Assert(string != null, "text is null.");

// ...
}


Because this method is private, I have full control of what is passed to the text parameter, therefore I’m asserting that it will never be null. Because it might not be obvious that text will never be null, the assertion also acts as documentation.


I usually run my unit tests and integration test on debug compilations and these assertions would be helpful by making the test fail on an assertion fail instead of running through the method and failing with an NullReferenceException. That’s why I (and more people out there) wrote this simple TraceListener:

public class TraceListener : global::System.Diagnostics.TraceListener
{
public static readonly TraceListener Default = new TraceListener();

protected TraceListener()
{
this.Name = "Testing Trace Listener";
}

protected TraceListener(string name)
: base(name)
{
}

public override void Write(string message)
{
}

public override void WriteLine(string message)
{
}

public override void Fail(string message, string detailMessage)
{
var builder = new global::System.Text.StringBuilder();

builder.Append(message);

if (detailMessage != null)
{
builder.Append(" ");
builder.Append(detailMessage);
}

throw new global::Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException(builder.ToString());

}
}


This trace listener won’t write anything to anywhere. It will just throw an AssertFailedException if the Fail method is called, which is what happens when an assertion fails.


Because an assertion window is not desired when running the tests (specially if they are automated tests ran as part of a build process) it’s better to disable the assert UI on the configuration file of the test project.

<?xml version="1.0" encoding="utf-8" ?>
<
configuration>
<
system.diagnostics>
<
assert assertuienabled="false"/>
<
trace>
<
listeners>
<
add name="TestTraceListener"
type="PauloMorgado.TestTools.VisualStudio.UnitTesting.Diagnostics.TraceListener, PauloMorgado.TestTools.VisualStudio" />
</
listeners>
</
trace>
</
system.diagnostics>
</
configuration>
You can find this and other tools on the PauloMorgado.TestTools on CodePlex.

How To Set Elements Of An Array Of A Private Type Using Visual Studio Shadows

Visual Studio uses Publicize to create accessors public for private members and types of a type.


But when you try to set elements of a private array of elements of a private type, things get complicated.


Imagine this hypothetic class to test:

public static class MyClass
{
private static readonly MyInnerClass[] myArray = new MyInnerClass[10];

public static bool IsEmpty()
{
foreach (var item in myArray)
{
if ((item != null) && (!string.IsNullOrEmpty(item.Field)))
{
return false;
}
}

return true;
}

private class MyInnerClass
{
public string Field;
}
}


If I want to write a test for the case when the array has “non empty” entries, I need to setup the array first.


Using the accessors generated by Visual Studio, I would write something like this:

[TestClass()]
public class MyClassTest
{
[TestMethod()]
public void IsEmpty_NotEmpty_ReturnsFalse()
{
for (int i = 0; i < 10; i++)
{
MyClass_Accessor.myArray[i] = new MyClass_Accessor.MyInnerClass { Field = i.ToString() };
}

bool expected = false;
bool actual;

actual = MyClass.IsEmpty();

Assert.AreEqual(expected, actual);
}
}


But the test will fail because, although the elements of the private array myArray can be read as MyClass_Accessor.MyInnerClass instances, they can’t be written as such.


To do so, the test would have to be written like this:

[TestClass()]
public class MyClassTest
{
[TestMethod()]
public void IsEmpty_NotEmpty_ReturnsFalse()
{
for (int i = 0; i < 10; i++)
{
MyClass_Accessor.ShadowedType.SetStaticArrayElement("myArray", new MyClass_Accessor.MyInnerClass { Field = i.ToString() }.Target, i);
}

bool expected = false;
bool actual;

actual = MyClass.IsEmpty();

Assert.AreEqual(expected, actual);
}
}


But, this way, we loose all the strong typing of the accessors because we need to write the name of the array field.


Because the accessor for the field is a property, we could write a set of extension methods that take care of getting the field name for us. Something like this:

public static class PrivateypeExtensions
{
public static void SetStaticArrayElement<T>(this PrivateType self, Expression<Func<T[]>> expression, T value, params int[] indices)
{
object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value;

self.SetStaticArrayElement(
((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name,
elementValue,
indices);
}

public static void SetStaticArrayElement<T>(this PrivateType self, Expression<Func<T[]>> expression, BindingFlags invokeAttr, T value, params int[] indices)
{
object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value;

self.SetStaticArrayElement(
((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name,
invokeAttr,
elementValue,
indices);
}
}


Now, we can write the test like this:

[TestClass()]
public class MyClassTest
{
[TestMethod()]
public void IsEmpty_NotEmpty_ReturnsFalse()
{
for (int i = 0; i < 10; i++)
{
MyClass_Accessor.ShadowedType.SetStaticArrayElement(() => MyClass_Accessor.myArray, new MyClass_Accessor.MyInnerClass { Field = i.ToString() }, i);
}

bool expected = false;
bool actual;

actual = MyClass.IsEmpty();

Assert.AreEqual(expected, actual);
}
}


It’s not the same as the first form, but it’s strongly typed and we’ll get a compiler error instead of a test run error if we change the name of the myArray field.


You can find this and other tools on the PauloMorgado.TestTools on CodePlex.

Compiling .NET 1.1 Projects In Visual Studio 2008

After having put my .NET 1.1 application running on the .NET 2.0 runtime (^), I’m planning on migrating it to .NET 2.0, but not all at once.

Because I don’t want to have 2 solutions (one on Visual Studio 2003 for the .NET 1.1 assemblies and another on Visual Studio 2008 for the .NET 2.0 assemblies) I decide to try using MSBee and have only one Visual Studio 2008 solution.

MSBee has a CodePlex project. You can download it from there or from Microsoft Downloads. Because the build on Microsoft Downloads seemed to be the most stable one, that was the one I downloaded and installed. The package comes with a Word document that explains all that needs to be done.

Before you can install and use MSBee you’ll need to install the .NET 1.1 SDK.

Having everything installed, I just opened the Visual Studio 2003 solution in Visual Studio 2008 and let it convert the solution and projects (near 30).

After the conversion, for building the projects with the .NET 1.1 C# compiler, the project files need to be edited to add the override the default targets with the MSBee ones by adding the MSBee imports after the default imports for the language:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\MSBee\MSBuildExtras.FX1_1.CSharp.targets" />

Another change needed (for Visual Studio 2008 - I don't know if it was needed for Visual Studio 2005) is the tools version. MSBee needs version 2.0. To change that you'll have to change the ToolsVersion attribute of the project’s root element:

<Project DefaultTargets="Build" ToolsVersion="2.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

MSBee likes has own idea about output paths and I had set up custom output paths on my project. There’s information about this on the documentation but I decided to simply comment that out of the $(MSBuildExtensionsPath)\MSBee\MSBuildExtras.FX1_1.Common.targets file:

<!-- Paulo
<Choose>
  <When Condition=" '$(BaseFX1_1OutputPath)' == '' ">
    <PropertyGroup>
      <OutputPath>bin\FX1_1\</OutputPath>
    </PropertyGroup>
  </When>
  <Otherwise>
    <PropertyGroup>
      <OutputPath>$(BaseFX1_1OutputPath)</OutputPath>
      <OutputPath Condition=" !HasTrailingSlash('$(OutputPath)') ">$(OutputPath)\</OutputPath>
    </PropertyGroup>
  </Otherwise>
</Choose>
-->

<!-- Paulo
<PropertyGroup>
  <BaseIntermediateOutputPath>obj\FX1_1\</BaseIntermediateOutputPath>
  <IntermediateOutputPath Condition=" '$(PlatformName)' == 'AnyCPU' ">$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
  <IntermediateOutputPath Condition=" '$(PlatformName)' != 'AnyCPU' ">$(BaseIntermediateOutputPath)$(PlatformName)\$(Configuration)\</IntermediateOutputPath>

  <OutputPath Condition=" '$(PlatformName)' == 'AnyCPU' ">$(OutputPath)$(Configuration)\</OutputPath>
  <OutputPath Condition=" '$(PlatformName)' != 'AnyCPU' ">$(OutputPath)$(PlatformName)\$(Configuration)\</OutputPath>
  
  <- Once OutputPath is determined, set OutDir to its value. ->
  <OutDir>$(OutputPath)</OutDir>
</PropertyGroup>
-->

This all seemed to work fine on my old Windows XP machine without any third party Visual Studio plug-ins, but when I tried it on my Windows Vista X64 machine, I came across some problems:

  • License Compiler

    Because I'm using Infragistics' controls, there's a licences.licx file and the build will compile it. And that proved to be a problem.

    MSBee copies all the files it needs to the build process to a temporary folder, builds it in there and then copies the result to the output path.

    LC.exe seemed to never be able to find all the assemblies it needed. Searching seemed to me to be an old issue (even from the .NET 1.1 times) and the solution always pointed to not compile the license file. So, I commented that part out of the $(MSBuildExtensionsPath)\MSBee\MSBuildExtras.FX1_1.Common.targets file:

    <Target
        Name="CompileLicxFilesCondition="'@(_LicxFile)'!=''"
        DependsOnTargets="$(CompileLicxFilesDependsOn)"
        Inputs="$(MSBuildAllProjects);@(_LicxFile);@(ReferencePath);@(ReferenceDependencyPaths)"
        Outputs="$(IntermediateOutputPath)$(TargetFileName).licenses">
    
      <!--
      <LC
          Sources="@(_LicxFile)"
          LicenseTarget="$(TargetFileName)"
          OutputDirectory="$(IntermediateOutputPath)"
          OutputLicense="$(IntermediateOutputPath)$(TargetFileName).licenses"
          ReferencedAssemblies="@(ReferencePath);@(ReferenceDependencyPaths)"
          ToolPath="$(TargetFrameworkSDKDirectory)bin\">
    
        <Output TaskParameter="OutputLicense" ItemName="CompiledLicenseFile"/>
        <Output TaskParameter="OutputLicense" ItemName="FileWrites"/>
    
      </LC>
      -->
    </Target>

  • Resource Generator

    Although this worked fine on the command line, inside Visual Studio ResGen.exe would throw some error and needed to be closed.

    Looking at the Windows Application Log I found out this:

    Faulting application Resgen.exe, version 1.1.4322.573, time stamp 0x3e559b5f, faulting module MockWeaver.dll, version 0.0.0.0, time stamp 0x4adb072e, exception code 0xc0000005, fault offset 0x00018fac, process id 0x4a50, application start time 0x01ca53c14488a2fb.

    MockWeaver.dll belongs to Isolator and I just disable it when building inside Visual Studio. I was hoping to start using Isolator on this project, but, for now, I can't.

I hope this can be of some help and, if you need more, you’ll probably find it at the MSBee’s CodePlex forum.

The bottom line is: You don’t need Visual Studio 2003!

Help Typemock Launch Its New Visual Basic .NET Friendly API And You Might Get A Free License


Typemock is announcing today a new version of Typemock Isolator (5.2).


One of the coolest features in the new version is the inclusion of a new VB .NET unit testing API. This 'VB friendly' API was designed and written in VB.NET, for VB.NET developers. It uses the strengths of the VB.NET language to allow easy and intuitive use of the isolation API, for easier unit tests on any piece of .NET code.


If you are you a blogger, webmaster, or internet columnist, you can get your free personal license by helping Typemock launch their new 5.2 version for Isolator - the best tool to unit test VB.NET applications.


Although this version is targeted to unit test VB.NET applications, C# applications with unit tests built using Visual Studio 2005 can also benefit from this API.


How can you get the free license?


Post the text below on your blog (as is, with links) and tell them about it . If you are in the first 25 to mail them after posting, your license will be on its way!


If you have a VB.NET dedicated blog, you'll get a license automatically (even if more than 25 submit) during the first week of this announcement.


A few simple requirements:




  1. You must own a website, blog space or internet column, older than 2 months, or get permission from the owner of such a site.


  2. Your post must include the text below (including the links) between *Begin* and *End*.

_


*Begin*


Programming Visual Basic applications?


Typemock have released a new version of their unit testing tool, Typemock Isolator 5.2.
This version includes a new friendly VB.NET API which makes Isolator the best Isolation tool for unit testing A Visual Basic (VB) .NET application.


Isolator now allows unit testing in VB or C# for many ‘hard to test’ technologies such as SharePoint, ASP.NET MVC, partial support for Silverlight, WPF, LINQ, WF, Entity Framework, WCF unit testing and more.


Note that the first 25 bloggers who blog this text in their blog and tell us about it, will get a Free Full Isolator license (worth $139). If you post this in a VB.NET dedicated blog, you'll get a license automatically (even if more than 25 submit) during the first week of this announcement.


Go ahead, click the following link for more information on how to get your free license.


_


*End*


Once you post this in your site, just drop them a line at vb@typemock.com with your name and the post URL to get your free license.


Hurry up – this offer is limited to the first 25 general bloggers, or to VB.NET dedicated bloggers who will post this in the first week.


--


Disclaimer: This is an offer from Typemock as announced at http://blog.typemock.com/2009/01/get-free-isolator-licnese-for-helping.html. I’m just a fan.

Improving Debugging And Testing Through Assertions

Reading through the The Typemock Insider blog, I came across this post from Gil Zilberfeld.

I myself tend to fall in Gil’s practice ("binary search" debugging), but I don’t think Kent Beck has the right solution.

Gil’s suggestion of using Isolator is tempting (I don’t miss an opportunity to use it), but still not my favorite one.

I prefer to use debug assertions. Debug assertions can be used when running a debug version of the application to pop-up assertion messages and when running unit tests to fail tests.

In order to use debug assertions in unit tests a “special” trace listener is needed to make the test fail when its Fail method is called.

public class UnitTestTraceListener : global::System.Diagnostics.DefaultTraceListener
{
     public UnitTestTraceListener() : base()
    {
        this.Name = "UnitTest";
        this.AssertUiEnabled = false;
    }

    public override void Fail(string message, string detailMessage)
    {
        Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail("Debug.Assert Failed: " + message + " " + detailMessage);
    }
}

Now, all you need to do is register it.

Registering the trace listener can either be done in code:

System.Diagnostics.Trace.Listeners.Remove("Default");
System.Diagnostics.Trace.Listeners.Add(new UnitTestTraceListener());

or configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <assert assertuienabled="false"/>
    <trace>
      <listeners>
        <clear/>
        <add name="UnitTest" type="UnitTestTraceListener"/>
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

And if I’m using Isolator I have the take in account the accesses made in the call to the Assert method. More fun to me.

The Future Of C#


If you were able to attend this session at PDC or Tech-Ed EMEA Developers, you were presented with a first class presentation of the future of C#, presented, respectively, by Anders Hejlsberg and Mads Torgersen.


For the near future (.NET 4.0) C# will have:




  • Dynamically Typed Objects


  • Optional and Named Parameters


  • Improved COM Interoperability


  • Co- and Contra-variance

A preview of the compiler as a service was shown, but that’s not for the .NET 4.0 / Visual Studio 2010 timeframe. Probably, not even for the next.


Starting with .NET 4.0, C# and Visual Basic will converge in terms of features and follow a path of co-evolution going into the future.


No! That doesn’t mean that XML literals will be in C# in a foreseeable future. What that means is that the above list also applies to Visual Basic.


Talking of Visual Basic evolution, the _ line continuation character has been retired. If you have any use for the underscore, please visit http://www.unemployedunderscores.com/.


Resources:


PDC And Tech-Ed Wrap-Up

(It might seem a bit late for this, but, lately, I’ve been having a lot on my mind. So here it goes.)

This was my first PDC. It was just as I had been told.

For those who don’t know, the PDC is all about the future. The near future (.NET 4.0 and Windows 7) and the further future (Windows Azure, “Oslo”, “Dublin”, “Geneva”).

Next year’s PDC (Yes! Apparently, there’ll be one next year) will be also held in Los Angeles from November 17 to 20, and (I suspect) will be the commercial launch of the Azure Services Platform and a better story to tell about “Oslo”.

Tech-ED EMEA Developers, on the other hand, is more about the present and the near future. But, this year, attendees were able to have a sneak peek at what had bee shown at the PDC.

Next year’s Tech-ED EMEA Developers will be held in Berlin from November 2 to 6. Probably, like in 2006, it will be the launch of .NET 4.0 and Visual Studio 2010.

And I intend to attend both.

MSDN Ramp Up Program

MSDN Ramp Up Program

I just came across this: www.MyRampUp

Ramp Up is a free, online, community-based program that can help users save time in learning Microsoft technology.

The easy-to-access content (provided by subject-matter gurus) is specifically tailored to the Ramp Up program, and offered in a variety of forms (whitepaper, v-lab, codecast and slidecast).

Program Guide

The currently available routes are:

SharePoint for Developers track - learn more

Visual Studio 2008 track - learn more

Aspiring Developer - learn more

Success with Java and C# - learn more

Next Level Visual Basic - learn more

Next Level Microsoft.NET - learn more

Currently, there are no assessments in the program, so it's quicker than ever to graduate and receive the reward (25% off on certification and 50% off on e-Learning - only for graduates of Ramp Up).

Clone Detective For Visual Studio

Clone Detective for Visual Studio

Clone Detective is a tool that integrates with Visual Studio and uses the ConQAT (Continuous Quality Assessment Toolkit) to analyze C# projects and search for duplicated source code.

Watch the videos and see if this is the tool you were looking for.

Typemock Isolator 5.0 Is Out With Its New AAA API

Typemock has released version 5.0 of its unit testing tool: Isolator. Check out the release notes.

This new version comes with a new API: Arrange Act Assert:

I’ll have to say that I liked Isolator better over Isolate.

Also new in this version is the inclusion of the help file in the installation package.