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

#c# #.net #nunit #assembly.load

Вопрос:

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

До сих пор у меня было:

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

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

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

В чем секрет получения сборки?Загрузить(…) на работу??

Комментарии:

1. В конце концов, моим решением было просто использовать xUnit. НУнит довольно жестокий.

Ответ №1:

Если вы хотите открыть в режиме консоли, добавьте 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(); }
        }
    };
}
 

Комментарии:

1. Я попробовал этот подход, и он дает «Ссылку на объект, не заданную для экземпляра объекта». при вызове Main. Возможно, сейчас ожидаются другие аргументы?

2. Если вы используете режим графического интерфейса amp; nunit-gui-runner.dll, не забудьте пометить свою основную функцию как [STAThread].

3. Я только что сделал второй пример, графический интерфейс. Мне пришлось переодеться "/run" "-run" . Я работаю на Debian Gnu/Linux.

4. @Добавлял [STAThread] остановленную отладку локальной переменной. удаление исправило это.

5. Здравствуйте, когда я пытаюсь открыть режим графического интерфейса и использую код из вашего примера, у меня возникает следующая проблема: первый запуск ок, второй запуск я получаю ошибку: «Объект не установлен в экземпляр объекта». Анализируя трассировку стека, я обнаружил, что эта ошибка возникает внутри кода nunit. Может быть, мне следует что-то почистить после показа бегуна с графическим интерфейсом?

Ответ №2:

«В чем секрет получения Собрания?Груз на работу?»

Система.Отражение.Собрание.Загрузка принимает строку, содержащую имя сборки, а не путь к файлу.

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

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

(Загрузка из фактически используемой сборки.Загрузите внутри)

Кстати, есть ли какая-либо причина, по которой вы не можете использовать инструмент командной строки NUnit-Консоли и просто передать ему путь к вашей тестовой сборке? Тогда вы могли бы просто использовать Систему.Диагностика.Процесс запуска этого из клиентского приложения может быть проще?

Комментарии:

1. Ну, я хотел бы использовать загрузку из, но, к сожалению, Сборка. Загрузка вызывается из NUnit, а не из моего кода, поэтому я не могу ее контролировать.

2. Мне, вероятно, нужно будет просто вызвать его с помощью процесса, как вы предлагаете… Я бы предпочел иметь объекты для своих собственных целей отображения, но пока этого должно быть достаточно, чтобы просто использовать процесс.

3. В программировании нет никаких «секретов»!