Как я могу запускать тесты NUnit параллельно?

83

У меня есть большой приемочный тест (~ 10 секунд на тест), написанный с использованием NUnit. Я хотел бы использовать тот факт, что все мои машины представляют собой несколько стержневых ящиков. В идеале у меня будет возможность запускать один тест на ядро, независимо от других тестов.

Существует PNUnit, но он предназначен для тестирования проблем с синхронизацией потоков и тому подобного, и я не видел очевидного способа сделать это.

Есть ли переключатель / инструмент / параметр, который я могу использовать для параллельного запуска тестов?

Билли Онил
источник
Даже хотелось бы узнать об этом побольше. @ Билли Онил, пожалуйста, напишите ответ, если найдете его.
PK
Вы говорите десять секунд на тест и, в идеале, один тест на ядро. Насколько интенсивны тесты для ЦП? В противном случае возможно одновременное выполнение многих других.
Маттиас Нильссон
@Mattias: Да, тесты загружают процессор.
Билли Онил,

Ответы:

52

Если вы хотите запускать тесты NUnit параллельно, есть как минимум 2 варианта:

  • NCrunch предлагает его из коробки (ничего не меняя, но это коммерческий продукт)
  • NUnit 3 предлагает атрибут Parallelizable , который можно использовать для обозначения того, какие тесты можно запускать параллельно.
David_001
источник
Этот ответ кажется неправильным, учитывая вопрос, скорее хорошим предложением, чем истинным ответом. На мой взгляд, NCrunch нуждается в ваших голосах за и должен быть лучшим ответом, поскольку он может запускать (NUnit) тесты одновременно в одном или нескольких процессах и на одной или нескольких машинах и будет делать это из VS или с сервера сборки.
chillitom
2
@chillitom NCrunch был выпущен после того, как был дан ответ на этот вопрос, и это хороший выбор (так как это должно работать сразу из коробки, хотя для некоторых это слишком дорого). Другие варианты в будущем могут включать NUnit 3, который может предлагать параллельное выполнение тестов (согласно github.com/nunit/dev/wiki/Roadmap ).
David_001
3
Хотя это главный ответ, он уже не так верен, как раньше. Nunit 3.0 был выпущен в конце 2015 года и теперь имеет атрибут Parallelizable. Ссылка: github.com/nunit/nunit/wiki/Parallelizable-Attribute
pb.
36

NUnit версии 3 будет поддерживать параллельное выполнение тестов:

Добавление атрибута в класс: [Parallelizable(ParallelScope.Self)]запустит ваши тесты параллельно.

• ParallelScope.None указывает, что тест нельзя запускать параллельно с другими тестами.

• ParallelScope.Self указывает, что сам тест может выполняться параллельно с другими тестами.

• ParallelScope.Children указывает, что потомки теста могут выполняться параллельно друг другу.

• ParallelScope.Fixtures указывает, что приборы могут работать параллельно друг с другом.

NUnit Framework-Параллельное-Тест-Выполнение

Питер
источник
10

Если ваш проект содержит несколько тестовых DLL, вы можете запускать их параллельно с помощью этого сценария MSBuild. Очевидно, вам нужно настроить пути в соответствии с макетом вашего проекта.

Для работы с 8 ядрами запустите: c:\proj> msbuild /m:8 RunTests.xml

RunTests.xml

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="RunTestsInParallel" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
    <Nunit Condition=" '$(Nunit)' == '' ">$(MSBuildProjectDirectory)\..\tools\nunit-console-x86.exe</Nunit>
  </PropertyGroup>

  <!-- see http://mikefourie.wordpress.com/2010/12/04/running-targets-in-parallel-in-msbuild/ -->

  <Target Name="RunTestsInParallel">
    <ItemGroup> 
      <TestDlls Include="..\bin\Tests\$(Configuration)\*.Tests.dll" />
    </ItemGroup>

    <ItemGroup> 
      <TempProjects Include="$(MSBuildProjectFile)" > 
        <Properties>TestDllFile=%(TestDlls.FullPath)</Properties> 
      </TempProjects> 
    </ItemGroup> 

    <MSBuild Projects="@(TempProjects)" BuildInParallel="true" Targets="RunOneTestDll" /> 
  </Target>

  <Target Name="RunOneTestDll"> 
    <Message Text="$(TestDllFile)" />
    <Exec Command="$(Nunit) /exclude=Integration $(TestDllFile)  /labels /xml:$(TestDllFile).results.xml"
      WorkingDirectory="$(MSBuildProjectDirectory)\..\bin\Tests\$(Configuration)" /> 
  </Target>

