Search code examples
c#.netnunitassembly.load

How to run NUnit programmatically


I have some assembly that references NUnit and creates a single test class with a single test method. I am able to get the file system path to this assembly (e.g. "C:...\test.dll"). I would like to programmatically use NUnit to run against this assembly.

So far I have:

var runner = new SimpleTestRunner();
runner.Load(path);
var result = runner.Run(NullListener.NULL);

However, calling runner.Load(path) throws a FileNotFound exception. I can see through the stack trace that the problem is with NUnit calling Assembly.Load(path) down the stack. If I change path to be something like "Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" then I still get the same error.

I have added an event handler to AppDomain.Current.AssemblyResolve to see if I could manually resolve this type but my handler never gets called.

What is the secret to getting Assembly.Load(...) to work??


Solution

  • If you want to open in a console mode, add nunit-console-runner.dll reference and use:

    NUnit.ConsoleRunner.Runner.Main(new string[]
       {
          System.Reflection.Assembly.GetExecutingAssembly().Location, 
       });
    

    If you want to open in a gui mode, add nunit-gui-runner.dll reference and use:

    NUnit.Gui.AppEntry.Main(new string[]
       {
          System.Reflection.Assembly.GetExecutingAssembly().Location, 
          "/run"
       });
    

    This is the best approach because you don't have to specify any path.

    Another option is also to integrate NUnit runner in Visual Studio debugger output:

    public static void Main()
    {
        var assembly = Assembly.GetExecutingAssembly().FullName;
        new TextUI (new DebugTextWriter()).Execute(new[] { assembly, "-wait" });
    }
    
    public class DebugTextWriter : StreamWriter
    {
        public DebugTextWriter()
            : base(new DebugOutStream(), Encoding.Unicode, 1024)
        {
            this.AutoFlush = true;
        }
    
        class DebugOutStream : Stream
        {
            public override void Write(byte[] buffer, int offset, int count)
            {
                Debug.Write(Encoding.Unicode.GetString(buffer, offset, count));
            }
    
            public override bool CanRead { get { return false; } }
            public override bool CanSeek { get { return false; } }
            public override bool CanWrite { get { return true; } }
            public override void Flush() { Debug.Flush(); }
            public override long Length { get { throw new InvalidOperationException(); } }
            public override int Read(byte[] buffer, int offset, int count) { throw new InvalidOperationException(); }
            public override long Seek(long offset, SeekOrigin origin) { throw new InvalidOperationException(); }
            public override void SetLength(long value) { throw new InvalidOperationException(); }
            public override long Position
            {
                get { throw new InvalidOperationException(); }
                set { throw new InvalidOperationException(); }
            }
        };
    }