May 2004 - Posts

Non-Admin & VS2005

I've had mixed success with the NUnitAddIn installation issues.  I've tried to make it so that an administrator can do and install for all non-admin users.  According to the documentation Visual Studio does supports this, but so far I haven't been able to get it working.  I even created a noddy add-in using the 'Extensibility Project' wizard, but even this wouldn't work for non-admin users.  Are there any add-ins out there that work for non-admin users?

I've had better luck getting it to work with Visual Studio 2005.  I haven't uploaded it for general consumption yet as there are a couple of minor quirks you will need to need to be aware of (I now know what Don Box means about VS2005 having several "trip wires").  If you are interested in trying it just drop me a line and I'll send a link along with some notes.

Does anyone know if .NET 1.1 will work with any 2.0 assemblies?

Posted by Jamie Cansdale | with no comments

NUnitAddIn Install

If you have had problems installing a recent version of NUnitAddIn please contact me. I know some people have had issues and I would really like to get to the bottom of this. The most recent version is NUnitAddIn-0.6.365 and you can find it here.  There have been over 800 downloads of this version and only 1 person has contacted me (thanks Mawi).  The chances are it will work, but if not please let me know!

Posted by Jamie Cansdale | 9 comment(s)
Filed under:

Mono in 2005

I'm in the slightly odd situation where only Mono is working with Visual Studio 2005. The older .NET runtimes are throwing the following exception...

TestCase 'M:Tests.TestVS2005.TestRuntime' failed: The format of the file 'ClassLibrary2005.dll' is invalid.
System.BadImageFormatException: The format of the file 'ClassLibrary2005.dll' is invalid.
File name: "ClassLibrary2005.dll"

I find it hard to believe that .NET 1.1 will choke on any 2.0 assembly. Hopefully there will be some way to persuade it to work. Any ideas?

Above you can see Mono executing a .NET 2.0 assembly built with Visual Studio 2005. Notice that PInvoke works with Mono.  I'd writing debug strings like this to avoid referencing the 'System' assembly.  I don't think Mono supports binding redirects yet.  Apart from that, what can I say?  Go Mono!

I'm afraid this build isn't out yet.  I'm still knocking out a few rough edges when running under 2005.  Without my unit tests working I'm feeling a bit hobbled!

Posted by Jamie Cansdale | with no comments
Filed under:

Changing a DLL Project to EXE

NUnit supports having a '.config' file associated with a test assembly.  When creating a new app domain, NUnit looks for a file with the same file name as the test assembly but ending with '.config' (eg My.Tests.dll.config).  This is similar to the way .NET uses EXE.config files when a new process is started.

The only problem here is that your DLL probably ends up in a 'bin\Debug' or 'bin\Release' directory.  You could just copy the '.config' files there, but do you really want to be checking files in these directories into version control?  One possible solution is to put your tests in an EXE project. Doing it this way means Visual Studio will copy any 'app.config' file into the correct place. As Kiwidude pointed out you can even create a link to the 'app.config' file in your real project. Now that is pretty neat.  There is one subtle gotcha that it far too easy to fall into...

Kiwidude said:

My excitement at this new solution was sadly short-lived... for whatever reason the 'Test With Debugger' functionality does not appear to work when the test project type is an executable. Breakpoints in the test case code itself are ignored - although breakpoints are caught in the .dlls that the test code calls. Looking at the call stack it appears the test cases are on the 'wrong side' of the remoting boundary when contained in an executable... switching the project type back to a .dll and the test case breakpoints magically work again. Excuse my ignorance but I assume there is some logical reason for this rather than it being a bug?

When you change a DLL project to an EXE project, Viausl Studio will leave a copy of the old DLL in the output directory. This can cause all kinds of maddening and subtle bugs. The problem is the EXE will end up in the LoadFrom binding context whereas the DLL will end up in the Load binding context. After being burnt numerous times I have taken to always using Assembly.Load rather than Assembly.LoadFrom if at all possible. Unfortunately in this case it will mean the original DLL will be loaded instead of the EXE. I suspect this is what is causing the 'Test With Debugger' issue. With any luck deleteing the old DLL will fix it.

[Update] Darrell made me realise I completely missed out any kind of introduction. :o)
[Update] See comments for Kiwidude's explanation of why doing it this way is a good idea.

