Как я могу выделить модульные тесты по классам?

1

У меня есть несколько "единичных тестов" (они действительно интеграционные тесты) в нескольких классах, которые обращаются к общему ресурсу, и я хочу, чтобы каждый тестовый класс только один раз приобретал ресурс (по соображениям производительности).

Тем не менее, я получаю проблемы при выпуске ресурса в [ClassCleanup], потому что это не работает, пока все тесты не будут завершены.

Здесь упрощенный пример:

using Microsoft.VisualStudio.TestTools.UnitTesting;

static class State
{
    public static string Thing;
}
[TestClass]
public class ClassA
{
    [ClassInitialize]
    public static void Initialize(TestContext ctx)
    {
        State.Thing = "Hello, World!";
    }
    [ClassCleanup]
    public static void Cleanup()
    {
        State.Thing = null;
    }
    [TestMethod]
    public void TestA()
    {
        Assert.IsNotNull(State.Thing); // Verify we have a good state
    }
}
[TestClass]
public class ClassB
{
    [TestMethod]
    public void TestB()
    {
        Assert.IsNull(State.Thing); // Verify we have an uninitialized state
        // Initialize state, do stuff with it
    }
}

На моей машине, по крайней мере, TestB терпит неудачу, потому что она работает до того, как ClassA был очищен.

Я прочитал, что ClassCleanup может работать позже, чем вы думаете, но это не объясняет, как изменить поведение. И я понимаю, что я не должен зависеть от тестового заказа, но слишком дорого переустанавливать ресурс для каждого теста, поэтому я хочу сгруппировать их по классам.

Как я могу это исправить? Есть ли способ заставить каждый тестовый класс работать как единое целое и немедленно выполнить очистку?

  • 0
    Сделайте вызов внутри TestB, тогда он будет работать с отступом
  • 0
    @AmitAgrawal Что значит "сделать звонок"?
Показать ещё 6 комментариев
Теги:
mstest
visual-studio
unit-testing
integration-testing

2 ответа

0

Есть ли причина, по которой вы не можете сделать этот ресурс общим для всей сборки сразу? Сделайте его внутренней или общедоступной статической переменной в одном из тестовых классов (или отдельном назначенном классе) и обратитесь к нему непосредственно из всех тестовых классов. Инициализация ресурса будет выполняться в методе [AssemblyInitialize], и очистка будет выполняться в [AssemblyCleanup].

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

Хотя ClassCleanup может быть ненадежным с точки зрения его запуска, ClassInitialize не является; почему бы не дать каждому тестовому классу, который полагается на этот общий ресурс, ClassInitialize который очищает общий ресурс предыдущего тестового класса (если он есть), непосредственно перед приобретением самого ресурса?

Единственный раз, когда общий ресурс не был выпущен, относится к последнему тестовому классу, но вы можете справиться с этим с помощью ClassCleanup потому что тогда это не имеет значения, когда он выполняется (поскольку после него не будет больше тестовых классов).

  • 0
    Я обнаружил, что некоторые из моих тестов фактически выполняются между тестами из другого класса. Я должен был сделать эпическую гимнастику, чтобы получить временное решение для этого. Есть ли у вас какие-либо идеи о том, как заставить тесты сгруппироваться по классам? Лучшее, что я могу придумать, это заказанный тест или, возможно, создание нового проекта.
  • 0
    @KendallFrey Честно говоря, я не думал о том, что это будет смешивать тесты из разных классов тестов. Если на самом деле нет возможности разделить этот ресурс между тестовыми классами, тогда упорядоченные тесты, вероятно, будут лучшим выбором (я не думаю, что есть такая вещь, как частично упорядоченные тесты).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню