Дебаг ошибки «The agent process was stopped while the test was running»

Дебаг

Недавно я пару раз столкнулся с бесполезным результатом ошибки MSTest «The agent process was stopped while the test was running», и подумал что надо поделиться несколькими моими открытиями и подходами к дебагу юнит тестов которые ее вызывают.

«Error» результат MSTest

По моему опыту, Error result обычно гласит об одной из двух причин:

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

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

Просмотр информации об ошибках запуска теста

Результаты ошибок как правило представлены в окне Test Results следующим образом:

Окно Test Results с результатами ошибок  Дебаг ошибки The agent process was stopped while the test was running

Примечание: как вы видите я сгруппировал тесты по их результатам — это мой предпочитаемый подход к просмотру юнит тестов в этом окне.

Когда результаты тестов содержат ошибку, вы можете получить больше деталей нажав на ссылку «Test run error». Это покажет детали ошибки для каждого теста который закончился ошибкой, и может дать вам достаточно информации что бы решить проблему:

Детали ошибки запуска теста  Дебаг ошибки The agent process was stopped while the test was running

 Тут вы можете увидеть что ошибка в фоновом потоке свалила тест. Если вам повезет, то это окно должно дать достаточно информации что бы решить вашу проблему.

Фоновые потоки

Важно упомянуть, что если ваш код использует фоновые потоки существующие  за пределами жизненного цикла теста, то исключение сгенерированное  в этом потоке может привести к обнаружении ошибки уже в следующем тесте!

Рассмотрите эти примеры:

[TestMethod]
public void BadBackgroundTestCausingDelayedError()
{
    // Создаем другой поток и запускаем его - этот тест пройдет,
    // но исключение сгенерированное потоком приведет к провалу ДРУГОГО теста.
    var thread = new Thread(() =>
        {
            DoSomething();
        });
    thread.Start();
}
[TestMethod]
public void GoodTest1()
{
    // Притворяемся что делаем какую то работу
    Thread.Sleep(2000);
}
private void DoSomething()
{
    throw new Exception("I'm sorry Dave, you can't do that.");
}

Если запустить тесты по порядку, то вы увидите это в результатах теста:

Результаты запуска тестов с исключением в фоновом потоке  Дебаг ошибки The agent process was stopped while the test was running

Ох, ах. Тест который не сделал ничего плохого был обвинен в провале плохого теста. Взгляд на репорт запуска тестов в этом случае немного поможет — стек вызовов выглядит примерно так:

One of the background threads threw exception: 
System.Exception: I'm sorry Dave, you can't do that.
   at TestProject1.UnitTest1.DoSomething() in UnitTest1.cs:line 56
   at TestProject1.UnitTest1.<BadBackgroundTestCausingDelayedError>b__0() in UnitTest1.cs:line 20
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Если посмотреть внимательно, то можно увидеть некоторые признаки теста из которого происходит исключение.

Отсутствие стека вызовов в окне результатов

Не всегда из стека вызовов можно определить тест лежащий в корне этой проблемы. Кроме того, временами вы вообще не получите какой либо информации о стеке вызовов, например:

Результат запуска тестов без стека вызовов  Дебаг ошибки The agent process was stopped while the test was running

Я определил, что обычно такое случается потому что исключение, генерируемое в другом потоке, является специальным исключением, и тестовый фреймворк не способен десериализовать его в AppDomain теста. Если покопать в выводе дебага, то можно найти детали исключения, которые индицируют это:

E, 1020, 17, 2011/04/25, 22:34:14.366, MGLAPTOP\QTAgent32.exe, 
    Unhandled Exception Caught, reporting through Watson: 
    System.Runtime.Serialization.SerializationException: 
    Unable to find assembly 'TestProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
   at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
   ...
   at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm)
   at System.AppDomain.Deserialize(Byte[] blob)
   at System.AppDomain.UnmarshalObject(Byte[] blob)
The program '[1020] QTAgent32.exe: Program Trace' has exited with code 0 (0x0).

The program '[1020] QTAgent32.exe: Managed (v4.0.30319)' has exited with code -2 (0xfffffffe).

Дебаг тестов

Если вы еще не добрались до дна ошибки теста, то всегда можно продебажить тесты. Перед началом дебага, убедитесь что вы отлавливаете все исключения из меню Debug/Exceptions (или Ctrl-Alt-E):

Окно Exceptions в Visual Studio  Дебаг ошибки The agent process was stopped while the test was running

Надеюсь эти подсказки помогут вам определить причины ошибок ваших юнит тестов — удачи!

Источник: http://www.goatly.net/2011/4/25/debugging-the-agent-process-was-stopped-while-the-test-was-running.aspx

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>