ExceptionAsserts и отладка вашего C # проекта в VS - PullRequest
8 голосов
/ 18 января 2010

Мы уже давно используем NUnit & VisualStudio для написания кода на C # .NET. Тестирование исключений было выполнено в стиле

старый синтаксис:

[Test]
[ExpectException(typeof(ExceptionType))] 
public void TestExceptionType()
{

}

Теперь NUnit выпустила версию 2.5.2, которая представила Assert.Throws( Type expectedExceptionType, TestDelegate code ); Это делает тестирование исключений намного более гибким. Наши тесты исключений теперь выглядят так:

новый синтаксис:

[Test]
public void TestWithNullBufferArgument()
{
   ArgumentNullException ex = Assert.Throws<ArgumentNullException>(() => _testInstance.TestFunction(null));

   // now you can examine the exception and it's properties
   Assert.AreEqual(ex.Message, "Argument was null");
}

Наша проблема в том, что если используется Assert.Throws, Visual Studio выдает окно с необработанным исключением, когда для отладки программы используется NUnit (консоль или GUI runner).

, чтобы уточнить это: мы настроили проект VS, содержащий модульные тесты, для запуска nunit-x86.exe при отладке. (См. Свойства проекта, вкладка «Отладка», запускается действие для запуска nunit-x86.exe)

Это останавливает NUnit от продолжения испытаний. Можно продолжить отладку / модульное тестирование, нажав F5, но это не является жизнеспособным решением.

Есть ли способ избежать этого? Помещение блока try ... catch вокруг Assert.Throws ничего не делает, так как исключение происходит в коде делегата.

Я надеюсь, что кто-то может пролить свет на это.

Ответы [ 4 ]

7 голосов
/ 08 февраля 2010

Сама проблема возникает потому, что, скорее всего, у вас включен параметр Включить только мой код (Сервис-> Параметры-> Отладка-> Общие-> Включить только мой код).

«Когда эта функция включена, отладчик отображает и входит только в пользовательский код (« Мой код »), игнорируя системный код и другой код, который оптимизирован или не имеет отладочных символов» (см. « Общее, Отладка, диалоговое окно "Параметры"")

Обычно у вас есть версия выпуска nunit.framework.dll, у которой нет соответствующего файла nunit.framework.pdb.

Так что есть 2 варианта:

  1. Отключить функцию «Просто мой код»

  2. Загрузите исходные коды nunit (из http://www.nunit.org/index.php?p=download), соберите их в режиме отладки, поместите все nunit.framework. * (Dll, pdb, xml) в lib или другой каталог в вашем решении и укажите ссылку на nunit .framework.dll в вашем тестовом проекте.

Надеюсь, это поможет.

2 голосов
/ 09 февраля 2010

Эта проблема также раздражала меня довольно долго, я сделал несколько тестов и обнаружил следующее:

Если библиотека (в данном случае nunit) скомпилирована с отладочной информацией, установленной в 'none', то если конструкция, подобная приведенной ниже, выполняется с библиотекой, а код делегата выдает исключение, то VS прекращает жаловаться на исключение, не обработанное по коду пользователя.

Код библиотеки:

public static Exception Throws(TestDelegate code, string message)
{
    Exception caughtException = null;

    try
    {
        code();
    }
    catch (Exception ex)
    {
        caughtException = ex;
    }        

    return caughtException;
}

Код клиента:

private void btnTest_Click(object sender, EventArgs e)
{
  var ex = MyAssert.Throws(() => { throw new Exception(); }, "");    
}

Установка отладочной информации для библиотечного проекта для любой другой опции, кроме 'none', решает проблему, т. Е. Отладчик больше не останавливается на этих «необработанных» исключениях. Я проверил его с помощью nunit и моей собственной библиотеки, созданной вручную, с помощью приведенного выше кода (взял фрагмент из метода Throws nunit). Я полагаю, что это особенность или «особенность» VS.

Это оставляет нам не так много вариантов:

  1. Исключение фильтра, как предлагалось ранее

  2. Перекомпилируйте nunit.framework.dll для локального использования, чтобы избежать этих раздражающих остановок

Другие варианты могут заключаться в том, чтобы связаться с командами MS или NUnit или с обоими и попросить их исследовать / выяснить проблему и скомпилировать NUnit с минимальным уровнем отладочной информации соответственно.

Edit:

Нашел еще один вариант.

  1. В моем случае снятие флажка «Подавить оптимизацию JIT при загрузке модуля» также помогает, даже если библиотеки скомпилированы без отладочной информации. Однако это работает только тогда, когда проект запускается в конфигурации выпуска.
1 голос
/ 05 февраля 2010

Я думаю, что вы ослеплены утверждением NUnit. Вы можете добиться того же с помощью простой попытки / улова.

try
{
  _testInstance.TestFunction(null);
  Assert.Fail("The method should have thrown...");
}catch{}

Теперь у вас есть все, что вам нужно. Вы терпите неудачу, если исключение не выдается, и ваш обычный код может обрабатывать исключения, как ожидалось.

0 голосов
/ 18 января 2010

Может ли это быть достигнуто путем отключения исключения. Откройте меню «Отладка / Исключения» и найдите исключение.

...