Поддерживать контекст между методами модульного тестирования в VS Test Project - PullRequest
8 голосов
/ 12 февраля 2011

Я хочу запустить следующие юнит-тесты, по порядку:

  1. Создание нового клиента со случайным числом для имени, пароля и т. Д.
  2. Получить только что созданного клиента и утверждать, что его свойства содержат одно и то же случайное число
  3. Вызовите функцию ForgotPassword для того же пользователя, с тем же случайным числом для имени пользователя

Как видно, мне нужно сгенерировать случайное число один раз и разделить его на 3 метода теста.
Я не могу найти способ сделать это.

  • Я думал об использовании объекта TestContext, но он создается для каждого экземпляра.
  • Я пытался использовать метод ClassInitialize (), это не помогает, так как он статический, и поэтому число недоступно для других методов.

Есть идеи, как достичь моей цели?

Ответы [ 4 ]

10 голосов
/ 12 февраля 2011

Можете ли вы просто разместить ваши общие данные в статических переменных?

Что-то простое, как это:

    private static string testValue = "something";

    [TestMethod]
    public void TestMethod1()
    {
        Assert.AreEqual(testValue, "something");
        testValue = "something2";
    }

    [TestMethod]
    public void TestMethod2()
    {
        Assert.AreEqual(testValue, "something2");
        testValue = "something3";
    }

    [TestMethod]
    public void TestMethod3()
    {
        Assert.AreEqual(testValue, "something3");
    }

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

3 голосов
/ 12 февраля 2011

Что вы хотите сделать здесь, это использовать что-то вроде репозитория за интерфейсом IRepository:

interface IRepository{
    Customer GetCustomer(int id);
}

Вы можете реализовать в своем коде реальный класс, который будет запрашивать базу данных, но в своих тестах вы можете «макетировать» этот интерфейс, чтобы получить именно то, что вы хотите. Moq - мой любимый, а далее псевдокод, но, надеюсь, вы поймете:

[Test]
public void Customer_Should_Have_CreateAt_Set_To_Today{
  var mock = new Mock<IRepository>();
  mock.Setup(x => x.GetCustomer(100)).Returns(new Customer{id = 100, Name = "Steve"});

  var Customer = mock.Object;
  Assert.Equal(Customer.CreatedAt,Date.Today);
}

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

2 голосов
/ 12 февраля 2011

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

Если кто-то запустит ваши тесты в другом порядке или изолированно, он потерпит неудачу. Такие тесты называются flakey - они проходят иногда, но не другие - и не понятно почему.

Гораздо лучше использовать фреймворк, такой как Rhino Mocks , для создания экземпляров макетных зависимостей в нужном вам состоянии. Таким образом, каждый тест является отдельным тестом, который проверяет конкретную вещь без ссылки на какие-либо другие тесты.

Вам будет намного проще поддерживать подобные тесты, и в ваших результатах будет меньше ложных и отрицательных результатов.

0 голосов
/ 02 октября 2013

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

То, что вы пытаетесь сделать, не является модульным тестом. Это функциональный тест. И вам не нужно делиться значениями между методами тестирования, чтобы выполнить задачу с точки зрения пользователя.

...