38

Я ищу способы запуска тестовых наборов параллельно.Как запускать модульные тесты (MSTest) параллельно?

Я знаю .testrunconfig установка. Это позволяет использовать мультиплекс по количеству процессоров.

Я хочу запустить 1000 тестов параллельно. Это имеет смысл, потому что я тестирую веб-сервис, поэтому 90% времени, проведенного в тесте, ждут ответа службы.

Любые идеи о том, как это сделать? Тесты написаны для VS, но я открыт для запуска их вне VS.

Позже отредактируйте: команда тестирования Visual Studio добавила это в VS 2015 Обновление 1. См. Ответ Марк Савул ниже.

+0

Ваш разговор здесь о 1000 потоках. –

+0

Правильно, мне интересно, существует ли предварительная сборка для управления этим. Или если кто-то построит свои собственные рамки. –

+2

Вам нужен симулятор нагрузки. MSTest не предназначен для использования в качестве теста нагрузки. Кстати, 1000 потоков безумны, что вам нужно сделать, это изучить различные технологии тестирования, это выходит за рамки единичного теста. – Aren

ответ

20

Visual Studio 2015 Update 1 добавляет это. https://www.visualstudio.com/en-us/news/releasenotes/vs2015-update1-vs#a-idmisc-a-miscellaneous

Для обновления 2 на панели инструментов в верхней части панели «Проводник» (между полями «группировка» и «поиск») есть кнопка переключения пользовательского интерфейса.

Для обновления 1, установите следующие в .runsettings

<?xml version="1.0" encoding="utf-8"?> 
<RunSettings> 
    <RunConfiguration> 
    <MaxCpuCount>0</MaxCpuCount> 
    </RunConfiguration> 
</RunSettings> 

Значение для MaxCpuCount имеет следующую семантику:

• 'п' (где 1 = п < < = число ядер): начнутся процессы «n».

• «n» любого другого значения: количество запущенных процессов будет равно числу доступных ядер на машине.

+2

У нас есть тестовые DLL с сотнями тестов, некоторые из них могут работать параллельно, некоторые не могут. Есть ли способ приписывать безопасные и небезопасные тестовые классы/методы? Обычно я хочу выбрать одну или несколько из этих огромных библиотек DLL и позволить ей копировать. – GilesDMiddleton

+2

Следует иметь в виду, что параллелизм находится на уровне класса, а не на уровне теста. Я не вижу встроенного способа делать то, что вы хотите, но вы можете сделать это сами, например. с именами Mutexes в ClassInitialize/ClassCleanup. К сожалению, вы можете завершить те тесты, которые блокируют параллелизм какое-то время (например, все четыре параллельных теста - это те, которые используют мьютекс), но это так хорошо, как я думаю, вы можете получить. –

+4

Тесты распараллеливаются на уровне контейнера (в случае C#, это Assembly), поэтому он будет запускать тесты из разных сборок параллельно. Тесты в той же сборке выполняются последовательно в новой модели. – jessehouwing

27

Вы можете получить до 5 с помощью метода from the Visual Studio Team Test Blog

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

(Не знаю, почему предел 5, но MSTest не будет запускать их параллельно, если parallelTestCount установлен на более чем 5. Согласно комментариях ниже, это правило, по-видимому изменяется с Visual Studio 2013)

+0

Угу, только что обнаружил, что трудный путь :) - Я провел набор на 8 основных и все тесты были прерваны ... –

+0