.NET Reflector Add-Ins 4.0.3.0

The Reflector Add-In for Visual Studio .NET is now being maintained in the .NET Reflector Add-Ins GDN Workspace. This has the huge advantage that for every new build of .NET Reflector the add-ins will be compiled and updated. Although the add-ins might keep working when you use Reflector's 'Check for Updates' feature - it is highly recomended that you download the latest add-ins.

In the latest build of the Visual Studio add-in I have fixed one of its most anoying shortcomings. In previous builds you were required to launch Reflector using the 'Addins/Reflector' menu before using any of the Reflector options. In the new build Reflector will be launched when you first use any of the Reflector related functionality. If you wanted to decompile some Visual Basic source into C# you could just select 'Reflector.../Decompile to C#'.  'Synchrinize Reflector' on the other hand keeps your existing view and only synchronizes Reflector (it is desinged to work in a similar way to 'Synchronize Class View').

You can download the latest add-ins from here. Make sure you unzip them into the same directory as 'Reflector.exe' (if you don't the installer won't work!). To install the add-in simply double click on 'Reflector.VisualStudio.exe'. This will install the add-in and fill Visual Studio with Reflector related functionality.  It is a good idea to close all instances of Visual Studio before installing any add-ins.

If you have any problems, questions or ideas please comment here or in the workspace.  If you find a bug then please use the bug tracker.  There is a know issue if you close Visual Studio without first exiting Reflector.  Visual Studio will forget Reflector's tool window locations.  To avoid this simply exit Reflector before shutting down Visual Studio.  Nothing bad will happen if you don't.

Posted by Jamie Cansdale | 13 comment(s)
Filed under:

App.config Files

Kiwidude asked a question about how 'app.config' files are handled.

How do use your add-in with app.config files now? With the 'previous version' I managed a 'bodge' of creating one in my test project bin directory called 'NUnitAddin.TestRunner.Server.exe.config', and copying the contents of my 'real' app.config into that. Ugly but only way I could get it to work. Now this no longer works (you seem to be creating random appdomain config files in temp directory)... Can you please explain how we get it to work ?

NUnitAddin has supported config files for a long time. It intentionally handles them in a similar way to NUnit. The last thing you want is tests working in NUnitAddin but failing with NUnit (or the other way around). When NUnit creates a new app domain it looks for a config file with the same name as the test assembly but ending with '.config'. This is convenient if the test assembly is an EXE project because Visual Studio with automatically rename and copy 'app.config' files into the project output directory. If however the project you're working on is a DLL project, you will have to do this yourself as Visual Studio won't help you out.

It would be easy for NUnitAddin to help out here and copy 'app.config' files for library projects as well. I have been a bit reluctant to do this so far the following reason. If you're using a tool such as CruiseControl.NET for Continuous Integration you will have to make sure the '.config' file is copied as part of the build. In the past I have found it tricky enough mirroring everything that Visual Studio does in the build script. If NUnitAddin started doing this is would be one more thing to remember. If you still want the 'app.config' file automatically copied for your test projects there is an easy solution. Just make your tests and EXE project and Visual Studio will do your dirty work. ;)

Abstract Test Pattern

I thought now would be a good time to mention NUnitAddin's support for 'Abstract Tests'. Jonathan de Halleux has a good write up where he compares the Abstract Test Pattern with MbUnit's support for Composite Unit Testing.  I'm working with him to add support for MbUnit and will mention here when it's ready.  For the moment this is what you can do with plain old NUnit...

Let's say you wanted to test a number of different implementations of the IList interface.  Instead of writing tests for each implementation, you can create an abstract class containing all of the tests.  You then create concrete fixtures that implement a factory method for each implementation you want to test.

Once you have created your abstract tests, you can execute all tests in one of the concrete fixtures as per usual (by right clicking inside the body of the class and selecting 'Run Test(s)').  It is however more interesting to execute tests from inside the abstract base class.  This time if you select inside the body of the base class you will execute all tests in the concrete fixtures (in this case 6).  If you want to be more specific, you can target one of the test methods and have it executed for each concrete fixture.  Below you can see the 'TestAdd' method being targeted which, which causes the 'Add' method of both 'ArrayList' and 'StringCollection' to be tested (2 succeeded).

You can find build 0.6.350 of NUnitAddIn here under 'Latest File Releases'.