</Project>

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

чиллитом
источник
1
Это помогло мне сократить время выполнения модульных тестов с 3 до 2 минут. Тестировал на 2-ядерном процессоре.
Дмитрий Лобанов
4

В этой статье упоминается, что для ускорения тестов плакат запускает несколько экземпляров NUnit с параметрами команды, определяющими, какие тесты должен запускать каждый экземпляр.

FTA:

Я столкнулся с странной проблемой.

Мы используем nunit-console для запуска теста на нашем сервере непрерывной интеграции. Недавно мы перешли с Nunit 2.4.8 на 2.5.5 и с .Net 3.5 на 4.0. Чтобы ускорить выполнение теста, мы запускаем несколько экземпляров Nunit параллельно с разными аргументами командной строки.

  • У нас есть две копии наших тестовых сборок и двоичные файлы nunit в папках A и B.
  • В папке A выполняем

nunit-console-x86.exe Model.dll Test.dll / exclude: MyCategory /xml=TestResults.xml /framework=net-4.0 / noshadow

  • В папке B выполняем

nunit-console-x86.exe Model.dll Test.dll / включает: MyCategory /xml=TestResults.xml /framework=net-4.0 / noshadow

Если мы выполним команды последовательно, оба будут успешно выполнены. Но если мы выполняем их параллельно, только один добьется успеха. Насколько я могу судить, это тот, который первым загружает тестовые приборы. Другой выдает сообщение «Невозможно найти прибор».

Эта проблема уже известна? Я не смог найти ничего связанного в списке ошибок на панели запуска. Кстати, наш сервер работает под управлением 64-разрядной версии Windows Server 2008. Я также мог воспроизвести проблему на 64-битной Windows 7.

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

Обновить

TeamCity выглядит как инструмент, который можно использовать для автоматического запуска тестов NUnit. Здесь обсуждается средство запуска NUnit, которое можно использовать для запуска нескольких экземпляров NUnit. Вот сообщение в блоге, в котором обсуждается объединение нескольких результатов NUnit XML в один файл результатов.

Таким образом, теоретически вы можете заставить TeamCity автоматически запускать несколько тестов NUnit в зависимости от того, хотите ли вы разделить рабочую нагрузку, а затем объединить результаты в один файл для обработки после тестирования.

Достаточно ли это автоматизировано для ваших нужд?

Kniemczak
источник
Это та же идея, о которой уже писали о категориях ... Я не хочу, чтобы здесь поддерживались достаточно равные времена выполнения между экземплярами. Я лучше напишу свой собственный бегун NUnit, прежде чем делать это.
Билли Онил
Насколько мне известно, NUnit не поддерживает это без обходного пути, такого как запуск нескольких экземпляров. Если вы хотите, я думаю, вы можете создать инструмент, который разбивает тесты на N наборов и автоматически запускает N экземпляров NUnit, где N - количество процессоров / ядер, которые у вас есть. Это был бы единственный способ иметь какое-то автоматическое параллельное тестирование, которое я могу придумать с помощью NUnit.
kniemczak
Я добавил обновление, посвященное инструменту непрерывной интеграции TeamCity, и включил несколько сообщений о том, как использовать этот инструмент для решения ваших задач автоматизации.
kniemczak
3

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

Кстати, у меня нет времени читать весь их источник, но мне было любопытно проверить класс Barrier, и это очень простой счетчик блокировок. Он просто ждет, пока войдут N потоков, а затем отправляет импульс, чтобы все они продолжали работать одновременно. Вот и все - если вы не прикоснетесь к нему, он вас не укусит.

Может быть немного противоречиво интуитивно понятно для нормальной многопоточной разработки (блокировки обычно используются для сериализации доступа - 1 на 1), но это довольно энергичное отклонение :-)

ZXX
источник
3

Теперь вы можете использовать NCrunch для распараллеливания модульных тестов, и вы даже можете настроить, сколько ядер должно использоваться NCrunch, а сколько должно использоваться Visual Studio.

плюс непрерывное тестирование в качестве бонуса :)

