Как запустить NUnit программно

У меня есть сборка, которая ссылается на NUnit и создает один тестовый класс с одним тестовым методом. Я могу получить путь файловой системы к этой сборке (например, "C:...\test.dll"). Я хотел бы программно использовать NUnit для работы с этой сборкой.

Пока у меня есть:

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

Однако вызов runner.Load(path) вызывает исключение FileNotFound. По трассировке стека я вижу, что проблема в том, что NUnit вызывает Assembly.Load(path) вниз по стеку. Если я изменю путь на что-то вроде «Тест, версия = 1.0.0.0, культура = нейтральный, PublicKeyToken = null», я все равно получаю ту же ошибку.

Я добавил обработчик событий в AppDomain.Current.AssemblyResolve, чтобы увидеть, могу ли я вручную разрешить этот тип, но мой обработчик никогда не вызывается.

В чем секрет работы Assembly.Load(...)??


person justin.m.chase    schedule 12.10.2008    source источник
comment
В конце концов, мое решение состояло в том, чтобы просто использовать XUnit. NUnit довольно грубый.   -  person justin.m.chase    schedule 20.09.2011


Ответы (2)


Если вы хотите открыть в консольном режиме, добавьте ссылку nunit-console-runner.dll и используйте:

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

Если вы хотите открыть в режиме графического интерфейса, добавьте ссылку nunit-gui-runner.dll и используйте:

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

Это лучший подход, потому что вам не нужно указывать какой-либо путь.

Другой вариант — также интегрировать NUnit runner в выходные данные отладчика Visual Studio:

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(); }
        }
    };
}
person Ricibald    schedule 16.01.2009
comment
Я попробовал этот подход, и он дает ссылку на объект, не установленную на экземпляр объекта. при звонке на мейн. Возможно, сейчас ожидаются другие аргументы? - person Justin; 22.08.2011
comment
Если вы используете режим графического интерфейса и nunit-gui-runner.dll, не забудьте пометить свою основную функцию как [STAThread]. - person Wes; 29.03.2012
comment
Я только что сделал второй пример, GUI. Мне пришлось изменить "/run" на "-run". Я работаю на Debian Gnu/Linux. - person ctrl-alt-delor; 11.02.2014
comment
@Was Добавление [STAThread] перестало отлаживать локальную переменную. удаление исправило это. - person ctrl-alt-delor; 11.02.2014
comment
Здравствуйте, когда я пытаюсь открыть режим графического интерфейса и использую код из вашего примера, у меня возникает следующая проблема: при первом запуске все в порядке, при втором запуске я получаю сообщение об ошибке: Объект не установлен в качестве экземпляра объекта. Анализируя трассировку стека, я обнаружил, что эта ошибка возникает внутри кода nunit. Может быть, я должен что-то почистить после показа графического интерфейса? - person Sergiu; 07.06.2016

«В чем секрет работы Assembly.Load?»

System.Reflection.Assembly.Load принимает строку, содержащую имя сборки, а не путь к файлу.

Если вы хотите загрузить сборку из файла, используйте:

Assembly a = System.Reflection.Assembly.LoadFrom(pathToFileOnDisk);

(LoadFrom фактически использует Assembly.Load внутри)

Кстати, по какой причине вы не можете использовать NUnit -Консольный инструмент командной строки и просто передать ему путь к вашей тестовой сборке? Затем вы можете просто использовать System.Diagnostics.Process для запуска этого из вашего клиентского приложения, может быть проще?

person Ash    schedule 12.10.2008
comment
Ну, я хотел бы использовать LoadFrom, но, к сожалению, Assembly.Load вызывается из NUnit, а не из моего кода, поэтому я не могу его контролировать. - person justin.m.chase; 12.10.2008
comment
Мне, вероятно, нужно будет просто вызвать его через процесс, как вы предлагаете... Я бы предпочел иметь объекты для своих собственных целей отображения, но сейчас должно быть достаточно просто использовать процесс. - person justin.m.chase; 12.10.2008
comment
В программировании нет «секретов»! - person Marcel Valdez Orozco; 21.12.2012