Подтвердить что ты не робот

XUnit Асинхронный тест не работает должным образом

Мы используем xUnit Framework в нашем проекте в качестве тестовой платформы с самого начала. В настоящее время в проекте есть 2200+ единичных тестов, и все кажется прекрасным.

Но вчера я решил запустить модульные тесты в сборках CI и ночных сборках. Борьба с контроллером сборной команды для запуска тестов xunit в течение 1-2 часов мне удастся запустить тесты. Но была проблема, там было 22 предупреждения о тестах, как показано ниже, - Xunit.Sdk.EqualException: Assert.Equal() Ошибка или - System.ArgumentNullException: значение не может быть нулевым.

После нескольких исследований я понял, что эти тесты должны быть провалены, но кажется, что они прошли, потому что все эти тесты отмечены ключевым словом "async".

На самом деле не должно быть никаких ошибок, поскольку xUnit поддерживает асинхронные тесты в отношении этих сообщений http://bradwilson.typepad.com/blog/2012/01/xunit19.html http://sravi-kiran.blogspot.com.tr/2012/11/UnitTestingAsynchronousMethodsUsingMSTestAndXUnit.html Для меня реальность Хаувервер - более легкая разница. Да xUnit работает без каких-либо проблем, но не тестируется должным образом.

Вот два небольших метода.

public async Task<string> AsyncTestMethod() {
    throw new Exception("Test");
}
public string NormalTestMethod() {
    throw new Exception("Test");
}

Как вы видите только разницу, первый метод, определяемый как "асинхронный", И вот два теста для этих методов.

  [Fact]
    public async void XunitTestMethod_Async() {
        Program p = new Program();
        string result = await p.AsyncTestMethod();
        Assert.Equal("Ok", result);
    }
        [Fact]
    public  void XunitTestMethod_Normal() {
        Program p = new Program();
        string result =  p.NormalTestMethod();
        Assert.Equal("Ok", result);
    }

Оба из исходных методов вызывают исключение, поэтому я думаю, что оба теста должны потерпеть неудачу, но результат будет иным. Вы можете увидеть результаты: Test results

XunitTestMethod_Async проходит тест, но XunitTestMethod_Normal терпит неудачу. Выбрасывание исключения не так, вы можете изменить содержание метода, которое вы хотите всегда передавать AsyncTestMethod.

Вот пример решения: https://github.com/bahadirarslan/AsyncTestWithxUnit

Я мог бы неправильно понимать или думать неправильно, но теперь это поведение вызывает много боли для меня

Надеюсь, ты можешь рассказать мне.

PS: Я создал проблему на странице xUnit github, но я не мог быть уверен, что это вызвано мной или xUnit. Поэтому я решил спросить здесь тоже. Проблема: https://github.com/xunit/xunit/issues/96

4b9b3361

Ответ 1

Проблема заключается в том, что метод async void не возвращает объект Task, который xUnit мог бы изучить для исключений. xUnit не может даже отслеживать завершение конкретного метода async void, в отличие от метода async Task.

Кроме того, методы async void не генерируют исключения в одном стеке стека даже для исключений, выведенных из синхронной части метода. Скорее, исключения распространяются на текущий контекст синхронизации через SynchronizationContext.Post (в случае SynchronizationContext.Current != null) или иначе через ThreadPool.QueueUserWorkItem. Это поведение отличается от методов async Task, более подробной информации. Можно отслеживать общее количество ожидающих методов async void (через SynchronizationContext.OperationStarted/OperationCompleted), но не отдельные методы.

Итак, изменение сигнатуры метода XunitTestMethod_Async от async void до async Task должно решить проблему.