Рикард
источник
3
NCrunch хорош, когда вы используете его в Visual Studio, но он не помогает, когда вы пытаетесь распараллелить тесты на своем сервере сборки.
Paccc
3
NCrunch теперь имеет инструмент командной строки, который действительно хорошо работает на серверах сборки.
chillitom
3

В качестве альтернативы добавлению атрибута Parallelizable в каждый тестовый класс:

Добавьте это в класс AssemblyInfo.cs тестового проекта для nunit3 или выше:

// Make all tests in the test assembly run in parallel
[assembly: Parallelizable(ParallelScope.Fixtures)]
Том Редферн
источник
2

Это было бы немного похоже на взлом, но вы можете разделить модульные тесты на несколько категорий . Затем запустите новый экземпляр NUnit для каждой категории.

Изменить: похоже, что они добавили параметр / process в консольное приложение. В справке командной строки указано, что это «Модель процесса для тестов: одиночный, отдельный, множественный». У тестового раннера также есть эта функция.

Изменить 2: К сожалению, хотя он создает отдельные процессы для каждой сборки, параметр изоляции процесса (/ process из командной строки) запускает агенты по одному.

Педро
источник
2

Поскольку этот проект здесь не упоминался, я хотел бы упомянуть NUnit.Multicore . Сам я не пробовал этот проект, но, похоже, у него интересный подход к проблеме параллельного тестирования с NUnit.

тронда
источник
2

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

TBox создан для упрощения работы с большими решениями, в которые входит множество проектов. Он поддерживает множество плагинов, и один из них позволяет запускать тесты NUnit параллельно. Этот плагин не требует никаких изменений в ваших существующих тестах.

Также он поддерживает:

  • Клонирование папки с модульным тестом (если ваши тесты изменяют локальные данные),

  • Синхронизация тестов (например, если ваши тесты на testfixtureteardown убивают все серверы разработчиков или chromerunner для qunit)

  • Режим x86 и права администратора для запуска тестов

  • Пакетный запуск - вы можете запускать тесты для многих сборок параллельно

  • Даже для однопоточного запуска работает быстрее, чем стандартный nunit runner, если у вас много небольших тестов.

Также этот инструмент поддерживает запуск тестов командной строки (для параллельного запуска), и вы можете использовать его с непрерывной интеграцией.

Alex H
источник
Если вы связаны с этим продуктом, сообщите об этом. Вы опубликовали несколько вещей, указывающих на это.
Брэд Ларсон
Конечно, TBox - это мой собственный инструмент. Я написал это в свободное время в одиночестве. Если здесь говорить о бесплатных инструментах - плохая практика, я удалю этот ответ, это не проблема :)
Alex H
Мы просто хотим, чтобы люди четко понимали, какие продукты они создают. Если вы полностью раскроете, что это ваш вопрос, почему было бы уместно решить проблему, поставленную вопросом, и не продвигайте его слишком агрессивно, ваши ответы здесь должны быть приемлемыми.
Брэд Ларсон
@brad Это открытый исходный код на Codeplex, не знаю, почему здесь проблема.
dvallejo
@DanVallejo - проект с открытым исходным кодом - причина, по которой он не был удален сообществом при публикации. Мы даем немного больше свободы действий, но все же просим вас раскрыть свою принадлежность к проекту, чтобы люди могли понять контекст вашей рекомендации. Алекс сделал это здесь, поэтому его ответ в нынешнем виде прекрасен.
Брэд Ларсон
1

Я успешно использовал NUnit 3.0.0 beta-4 для параллельного запуска тестов

  • Работает на сервере сборки
  • Выполняет тесты Selenium
  • Имеет поддержку Visual Studio
  • пока нет поддержки Resharper

Спасибо за ответ коллег .

Попадания:

  • Атрибут Parallelizable не наследуется, поэтому его необходимо указать в тестовом классе.
Алвис
источник
1
NUnit 3.0 уже вышел
Ральф Уиллгосс
0

Вы можете использовать следующую команду PowerShell (для NUnit3, для NUnit2 изменить имя бегуна):

PS> nunit3-console (ls -r *\bin\Debug\*.Tests.dll | % FullName | sort-object -Unique)

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

Замечания

  1. Не забудьте настроить шаблон поиска в каталоге. В данном примере выполняются только сборки, заканчивающиеся на каталоги .Tests.dllи внутри них \bin\Debug.

  2. Помните о Uniqueфильтрации - вы можете не захотеть ее иметь.

one_mile_run
источник