namespace Collections.Tests
{
   using System;
   using System.Collections;
   using System.Collections.Specialized;
   using NUnit.Framework;

   public class TestArrayList : BaseTestStringList
   {
       protected override IList CreateList()
       {
           return new ArrayList();
       }
   }

   public class TestStringCollection : BaseTestStringList
   {
       protected override IList CreateList()
       {
           return new StringCollection();
       }
   }

   [TestFixture]
   public abstract class BaseTestStringList
   {
       private IList list;

       [SetUp]
       public void SetUp()
       {
           this.list = CreateList();
       }
protected abstract IList CreateList(); [Test] public void TestAdd() { object item = Guid.NewGuid().ToString(); int beforeCount = this.list.Count; this.list.Add(item); Assert.AreEqual(beforeCount + 1, this.list.Count); } [Test] public void TestContains() { object item = Guid.NewGuid().ToString(); int beforeCount = this.list.Count; this.list.Add(item); Assert.IsTrue(this.list.Contains(item)); } [Test] public void TestClear() { object item = Guid.NewGuid().ToString(); this.list.Add(item); this.list.Clear(); Assert.AreEqual(0, this.list.Count); Assert.IsFalse(this.list.Contains(item)); } } }

A Quick Outline

The .NET Guy highlights one of the most useful features of Reflector from a design and understanding APIs point of view. Selecting 'Outline' with only public visability checked on one of your own namespaces can prove very informative.

If you have installed the .NET Reflector Visual Studio add-in you can outline a class by doing the following. Click on Reflector from the Addins main menu (this step will be obsolete in the next release). Right click anywhere inside the class you want to outline (away from any fields or methods) and select 'Reflector.../Outline'. At this point a new tool window should appear showing your outlined class. Dock the window where you want it (I find next to the 'Output' tab works well). At the moment for the tool window position to be saved you will have to exit Reflector before closing Visual Studio.

As you can see there are still a few quirks I need smooth out. Despite this you should find the add-in unobtrusive and a good alternative to an icon on your quick launch bar. If now runs out-of-proc and in theory shouldn't cause any instability of the Visual Studio process. If it does start playing up just kill the 'Reflector.VisualStudio.exe' process and please let me know!

You can find a download link here.  Remember to read the readme.txt - I never do ;o)

 

Posted by Jamie Cansdale | with no comments
Filed under:

Reflector Add-In Resurrection

You must have been hiding under a rock if you haven't heard about the new version of Lutz Roeder's .NET Reflector by now. With its support for generics, loading any version of mscorlib (including 2.0 and Mono) and the refreshing of assemblies you're in for a treat! This means all of the frustrations faced by my original Reflector Add-In are gone.

Lutz has been kind enough to give me all of the code and hooks needed to make a maintainable version of the add-in. This time round I won't be faced with breakages on every new revision of Reflector (they were coming every few days at one point). Even obfuscation turned out to be a good thing as it removed the temptation to dip into internal stuff that was likely to change.

Here is a link to the new add-in and release notes...

Name: 
Reflector.VisualStudio
Feed: http://weblogs.asp.net/nunitaddin/category/5004.aspx
Description: An add-in for Visual Studio that hosts .NET Reflector and synchronizes the selected CodeElement.
Unzip files into the same directory as Reflector.exe. The resulting directory structure should look like this...
Reflector.exe Reflector.VisualStudio.exe Reflector.VisualStudio.exe.config VisualStudio\MutantDesign.ManagedAddIns.dll VisualStudio\MutantDesign.ManagedAddIns.Services.dll
From the command line execute "Reflector.VisualStudio.exe /install". To remove the add-in execute "Reflector.VisualStudio.exe /uninstall".

To launch .NET Reflector in a tool window select 'Addins/Reflector'. Once started you can 'Synchronize Reflector' (just like Synchronize Class View) on any code element.  This includes methods, fields, classes etc.  Let me know if you find any code elements that don't work in C# projects (support should be pretty comprehensive).  I haven't tested it at all with VB so I'd be interested to know how you get on there.

There is a known issue if you close Visual Studio before closing Reflector.  Your tool window positions won't be saved (which is a bit annoying).  There should be a fix for this later on in the week.  Bug reports are welcome, please comment here.

Posted by Jamie Cansdale | 36 comment(s)
Filed under:
More Posts Next page »