Конфликт NUnit с Debug.Assert - PullRequest
       13

Конфликт NUnit с Debug.Assert

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

Я использую NUnit для написания модульных тестов для библиотеки, написанной моим коллегой. Его библиотека содержит много Debug.Asserts, которые срабатывают при неверном вводе. Когда я пишу модульные тесты и передаю неверные данные в его библиотеку, его Debug.Assert выдает окно сообщения с жалобой на неправильный ввод.

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

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

Какой «лучший» подход в этом случае?

Ответы [ 3 ]

3 голосов
/ 26 февраля 2010

Взгляните на документацию MSDN для метода Debug.Assert . В частности, в разделе «Примечания» объясняется, как можно отключить пользовательский интерфейс:

<configuration>
  <system.diagnostics>
    <assert assertuienabled="false" logfilename="c:\\myFile.log" />
  </system.diagnostics>
</configuration>

Поэтому я хотел бы предложить, чтобы файл конфигурации приложения имел это по умолчанию, и ваш коллега включает Assert в UI всякий раз, когда он считает это полезным.

2 голосов
/ 12 июня 2014

Простой вариант, который я считаю эффективным, - это использовать стандартный ConsoleTraceListener , который позволит запускать проверки Debug.Assert, но будет направлять их вывод на вкладку NUnit Text Output, не влияя на юнит-тест .

Вы можете добавить это к вашей настройке теста ...

[SetUp]
public void SetUp()
{
    // Replace pop-up assert trace listener with one that simply logs a message.
    Debug.Listeners.Clear();
    Debug.Listeners.Add(new ConsoleTraceListener());
}

Только не забудьте проверить вывод текста при сбое теста!

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

Как уже отмечал Хенк, подавление пользовательского интерфейса бесполезно, потому что вы хотите, чтобы ваш код не работал. Если вы не хотите изменять свой код, вы можете написать собственный прослушиватель трассировки, который выдает исключение, следующим образом:

public class ProductionTraceListener : DefaultTraceListener
{
    public override void Fail(string message, string detailMessage)
    {
        string failMessage = message;

        if (detailMessage != null)
        {
            failMessage += " " + detailMessage;
        }

        throw new AssertionFailedException(failMessage);
    }
}

[Serializable]
public class AssertionFailedException : Exception
{
    public AssertionFailedException() { }
    public AssertionFailedException(string message) : base(message) { }
    public AssertionFailedException(string message, Exception inner) 
        : base(message, inner) { }
    protected AssertionFailedException(SerializationInfo info,
        StreamingContext context) : base(info, context) { }
}

И вы можете зарегистрировать его следующим образом:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace>
      <listeners>
        <clear />
        <add name="Default"
          type="[Namespace].ProductionTraceListener, [Assembly]" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

Как вы уже могли ожидать от имени слушателя трассировки ProductionTraceListener, я использую эту вещь в своей производственной среде (веб-приложениях), а не в своих модульных тестах. Хотя вы можете использовать этот трюк в своих модульных тестах, я советую вам изменить свой код. IMO, вы должны использовать утверждения только для путей кода, которые никогда не должны запускаться, и если они это делают, тест должен провалиться. В вашей ситуации вы хотите пройти успешный тест при неудачном утверждении, что противоречит интуиции.

Мой совет - изменить код и использовать обычные if (x) throw ArgumentException() проверки предварительных условий (или использовать CuttingEdge.Conditions ) и использовать эти утверждения только для путей кода, которые никогда не должны выполняться. Также попробуйте использовать Trace.Assert вместо Debug.Assert, поскольку вы также хотите, чтобы эти утверждения проверялись в вашей производственной среде. Когда вы это сделаете, вы можете использовать ProductionTraceListener в своей производственной среде, а этот UnitTestTraceListener в своих модульных тестах.

public class UnitTestTraceListener : DefaultTraceListener
{
    public override void Fail(string message, string detailMessage)
    {
        string failMessage = message;

        if (detailMessage != null)
        {
            failMessage += " " + detailMessage;
        }

        // Call to Assert method of used unit testing framework.
        Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail(
            failMessage);
    }
}

Удачи.

...