Обменивайтесь данными между сценариями specflow

В нашем приложении мне нужно открыть 3 абсолютно одинаковых документа, для каждого документа у меня есть кнопка с уникальным локатором, так как мы выполняем тесты параллельно мне нужно знать какой документ уже открыт и открыть другой который не используется, я не умеет открывать один документ параллельно. Мои сценарии должны делиться статусом того, какой документ был открыт, а какой доступен для редактирования. Можно ли обмениваться такими данными между сценариями?

Я проверил все, что было возможно IObjectContainer и было создано GlobalContainer с помощью var Container = new ContainerBuilder().CreateGlobalContainer();, но ничего не работает.

ОБНОВЛЕНИЕ:

Решение найдено, нужно передать TestThreadContext в конструктор хуков, но это сработает, только если мы будем использовать один поток:

private readonly TestThreadContext _context;

private Hooks(ScenarioContext scenarioContext, TestThreadContext context)
    {
        ScenarioContext = scenarioContext;
        _context = context;
        if (!_context.TestThreadContainer.IsRegistered<Dictionary<int, bool>>("myObject"))
            _context.TestThreadContainer.RegisterInstanceAs(MyDictionary, "myObject"); // you can register any object not only dictionary.
    }

    [BeforeScenario]
    private void BeforeScenario()
    {
        var myDictionary = _context.TestThreadContainer.Resolve<Dictionary<int, bool>>("myObject"); // to get your dictionary back from container
    }

Если вы хотите обмениваться данными между параллельными тестовыми сценариями, вы должны создать новый AppDomain в GlobalStep(SpecRun) и передать этому домену приложения свой класс с данными и методами, которые могут возвращать данные и обновлять данные, это можно сделать с помощью yourDomain.SetData("youKey", new yourClass), затем в Hooks вы должны получить свой домен (как получить требуемый домен приложения) и из домена получите свой добавленный класс var data = domain.GetData("yourKey"), а затем вы можете вызывать свои методы data.YourMethod();, также вы должны заблокировать строки внутри своих методов, чтобы быть потокобезопасными, используя lock(object) {your code}.


person Shilovskoye Moloko    schedule 28.08.2017    source источник


Ответы (2)


Я не уверен, что полностью понимаю ситуацию. Как правило, вы можете запускать тесты параллельно (с помощью SpecRun, также известного как SpecFlow+ Runner) двумя разными способами, и решение также зависит от того, какой из них вы используете.

  1. Вы можете запускать тестовые потоки в изоляции от домена приложения. В этом случае для каждого потока создается новый AppDomain. AppDomains имеют изолированную память, поэтому вы не можете создать «глобальный» словарь, доступный из всех потоков. В этом случае вы должны поделиться состоянием как-то иначе, например, создать пустые файлы во временной папке. (Вы можете назвать свои файлы на основе вашего документа, например, mydoc1.lock, и проверить наличие файла, соответственно создать/удалить файл.)

  2. Вы можете запускать тесты в том же домене приложения. (Это то, что вы можете сделать и с xunit/nunit.) В этом случае вы можете просто объявить поле static для словаря, и оно будет общим для всех потоков. (Конечно, вы должны защитить свои операции чтения/записи, потому что словарь по умолчанию не является потокобезопасным.)

person Gaspar Nagy    schedule 05.09.2017
comment
Можно обмениваться данными между доменами. Но все равно спасибо за ответ :) - person Shilovskoye Moloko; 29.09.2017

Почему бы не создать общий шаг для открытия документа с указанным идентификатором, например:

[Then(@"User opens document with ID ""(.*)""")]
public void ThenUserOpensTheDocument(string docId)
{
}

а затем вызовите его из сценария Specflow следующим образом:

User opens document with ID "1234567"

Таким образом, вы вызовете этот шаг 3 раза из разных тестовых сценариев, каждый вызов будет иметь собственный идентификатор документа.

person Koncervator    schedule 28.08.2017
comment
Поскольку мы не можем заказывать тестовые сценарии, иногда этот документ открывается дважды с одним и тем же идентификатором. - person Shilovskoye Moloko; 28.08.2017