Он не должен ограничиваться 5, всего 5 тестов. Комментарий Брюса Таймана: «Если эта очистка« зависает »или задерживается слишком долго, мы позволяем ей продолжать очистку, но параллельно начинаем следующий тест. Если вы достигнете 5« проверенных »тестов, мы прекратим». Прочитайте весь комментарий [здесь] (http://blogs.msdn.com/b/vstsqualitytools/archive/2009/12/01/executing-unit-tests-in-parallel-on-a-multi-cpu-core- machine.aspx # 10091555). – Anttu

+0

@Anttu Я бы хотел увидеть решение, которое настроено для запуска более 5 одновременно, и фактически оно запускает их вместо сбоев. Каждый раз, когда я пытался иметь более 5 для этого параметра, он просто терпел неудачу. Может быть, время для зависания считается слишком маленьким? Я действительно не знаю. – Rangoric

8

Что Я обнаружил, что C: \ Program Files (x86) \ Microsoft Visual Studio 11.0 \ Common7 \ IDE \ CommonExtensions \ Microsoft \ TestWindow \ vstest.console.exe проведет параллельные тесты с файлом .testsettings, который выглядит так:

<?xml version="1.0" encoding="UTF-8"?> 
<TestSettings name="TestSettings1" id="21859d0f-7bdc-4165-b9ad-05fc803c9ee9" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010"> 
    <Description>These are default test settings for a local test run.</Description> 
    <Deployment enabled="false" /> 
    <Execution parallelTestCount="8"> 
    <TestTypeSpecific> 
     <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b"> 
     <AssemblyResolution> 
      <TestDirectory useLoadContext="true" /> 
     </AssemblyResolution> 
     </UnitTestRunConfig> 
    </TestTypeSpecific> 
    <AgentRule name="Execution Agents"> 
    </AgentRule> 
    </Execution> 
</TestSettings> 

Ссылка может быть найдена здесь http://msdn.microsoft.com/en-us/library/vstudio/jj155796.aspx

+1

Он также работает, если вы используете «Test Explorer», когда в Visual Studio. Вам нужно только выбрать '.testsettings', настроенный с помощью' parallelTestCount'. Подробнее здесь: http://ardalis.com/run-your-unit-tests-in-parallel-to-maximize-performance Кстати: чтобы выбрать '.testsettings', нажмите меню' TEST' в VS 2013 затем 'Test Settings => Select Test Settings File '. –

+0

Я никогда не видел такого зверя. В 2013 году мне пришлось создать свой собственный файл настроек теста (Добавить элемент на уровне решения), а затем изменить его для параллельной поддержки в соответствии с инструкциями Игоря. –

4

Вышеуказанные ответы определенно помогли мне прояснить ситуацию, но этот пункт из блога Джона Кернера: https://johnkoerner.com/vs2015/parallel-test-execution-in-visual-studio-2015-update-1-might-not-be-what-you-expect/ был бит, который нам не хватало.

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

->" Отдельный контейнерный бит - это часть, которую я отсутствовал. Чтобы мои тесты выполнялись параллельно, мне нужно было разделить мои тесты на отдельные тестовые сборки. После этого я увидел, что тесты в разных сборках выполнялись параллельно ».

Итак, мы проверили параллельные тесты в VSTS, используя их удобный флажок« работать параллельно », но это не было достаточно, мы должны были разделить наши тесты на отдельные тестовые проекты. Логически сгруппированные конечно, не проект-за тест, который был бы смешно

0
  1. Убедитесь, что первый столбец в вашем DataTable является уникальным идентификатором.
  2. Создайте делегат AsyncExecutionTask, который принимает DataRow и ничего не возвращает.
  3. Создайте статический класс (ParallelTestin g) с методом AsyncExecutionContext, который принимает делегат DataRow и делегат AsyncExecutionTask.
  4. В статическом классе добавить статическое свойство BatchStarted.
  5. В статическом классе добавьте статическое свойство словаря AsyncExecutionTests.
  6. В методе AsyncExecutionContext добавить следующее:

    public static void AsyncExecutionContext(DataRow currentRow, AsyncExecutionTask test) 
    { 
        if(!BatchStarted) 
        { 
         foreach(DataRow row in currentRow.Table) 
         { 
          Task testTask = new Task(()=> { test.Invoke(row); }); 
          AsyncExecutionTests.Add(row[0].ToString(), testTask); 
          testTask.Start(); 
         } 
         BatchStarted = true; 
        } 
        Task currentTestTask = AsyncExecutionTests[row[0].ToString()]; 
        currentTestTask.Wait(); 
        if(currentTestTask.Exception != null) throw currentTestTask.Exception; 
    } 
    
  7. Теперь использовать класс следующим образом:

    [TestMethod] 
    public void TestMethod1() 
    { 
        ParallelTesting.AsyncExecutionContext(TestContext.DataRow, (row)=> 
         { 
          //Test Logic goes here. 
         } 
        ); 
    } 
    

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

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

Таким образом, каждый вызов тестовой среды делает TestMethod просто собирает результаты теста соответствующего теста, который уже был запущен.

Возможные улучшения:

  • Make AsyncExecutionContext принимают параметр maxSynchronousTasks.
  • Посмотрите, как фреймворк перемещает полные стеки стеков по неуправляемому коду, чтобы увидеть, может ли исключение Task.Exception в тестовую среду визуальной студии, не реконструируя и не разрушая stacktrace.
Смежные вопросы