MSTest и домены приложений

В каком-то моем проекте я заметил, что во время выполнения модульных тестов под VSTS2008 его потребление памяти VSTestHost растет. Поскольку в моем решении очень много тестов, это в конечном итоге приводит к OutOfMemroyException. Для меня это выглядит очень странно, поскольку я был уверен, что MSTest создает новый AppDomain для каждого модульного теста. Иначе как бы он сбросил статические поля? Но если AppDomain создается для каждого теста, то утечки памяти не должно быть. Но это так.

Возникает вопрос: должна ли VS создавать AppDomain для каждого тестового класса или нет? Если да, то как я могу проверить, что он это делает. Я пробовал отслеживать через ProcessExpolorer и оснастку «Производительность». Значение «Всего выгруженного домена приложения» всегда равно 0 во время тестового запуска.

У меня такая же проблема. Не стало ли это «вашей проблемой», как, казалось, говорили респонденты? Или на самом деле это был тестовый раннер? Мне любопытно.

Peter Seale 24.02.2011 20:32

Я нашел social.msdn.microsoft.com/Forums/en-US/vststest/thread/… и social.msdn.microsoft.com/Forums/en-US/vststest/thread/… - мне кажется, что те немногие из нас, кто создал большой набор тестов, сталкиваются с этой проблемой.

Peter Seale 25.02.2011 22:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
2
7 528
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Я не думаю, что движок модульного тестирования создает новый домен приложений для каждого теста. Поскольку создание AppDomain - относительно дорогая операция, выполнение этого для каждого теста значительно замедлит выполнение модульных тестов!

Visual Studio 2008 использует отдельный исполняемый файл vstesthost.exe для запуска модульных тестов. VS связывается с vstesthost.exe (я не знаю, как это происходит), чтобы сообщить ему, какие тесты запускать. vstesthost.exe возвращает результаты выполнения в VS, который отображает эти результаты.

Если вы получаете OutOfMemoryExceptions при запуске модульных тестов, я бы сказал, что это сильный индикатор того, что ваш тестируемый код на самом деле не очищает вещи. Вы уверены, что не сохраняете дескрипторы неуправляемых объектов / памяти? Я бы рекомендовал запускать ваши модульные тесты в рамках анализа производительности (вы можете сделать это, найдя модульный тест в «Test View», щелкнув его правой кнопкой мыши и выбрав «Create Performance Session»). Это может пролить свет, по крайней мере, на распределение ваших объектов.

Я ошибался, имея отдельные домены приложений для каждого модульного теста.

Вот доказательства: синглтон

public class Singleton
{
    public static Singleton Instance = new Singleton();

    private Guid _token;
    private Singleton()
    {
        _token = Guid.NewGuid();
    }

    public Guid Token
    {
        get { return _token; }
    }
}

и два теста:

[TestClass]
public class UnitTest2
{
    [TestMethod]
    public void TestMethod1()
    {
        Console.WriteLine(Singleton.Instance.Token);
    }
}
[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Console.WriteLine(Singleton.Instance.Token);
    }
}

При выполнении обоих тестов выводится один и тот же guid.

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

Если вы видите утечки, вероятно, это ошибка либо в вашем тестовом коде, либо в вашем коде продукта. Убедитесь, что вы не запихиваете вещи в словари и не оставляете их там.

+1, домен приложения для каждой сборки. Но - он также создает новый экземпляр тестового класса для каждого теста, поэтому он должен фактически собирать поля. У меня также есть проблемы с памятью при тестировании MS, и я не знаю, почему. Думаю, в тестовом раннер есть какие-то проблемы.

Stefan Steinegger 26.04.2010 19:08

+1 к экземпляру тестового класса за тест. [ClassInitialize] статичен.

bryanbcook 09.01.2011 19:12

Наблюдал такую ​​же проблему при больших тестовых прогонах. Моя теория следующая. Исчерпание памяти в этом случае связано с тем, что файлы результатов теста MSTest представляют собой XML. Поэтому ему необходимо хранить все результаты журнала в памяти до конца тестового прогона перед сериализацией на диск. Ура XML :-)

Я опубликовал эту проблему как проблема подключения некоторое время назад, и она должна была быть исправлена ​​в MSTest 10 (переход на 64-разрядную версию), но я еще не смог проверить это из-за всех других проблем, которые мы переносим на VS2010 и .NET. 4.0.

Кажется, это не решено в MSTest 2010. Я испытываю множество подобных проблем. Почему сборка мусора не работает в модульном тесте?

Насколько я понимаю, структура UT позаботилась об удалении всех выполненных тестов, но, похоже, это не относится к некоторым одноэлементным шаблонам, которые у нас есть в коде.

Единственный способ избавиться от синглтона - это удалить appDomain. Синглтон - это статическая привязка к самому себе, поэтому в основном это круговая ссылка. Истинные синглтоны не удаляются, пока домен приложения не исчезнет.

Другие вопросы по теме