Nunit: Параллельное выполнение методов тестирования в приспособлении

Созданный на 5 авг. 2014  ·  76Комментарии  ·  Источник: nunit/nunit

В настоящее время мы реализовали параллельное выполнение только на уровне фикстур. Должна быть возможность запускать отдельные методы фикстуры параллельно, а также отдельные тестовые примеры для параметризованного метода.

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

Эта проблема ранее входила в состав # 66.

done hardfix feature high

Самый полезный комментарий

Хотя я могу делать вид, что предсказываю будущее, это удовлетворит вас только до сентября. :-)

Позвольте мне ответить, объяснив, как мы «планируем» функции.

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

В добровольном проекте с открытым исходным кодом нет фиксированного количества усилий в месяц. Мы можем использовать подход «вчерашняя погода», но оказывается, что количество времени, которое люди тратят на NUnit, а также количество людей, участвующих в волонтерской работе, весьма различны.

В качестве компромисса мы выбираем небольшое количество проблем, которые являются ключевыми для выпуска, и заранее добавляем их к этапу. Я предпочитаю добавлять не более 25% того, что мы можем надеяться сделать. Большинство проблем в выпуске добавляются к этому этапу только после того, как они решены, или, в лучшем случае, когда кто-то соглашается работать над ними. Как правило, вы не найдете открытых проблем в нашей вехе 3.5 без назначенного им человека, хотя я делаю это время от времени, если кажется, что что-то блокирует другую работу.

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

Что касается этой конкретной проблемы ... Я уделил ей первоочередное внимание, чтобы сказать нашим разработчикам, что это важно. Кто-то должен быть свободен, чтобы работать над этим, и иметь достаточно опыта для проекта такого масштаба и сложности. Если кто-то с правильным опытом поднимет это в ближайшие несколько недель, я думаю, что это может быть сделано к выпуску. В качестве ориентира, я думаю, что мне понадобится около месяца, работая над некоторыми другими вещами, чтобы разобраться с этим.

Извините, более однозначного ответа нет, но такой ответ обязательно будет ложью!

Все 76 Комментарий

Обновление: и этот комментарий, и следующий были даны в ответ человеку, который, по-видимому, удалил свои собственные комментарии. Я оставляю свои ответы.

Ну, это в спецификации и запланировано для реализации после версии 3.0. Если бы это было так просто, наверное, мы бы это сделали. Не уверен, какое соединение вы видите с mbunit. Тот факт, что он у них был, нам не помогает.

Это становится немного утомительно. Несколько моментов, уже заявленных, но явно упущенных ...

  1. Есть план реализовать то, о чем вы просите.
  2. Мы решили, как команда, запланировать его на определенный момент.
  3. Когда это запланировано, это в первую очередь связано с нашей оценкой ценности функции по сравнению с другими функциями.
  4. В команде NUnit есть несколько человек, которые могли бы реализовать эту функцию.
  5. Они могли бы реализовать это, в зависимости от приоритетов, из головы, и им не нужно было бы копировать его откуда-либо.

Я нахожу ваш разговор о «обратной инженерии» очень тревожным. Открытый исходный код возможен только в контексте соблюдения авторских прав. Так что, если вы предлагаете, чтобы мы могли проигнорировать условия лицензирования mbunit, вы ошибаетесь.

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

Что касается реверс-инжиниринга, то здесь толку нет. NUnit работает
полностью отличается от того, что сделал MbUnit. Мы займемся этим вопросом в свое время,
но подходим к этому осторожно, потому что другие похожие проблемы могут измениться
способ реализации этого или даже конфликт.
19 апреля 2015 г., 2:45, "CharliePoole" [email protected] написал:

Это становится немного утомительно. Несколько моментов, о которых уже говорилось, но
видимо пропустил ...

1.

Есть план реализовать то, о чем вы просите.
2.

Мы решили, как команда, запланировать его на определенный момент.
3.

Когда это запланировано, это в первую очередь связано с нашей оценкой
ценность функции по сравнению с другими функциями.
4.

В команде NUnit есть несколько человек, которые могли бы реализовать
характерная черта.
5.

Они могли бы реализовать это, в зависимости от приоритетов, вне
их головы и не нужно было бы копировать его откуда-либо.

Я нахожу ваш разговор о «обратной инженерии» очень тревожным. Открытый исходный код
возможно только в контексте соблюдения авторских прав. Так что если ты
предполагая, что мы можем игнорировать условия лицензирования mbunit, вы ошибаетесь
база.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/nunit/nunit/issues/164#issuecomment -94244650.

Гораздо более тактичный комментарий, чем мой!

Наши текущие приоритеты в мире параллельного выполнения:

  1. Параллельное выполнение процесса
  2. Группы исключения
  3. Параллельное исполнение (в одном приспособлении).

Это, кажется, представляет собой порядок наибольшей полезности для пользователей.

Я также упомяну, что пометка чего-либо как post-3.0 не обязательно означает, что функция появится позже, чем если бы мы сделали ее частью 3.0. Скорее, это может означать, что 3.0 появится раньше.

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

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

Привет!
Добавление этой функции в следующую версию NUnit было бы замечательно, поскольку это единственное, что мешает мне перейти на NUnit. Планируется ли эта функция еще в 3.4?

@julianhaslinger NUnit 3.4 выйдет в конце месяца, поэтому нет, эта функция не будет включена.

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

Следующая веха, 3.6, упадет еще через 3 месяца, что, вероятно, вас обескураживает. :-( Однако, если вы видите, что эта проблема объединяется с мастером, вы сможете получить более раннее удаление из нашей ленты MyGet.

@julianhaslinger этого не будет в 3.4, которая, вероятно, выйдет чуть более чем через неделю, но я бы хотел, чтобы это было сделано в ближайшее время, поэтому ваш голос помогает: +1:

Кроме того, какую среду тестирования вы используете, которая поддерживает выполнение параллельных методов? Я думал, что XUnit позволяет запускать тесты параллельно только до уровня класса . Я ошибаюсь? Я мало использую XUnit: smile:

@CharliePoole Спасибо за ответ! Хорошо, хотя это звучит немного обескураживающе. Однако я буду ждать следующих релизов (или более ранних выпусков). Пожалуйста (все же) рассмотрите эту возможность в следующей версии (3.6).

@rprouse Я сейчас использую MbUnit / Gallio. Проект практически умер, и теперь я перейду на NUnit.

@julianhaslinger Для вас вопрос времени? Есть ли у вас какие-то цифры по распределению тестовых примеров внутри фикстур? Я спрашиваю, потому что предполагал, что эта функция мало что дает пользователям, кроме того, что они получают от параллельных устройств. Если это не так, он может изменить свой относительный приоритет.

@CharliePoole Точно, наша актуальная проблема - время выполнения тестовых примеров. Мы хотели бы использовать NUnit для наших автоматических / регрессионных тестов (включая Selenium / WebDriver), и поскольку некоторые из наших тестовых классов имеют более 200 тестовых примеров, в настоящее время очень сложно выполнить весь набор тестов с NUnit.

Сравнения (в рамках меньшего набора наших регрессионных тестов) показали, что возможное решение NUnit будет выполнено примерно за 1,5 часа, тогда как текущее решение MBunit будет выполнено за 0,5 часа (тот же набор тестов).

Тем не менее, @CharliePoole , я знаю, что мы могли бы сократить время выполнения, разделив большие тестовые классы на более мелкие, но это каким-то образом подорвало бы первоначальную идею нашей иерархии тестовых классов.

@julianhaslinger - Просто чтобы подтвердить, вы уверены, что время работы ограничено процессором, а не памятью?

Мы столкнулись с той же проблемой, когда впервые попытались перейти на NUnit 3 - время выполнения стало значительно больше. Однако это произошло из-за того, что NUnit исчерпал доступную память - есть проблема с текущей версией, которая удерживает все тестовые объекты до завершения тестового запуска. В настоящее время мы запускаем внутреннюю версию с исправлениями - я хотел получить PR для 3.4, но не уверен, что на этом этапе у меня будет время. :-(

Извините, если это не так, но подумал, что об этом стоит упомянуть, поскольку Selenium может использовать свою долю памяти. :-)

@ChrisMaddock Спасибо за вклад! : +1: Мы скоро его посмотрим, и тогда я еще вернусь к вам.

@ChrisMaddock Я бы хотел увидеть ваше исправление памяти в 3.4. Если вы хотите разместить PR, мы можем помочь вам очистить его, если он еще не готов к производству: +1:

@rprouse - Эта первоначальная фиксация https://github.com/nunit/nunit/pull/1367/commit/5f98ae51025f7af8244abd4367d1f47260874dfc в PR # 1367 освобождает нас должным образом в исправленной версии 3.0.1.

В PR вы увидите, что перед слиянием он был перемещен в OneTimeTearDown - я еще не знаю, вызвало ли это движение его неработоспособность в v3.2.1, или было другое работающее изменение, которое повторно ввело удержание - возможно, я не перепроверил после переезда.

Попробую еще раз протестировать и бросить завтра, было бы здорово вернуться и к основным выпускам. :-)

@ChrisMaddock Я посмотрел на потребление памяти во время прогона регрессионного теста и обнаружил, что выполнение тестовых прогонов не связано с памятью. Думаю, нам действительно нужно дождаться версии NUnit, которая сможет обрабатывать параллельное выполнение отдельных методов внутри каждого класса.

просто чтобы добавить к тому, что сказал @julianhaslinger , я видел точно такую ​​же проблему при использовании NUnit с тестами Selenium. Мне пришлось написать настраиваемую оболочку, которая запускает отдельные экземпляры nunit-console.exe для одного теста, взятого из переданной сборки, чтобы я мог запускать параллельные тесты на данный момент. Это не идеально, потому что в результате создается много выходных файлов .xml (по одному для каждого тестового запуска), а не один выходной XML-файл, а также это означает, что я не могу использовать методы _OneTimeSetUp_ и teardown и вместо этого должен полагаться на внешние семафоры. и переменные среды для управления потоком выполнения, когда я хочу запускать только один раз. Я следил за обещанием иметь параллельное выполнение в NUnit в течение долгого времени (годы) и был очень разочарован тем, как эта функция была развернута в версии 3.0 (поддерживается только частично и требует некоторого реального покопания в проблемах и примечаниях к выпуску, чтобы обнаружил, что не все на самом деле поддерживалось). Я даже зашел так далеко, что сам исследовал, что будет вовлечено в продвижение этого вперед, но, к сожалению, похоже, что дизайн NUnit работает против реализации параллельного выполнения на уровне метода тестирования, я понятия не имею, как вы на самом деле хотели бы для обработки потенциала небезопасного для потоков кода (то есть следует оставить это человеку, использующему NUnit параллельно, чтобы гарантировать, что все методы тестирования правильно ссылаются на любые внешние элементы потокобезопасным способом, или должен сам NUnit обрабатывать выполнение каждого метода в своем собственном домене, пока каким-то образом пытаясь по-прежнему запускать методы типа одноразовой установки и разрыва только один раз), и, поскольку у меня уже есть обходной путь, я не мог оправдать время на реализацию этой функции самостоятельно (что, вероятно, к лучшему, потому что я был сожжен раньше, когда работа с командами на GitHub, чтобы помочь им реализовать параллельное выполнение). В любом случае ... извините за бессвязный разговор ... Я понимаю, что приоритет для модульного тестирования кода C #, вероятно, не так сильно зависит от параллелизма на уровне методов, но, пожалуйста, знайте, что для тех из нас, кто использует NUnit для тестов на основе Selenium это было бы ОГРОМНОЕ улучшение. Заранее спасибо! :улыбка:

Спасибо за ваши комментарии. Думаю, я тут немного поболтаю ...

Это помогает понять, что нужно людям и зачем им это нужно. Не будучи веб-разработчиком, я старался прислушиваться к мнению пользователей Selenium и сосредоточиться на том, чего они хотят. Казалось, что это были параллельные фикстуры с упорядочением тестовых примеров. Я полностью понимаю, что разные люди захотят разного, но когда обе группы представляют себя выражающими, «что нужно пользователям Selenium», это немного сбивает с толку. Не могли бы вы обрисовать мне в общих чертах, какие виды веб-тестов могут потребовать параллелизма на уровне методов, в отличие от тех, кто хочет запускать методы в заранее определенном порядке? Думаю, я мог догадаться, но я бы предпочел, чтобы это было от пользователя.

Что касается обходного пути ... вы рассматривали возможность использования отдельных тестовых сборок? NUnit будет рад запускать каждый из них параллельно в отдельном процессе. Конечно, это не устраняет необходимости синхронизировать доступ к таким вещам, как файлы.

Что касается безопасности потоков - мы никогда не планировали, чтобы наша параллельная реализация брала на себя ответственность за безопасность потоков. Единственное, что я ожидал гарантировать, это то, что NUnit не создаст никаких проблем безопасности потоков, если ваши методы уже являются потокобезопасными. Это само по себе оказывается нетривиальным.

Спасибо за ответ. Я полностью понимаю ваши комментарии о
упорядочивание выполнения тестов в фикстуре и разбиение тестов на отдельные
сборки.

Я уже являюсь пользователем NUnit и уже много лет (и JUnit до этого)
так что идея полагаться на порядок тестов в приспособлении даже не была
рассмотрение в моем тестовом дизайне. Каждый тест пытается быть полностью инкапсулированным.
действие или набор действий на сайте без ожидания порядка
исполнение. Дизайн сайта, который я тестирую, также означает, что многие тесты
выполнение может занять до 20 минут (большая часть этого времени тратится на ожидание
чтобы что-то произошло на сайте) и тип тестирования охватывает
несколько похожих сценариев, поэтому базовые тестовые классы используются для сокращения кода
дублирование и повышение ремонтопригодности за счет использования общего базового класса
методы. Тесты организованы в отдельные проекты на основе разработчика.
командное владение этой областью (поэтому мы используем отдельные сборки, но там
много тестов на сборку, и моя тестовая оболочка будет обрабатывать выполнение
все тесты во всех сборках проходили параллельно, как и было создано раньше
первый официальный выпуск NUnit 3, и я хотел убедиться, что все тесты
возможность одновременного выполнения при достаточном количестве потоков
доступный).

По сути, вы можете представить, что одна сборка может иметь 10 тестов и
еще 100 тестов, но на сборке с 10 тесты занимают 10 минут
каждый, в то время как сборка со 100 тестами занимает 1 минуту. Если я
иметь машину, способную запускать 110 параллельных потоков (что на самом деле
часть нашей инфраструктуры), то я бы ожидал, что тесты завершатся
через 10 минут, а не за 100 минут.

Надеюсь, это поможет объяснить ... извините, если все еще не совсем понятно,
но общая суть в том, что параллелизм на уровне методов - это то, что я
отсутствует в других тестовых библиотеках (например, prspec в ruby) и когда
делать анализ улучшений производительности, которые должны быть получены, добавив его i
обнаружил, что это может быть серьезное положительное изменение. См. В качестве примера следующее:
https://github.com/bicarbon8/rspec-parallel/wiki/Examples
1 июля 2016 г., 00:45, "CharliePoole" [email protected] написал:

Спасибо за ваши комментарии. Думаю, я тут немного поболтаю ...

Это помогает понять, что нужно людям и зачем им это нужно. Не будучи
веб-разработчик, я старался прислушаться к мнению пользователей Selenium и сосредоточиться на том, что
они хотели. Казалось бы, параллельные светильники с заказом
среди тестовых случаев. Я полностью понимаю, что разные люди захотят
разные вещи, но когда обе группы представляют себя выражающими
"что нужно пользователям Selenium" немного сбивает с толку. Вы можете набросать для меня наброски
какие виды веб-тестов могут потребовать параллелизма на уровне методов, а не
те люди, которые хотят запускать методы в заранее определенном порядке? Я думаю я мог бы
догадываюсь, но я бы предпочел получить его от пользователя.

Что касается вашего обходного пути ... вы рассматривали возможность использования отдельного теста
сборки? NUnit был бы рад запустить каждый из них параллельно в отдельном
процесс. Конечно, это не устраняет необходимости синхронизировать доступ к
такие вещи, как файлы.

Что касается потоковой безопасности - мы никогда не планировали нашу параллельную реализацию
взять на себя ответственность за безопасность потоков. Единственное, чего я ожидал
гарантия состоит в том, что NUnit не _создает_ проблемы безопасности потоков, если ваш
методы уже ориентированы на многопотоковое исполнение. Это само по себе оказывается нетривиальным.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/nunit/nunit/issues/164#issuecomment -229819324 или отключить звук
нить
https://github.com/notifications/unsubscribe/ACNsyoczCUV9L7kbF2SHB7lLsyBKlrv9ks5qRFUJgaJpZM4CUZ8r
.

Спасибо за информацию ... полезно видеть разные точки зрения.

Мои 5 центов.

В нашем проекте у нас есть ~ 25 тестовых сборок, и параллельное выполнение тестов для каждой сборки и для каждого приспособления уже значительно сокращает время выполнения. Параллельное выполнение тестов в приспособлении еще больше улучшит его. Теперь мы даже разбили наиболее трудоемкие фикстуры на несколько, чтобы ускорить выполнение, но будет намного лучше, если nunit будет запускать тесты фикстур параллельно.

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

Спасибо за вклад ... это область, которую мы собираемся решить в следующем выпуске вместе с конкурирующей, но дополнительной проблемой, заключающейся в том, чтобы некоторые тесты не выполнялись параллельно друг другу!

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

@CharliePoole Отличные новости! Большое спасибо!

На мой взгляд, тестовые примеры должны быть изолированными и не зависеть от других тестовых примеров или порядка выполнения. Если люди по-прежнему хотят запускать некоторые однопоточные тесты, они все равно могут использовать [Parallelizable (ParallelScope.None)] и / или OrderAttribute.

Эта реализуемая проблема позволит запускать наборы тестов быстрее по сравнению с локальной сеткой веб-драйверов или поставщиком Saas, таким как BrowserStack или SauceLabs. В настоящее время я пытаюсь ограничить количество тестовых методов в тестовом классе количеством доступных узлов webdriver или сеансов браузера, чтобы сетка использовалась полностью. В противном случае, если в тесте есть 8 методов тестирования, а в моей сетке 8 доступных сеансов браузера, будет использоваться только один, потому что все методы тестирования класса будут запускаться по одному.

@pablomxnl Абсолютно согласен. Как коуч или руководитель проекта, я всегда очень сильно продвигал эту идею. Однако я не ношу здесь ни одной из этих шляп. Я поставщик программного обеспечения с пользователями, которые просят о вещах. Если они просят по-настоящему вопиющие вещи, я просто говорю «нет». Но если они просят о вещах, которые являются разумными в одном контексте, но не о других - даже не в большинстве - я принимаю это во внимание.

В случае веб-сайтов мы почти всегда не говорим о модульных тестах. Функциональные тесты более высокого уровня часто требуют секвенирования. Независимо от того, выполняется ли это с помощью набора шагов в тесте или серии методов, - это деталь реализации для нас и вопрос удобства для пользователя. Лично я думаю, что нам, вероятно, понадобится что-то под названием [Step], которое находится внутри класса [StepFixture], или с какими-то подобными именами, чтобы мы могли убрать весь этот упорядочивающий / упорядочивающий материал из модульного тестирования. Может быть, у меня будет время сделать это до того, как Интернет умрет. :-)

В любом случае, всегда интересно узнать, как люди на самом деле используют ваше программное обеспечение.

@CharliePoole , пожалуйста, не поймите меня неправильно, спросив (просто хочу быть уверенным): будет ли эта функция добавлена ​​в следующую версию (3.5, срок выхода до 29 сентября 2016 г.)?

Хотя я могу делать вид, что предсказываю будущее, это удовлетворит вас только до сентября. :-)

Позвольте мне ответить, объяснив, как мы «планируем» функции.

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

В добровольном проекте с открытым исходным кодом нет фиксированного количества усилий в месяц. Мы можем использовать подход «вчерашняя погода», но оказывается, что количество времени, которое люди тратят на NUnit, а также количество людей, участвующих в волонтерской работе, весьма различны.

В качестве компромисса мы выбираем небольшое количество проблем, которые являются ключевыми для выпуска, и заранее добавляем их к этапу. Я предпочитаю добавлять не более 25% того, что мы можем надеяться сделать. Большинство проблем в выпуске добавляются к этому этапу только после того, как они решены, или, в лучшем случае, когда кто-то соглашается работать над ними. Как правило, вы не найдете открытых проблем в нашей вехе 3.5 без назначенного им человека, хотя я делаю это время от времени, если кажется, что что-то блокирует другую работу.

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

Что касается этой конкретной проблемы ... Я уделил ей первоочередное внимание, чтобы сказать нашим разработчикам, что это важно. Кто-то должен быть свободен, чтобы работать над этим, и иметь достаточно опыта для проекта такого масштаба и сложности. Если кто-то с правильным опытом поднимет это в ближайшие несколько недель, я думаю, что это может быть сделано к выпуску. В качестве ориентира, я думаю, что мне понадобится около месяца, работая над некоторыми другими вещами, чтобы разобраться с этим.

Извините, более однозначного ответа нет, но такой ответ обязательно будет ложью!

@CharliePoole есть ли какие-нибудь обновления с учетом этой функции?

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

@CharliePoole есть ли какие-нибудь обновления по этой проблеме?

@KPKA, мы еще не начали работу над этим, поэтому обновления нет. Для пользователей с установленным ZenHub вы увидите, что эта проблема перемещается из Backlog в ToDo, а затем In Progress, когда мы начинаем работать над ней.

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

@CharliePoole @rprouse

Привет!

Есть какие-нибудь новости по этому вопросу?
Будет ли это в следующем выпуске или планируется в одном из ближайших этапов?

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

Надеемся услышать от вас скоро

@GitSIPA, какую тестовую среду вы используете, которая позволяет запускать методы тестирования параллельно?

Отвечая на ваш вопрос, никто не начал работать над этой проблемой, поэтому расчетное время прибытия отсутствует, но мы учтем ваш голос при принятии решения о том, над чем работать дальше.

+1, согласен с @GitSIPA. Это действительно важный функционал

@GitSIPA +1
@rprouse Мы используем mbunit, но этот фреймворк сейчас не поддерживает. И у нас есть проблемы с mbunit.

@rprouse В настоящее время мы также используем MbUnit, но, поскольку поддержка не предоставляется для новых версий Visual Studio, мы рассматривали возможность перехода на NUnit.

В вопросе №1921 @ jnm2 спросил: «Что стоит между нами и параллельным запуском параметризованных тестовых примеров? Могу ли я внести свой вклад?»

Второй вопрос первый: точно! Мы будем рады вашей помощи.

И к первому вопросу:

  1. Мы выполняем «WorkItems», которые в настоящее время однозначно сопоставляют тесты. Я думаю, что нам нужно рассматривать OneTimeSetUp и OneTimeTearDown для фикстуры как отдельные рабочие элементы в качестве предварительного шага. Проблема № 1096 посвящена этому.

  2. Нам нужен какой-то способ сделать WorkItem зависимым от других WorkItem, чтобы он был запланирован на выполнение только тогда, когда все те, которые зависят от элементов, завершены. В настоящее время мы делаем это очень упрощенно, используя CountDown, но нам нужно что-то более общее. Первое использование этого, конечно же, будет заключаться в том, чтобы OneTimeTearDown зависел от завершения всех тестов. Позже, когда мы реализуем зависимость между тестами, он найдет другое применение. Я представляю это как очередь незавершенных рабочих элементов, но могут быть и другие способы реализовать это.

  3. Убрав эти две вещи, мы могли бы начать работать над самой основной проблемой: планировать запуск тестов, а не запускать их в том же потоке, который выполнял OneTimeSetUp для прибора.

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

Какое планирование было сделано до сих пор?
Мне нужно запустить достаточно тестов TestCaseSource параллельно, чтобы загрузить процессор. У меня нет требований к установке, демонтажу или заказу. Тем не менее, другим людям нужно будет принять это во внимание.

Я ожидаю, что выполнение TestCaseSource будет распараллелено, поэтому два метода в одном устройстве, которое использует разные TestCaseSource, будут выполнять перечисления параллельно. Также кажется, что было бы неплохо, если бы два метода использовали один и тот же TestCaseSource, если бы он выполнялся только один раз - мысли по этому поводу?

Изменить: комментируя СОСТОЯНИЕ ГОНКИ. Мы уже на хорошем старте! 😆

Я повторю историю, которую мне приходилось много рассказывать в последнее время. :улыбка:

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

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

IOW, ваши тестовые примеры не «используют» ваш исходный код, скорее, NUnit использует этот источник для создания тестовых примеров. Конечно, они ничего не могут сделать, пока не будут созданы. Есть смысл?

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

Итак, эта проблема связана с параллельным запуском тестовых примеров __running__. Это означает, что все тестовые примеры находятся под прибором, если вы не отметили некоторые из них как непараллелизуемые. При этом будут одинаково обрабатываться простые непараметрические тесты, а также отдельные случаи параметризованного теста.

Было бы интересно провести параллелизацию тестов в приборах, где нет OneTimeTearDown (я думаю, что OneTimeSetUp в порядке). Это могло бы сработать легко, если бы вы правильно сделали это определение. Однако определение сложнее, чем вы думаете, потому что OneTimeTearDown может включать как унаследованные методы, так и глобальные атрибуты ActionAttributes.

@ jnm2 У вас уже была возможность заняться этой конкретной проблемой?

@julianhaslinger Нет. Это в моем списке после двух моих ближайших проблем, 1885 и 1933. Если вы хотите взяться за это, тем лучше!

@julianhaslinger Поскольку мы не знаем друг друга, прошу меня извинить за то, что я сказал, что с этим сложно https://github.com/nunit/nunit/issues/164#issuecomment -265267804 для разбивки на отдельные PR, которые я хотел бы увидеть, чтобы исправить это. Если вы придумаете более простой подход, опубликуйте его перед кодированием, чтобы мы могли взвесить будущие соображения с очевидным YAGNI, участвующим в предсказании будущего.

@CharliePoole @ jnm2 Привет, ребята!

Дело не в том, что я хотел начать реализацию этой недостающей функции, а просто для того, чтобы узнать о ее прогрессе. Как я могу судить из ваших ответов (см. Выше), в отношении этого конкретного запроса функции не было никакого прогресса (?).

@CharliePoole Одна из потенциальных проблем, с которыми я столкнулся при исследовании кода, заключалась в том, как сейчас обрабатываются одному и тому

Одним из решений этого было бы, чтобы каждый WorkItem работал с новым экземпляром тестового класса, но это, вероятно, усложнит поведение настроек Fixture, поскольку больше не будет ни одного экземпляра устройства.

@ chris-smith-zocdoc Да, это самая большая разница между NUnit и его предшественником junit. Раньше это широко обсуждалось за и против, но сейчас мало что вспоминает. По этой причине тесты NUnit должны были быть без сохранения состояния, а вся инициализация выполнялась в методе SetUp.

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

Периодически всплывает тема добавления опции для создания отдельного экземпляра пользовательской фикстуры для каждого тестового примера. Пока что это не до стадии запланированной функции. Это определенно связано с удобством использования функции параллельного метода со стороны пользователей, но я думаю, что это ортогонально реализации. ЕСЛИ мы создавали новый прибор для каждого экземпляра, мы бы просто запускали "одноразовую" настройку более одного раза. Конечно, это сильно ударит по любому пользователю, использующему статику. 😢

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

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

ЕСЛИ мы создавали новый прибор для каждого экземпляра, мы бы просто запускали "одноразовую" настройку более одного раза. Конечно, это сильно ударит по любому пользователю, использующему статику.

Я думаю, что разумно потребовать, чтобы статическое состояние отсутствовало, если вы решите работать параллельно, в той степени, в которой это ваша вина, если что-то ломается из-за смешивания статического состояния и параллелизма. К счастью, весь ваш код будет тестироваться, так что его будет сложно пропустить 😆

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

Считайте меня за это.

Я тоже!

В субботу, 14 января 2017 г., в 3:58, Джозеф Мюссер [email protected]
написал:

>
>
>
>

[изображение: Boxbe] https://www.boxbe.com/overview

Автоматическая очистка: сохранить 1 последний адрес электронной почты ([email protected])

Изменить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ% 252BtolspNKBzqBxtH6H% 252FhqnTQ% 253D% 253D & tc_serial = 28420100882 & tc_rand = 128339648 & utm_source = stf & utm_medium = адрес электронной почты

| Удалить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ% 252BtolspNKBzqBxtH6H% 252FhqnTQ% 253D% 253D & tc_serial = 28420100882 & tc_rand = 128339648 & utm_source = stf & utm_medium = адрес электронной почты

| Отметить как важное
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ% 252BtolspNKBzqBxtH6H% 252FhqnTQ% 253d% 253d% 26important% 3Dtrue% 26emlId% 3D54854949581 & tc_serial = 28420100882 & tc_rand = 128339648 & utm_source = СТП & utm_medium = электронный & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001

ЕСЛИ мы создавали новый прибор для каждого экземпляра, мы бы просто запустили «один»
установка времени более одного раза. Конечно, это сильно ударит по всем пользователям, которые
используя статику.

Я думаю, что разумно потребовать, чтобы не было статического состояния, если вы
предпочитаю работать параллельно, если это ваша вина, если что-то
разрывы для смешивания статического состояния и параллелизма. К счастью, весь этот код будет
быть под тестированием, поэтому его будет сложно пропустить: D

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

Считайте меня за это.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-272488655 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAHNVlwVps8pQ93UIwZw6zY7TOyHO0a6ks5rR61EgaJpZM4CUZ8r
.

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

Вот в чем дело: если метод полностью не распараллеливается, это означает, что он не может работать параллельно с __ любым другим методом__. OTOH, если он не может быть распараллелен только в своем приспособлении, он не может работать параллельно с __ любым другим методом в том же приспособлении .__

Я предлагаю рассматривать это различие следующим образом:

  1. Если тестовый метод не имеет атрибута Parallelizable, он должен выполняться в том же потоке, что и содержащий его прибор, при условии, что никакой другой атрибут (например, Apartment) не требует его запуска в другом потоке.

  2. Если у него есть атрибут Parallelizable с областью действия Self, или если набор более высокого уровня определяет область действия Children, то метод тестирования запускается параллельно с другими методами в приспособлении.

Мысли @ nunit / core-team?

Слева вверху:

  1. Если у него есть атрибут Parallelizable с областью действия None, он выполняется в непараллельной очереди.

@CharliePoole - ваши три пункта имеют смысл, хотя я не понимаю, какой альтернативой вы предлагаете не заниматься. Не могли бы вы уточнить?

В настоящее время мы рассматриваем отсутствие атрибута так же, как наличие атрибута с ParallelScope.None. Это ставит их в очередь в непараллельную очередь, если я включу их диспетчеризацию, и выполнение теста значительно замедлится.

PR # 2011 делает некоторые начальные шаги для реализации этой функции, но содержит #define, который заставляет тестовые примеры запускаться в потоке их содержащего приспособления. Этот комментарий документирует то, что, по моему мнению, необходимо сделать, чтобы снять это ограничение.

В настоящее время OneTimeTearDown прибора выполняется в потоке, который использовался для завершения последнего выполненного тестового примера. Если тестовые примеры выполняются параллельно, мы не можем предсказать, какой это будет тестовый пример. Это может быть резьба с характеристиками, отличными от требуемых для приспособления. Например, если последний завершенный тест выполняется в STA, он будет использоваться для запуска OneTimeTearDown, даже если OneTimeSetUp запущен в MTA. Во многих случаях это может не вызвать никаких проблем, но в некоторых может.

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

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

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

http://cpntr.codeplex.com/

заранее извиняюсь @CharliePoole, если это сообщение немного ортогонально недавним обсуждениям в этой ветке, но если кто-то еще последние 3 года ждал этого добавления функции на основе обещаний, установленных для NUnit 3 (еще в начале дней), я думаю, это может предложить решение, пока вам, ребята, не удастся решить проблемы дизайна (похоже, вы приближаетесь к решению).

@CharliePoole

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

Нужно ли нам, чтобы диспетчер заранее знал об ожидающих демонтаж элементах, или мы можем отправить их по мере их поступления? Более конкретно, если CompositeWorkItem в настоящее время вызывает PerformOneTimeTearDown, можем ли мы использовать диспетчер для отправки новой единицы работы в правильную рабочую смену?

@ chris-smith-zocdoc Да, именно этим я и занимаюсь. Я создал рабочий элемент нового типа, OneTimeTearDownWorkItem , который вложен в CompositeWorkItem и отправляется при запуске последнего дочернего теста. Позже мы можем посмотреть на эффективность, когда OneTimeSetUp и все тесты выполнялись в одном потоке.

Я не читал все слишком внимательно, но одна вещь, которую я хотел бы попросить в рамках этой функции, - это чтобы параллелизм был «умным», особенно для тестов с привязкой к вводу-выводу. Например, если у вас есть 10 потоков, выполняющих 100 распараллеливаемых тестов, не должно быть случая, чтобы 10 потоков сидели и ожидали завершения первых 10 тестов, прежде чем перейти к следующим 10 тестам. Если первые 10 тестов начинают ожидать очень длительные задачи ввода-вывода, тогда потоки должны быть свободны для перехода к другим тестам. Когда задачи ввода-вывода завершены, потоки возобновят ожидающие тесты по мере освобождения потоков.

По сути, я прошу интеллектуального управления пропускной способностью для тестов с привязкой к вводу-выводу, которые широко используют async / await. Это, безусловно, наше узкое место номер один в тестах.

@ chris-smith-zocdoc Собственно говоря, я в основном этим и занимаюсь. По сути, я использую существующий механизм обратного отсчета для запуска одноразовой задачи удаления. Хитрость заключается в том, чтобы отправить его в нужную очередь.

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

Может кто-нибудь объяснить мне, как это работает?
У меня тестовый класс
Когда я запускаю тесты в этом классе НЕ параллельно - все тесты прошли
Но когда я запускаю их с помощью [Parallelizable (ParallelScope.Children)]
Таким образом, они работают параллельно (несколько методов в одном классе)
но по какой-то причине некоторые тесты не проходят.
У меня есть поля экземпляра в этом классе, которые используются в тестах, и кажется, что эти поля используются совместно между потоками.
Я прав?
Вы создаете только 1 экземпляр этого класса и одновременно вызываете методы для этого единственного объекта?
ЧарлиПул

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

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

Возможно ли иметь [Parallelizable (ParallelScope.Children)] в
AssemblyInfo.cs файл?

Кто-нибудь видел, что это работает?

14 июня 2017 года в 01:37 CharliePoole [email protected] написал:

[image: Boxbe] https://www.boxbe.com/overview Автоматическая очистка: сохранить
1 последний адрес электронной почты ([email protected]) Изменить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D & tc_serial = 30872123699 & tc_rand = 2087335475 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Удалить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D & tc_serial = 30872123699 & tc_rand = 2087335475 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Отметить как важное
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D% 26important% 3Dtrue% 26emlId% 3D61187554820 & tc_serial = 30872123699 & tc_rand = 2087335475 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001

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

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

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-308157832 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAHNVuK-J-X74mlAA_eT7OX7dxs7MpoRks5sDqzLgaJpZM4CUZ8r
.

@agray Да, на самом деле это единственная причина, по которой у меня сейчас есть AssemblyInfo.cs.

Привет Джозеф,

Какую строку параллелизма вы добавляете в свой файл AssemblyInfo.cs?

Я хотел бы знать, что работает.

Ваше здоровье,

Эндрю

В среду, 14 июня 2017 г., в 16:17, Джозеф Мюссер [email protected]
написал:

[image: Boxbe] https://www.boxbe.com/overview Автоматическая очистка: сохранить
1 последний адрес электронной почты ([email protected]) Изменить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D% 253D & tc_serial = 30882364582 & tc_rand = 1974513896 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Удалить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D% 253D & tc_serial = 30882364582 & tc_rand = 1974513896 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Отметить как важное
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D% 253D% 26important% 3Dtrue% 26emlId% 3D61214070592 & tc_serial = 30882364582 & tc_rand = 1974513896 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT = & utm_content =

@array https://github.com/array Да, на самом деле это единственная причина, по которой я
теперь есть AssemblyInfo.cs.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-308325726 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAHNVghNAX8CJkqAy-qhAz8bXNhZcFOQks5sD3NigaJpZM4CUZ8r
.

@agray Тот, о котором вы спрашивали:

c# [Parallelizable(ParallelScope.Children)]

не забывай цель

[assembly: Parallelizable(ParallelScope.Children)]

@LirazShay Я использую NUnit для проведения тестов Selenium и использовал поля уровня фикстуры для хранения таких вещей, как ссылки на учетные записи пользователей и на экземпляр Selenium WebDriver, с которым я работал, и поэтому не мог запускать тесты параллельно в устройстве. Я работал над тем, чтобы написать «фабрику» (я использую кавычки, потому что не уверен, что это правильный термин), которая реализует IDisposable, который для каждого теста инкапсулирует все мои тестовые потребности и аккуратно срывает их в конце тест без необходимости [TearDown] или [OneTimeTearDown] вроде этого:

 public class TestFactory : IDisposable
    {
    // Instantiate a new SafeHandle instance.
    private readonly System.Runtime.InteropServices.SafeHandle handle = new Microsoft.Win32.SafeHandles.SafeFileHandle(IntPtr.Zero, true);

    // Flag: Has Disposed been called?
    private bool disposed = false;

    public TestFactory()
    {
        this.UserRepository = new List<UserAccount>();
        this.DU = new DataUtility();
    }

    // A list of users created for this test
    public List<UserAccount> UserRepository { get; private set; }

    // A very simple data layer utility that uses Dapper to interact with the database in my application 
    public DataUtility DU { get; private set; }

    // Gets a new user and adds it to the repository
    public UserAccount GetNewUser()
    {
        var ua = new UserAccount();
        this.UserRepository.Add(ua);
        return ua;
    }


    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (this.disposed)
        {
            return;
        }

        if (disposing)
        {
            // Deletes all user accounts created during the test
            foreach (UserAccount ua in this.UserRepository)
            {
                try
                {
                    ua.Delete();
                }
                catch (Exception)
                {
                    // Take no action if delete fails.
                }
            }

            this.DU.DeleteNullLoginFailures(); // Cleans up the database after tests
            Thread.Sleep(1500);
        }

        this.disposed = true;
    }
}

Затем в рамках теста я могу сделать следующее:

[TestFixture]
public class UserConfigureTests
{
    [Test]
    public void MyExampleTest()
    {
        using (TestFactory tf = new TestFactory())
        {
            var testUser = tf.GetNewUser();

    tf.DU.DoSomethingInTheDatabase(myParameter);

    // Test actions go here, and when we exit this using block the TestFactory cleans
    // up after itself using the Dispose method which calls whatever cleanup logic you've written into it
        }
    }
}

Таким образом, я могу избежать большого количества дублирования кода, и если мне когда-нибудь понадобится изменить зависимости моего теста, я просто сделаю это один раз на фабрике. Если у кого-то есть отзывы о стратегии, которую я использовал, я был бы признателен!

@tparikka Я сам очень рекомендую именно такой подход.

В моем файле AssemblyInfo есть следующее:

[сборка: Parallelizable (ParallelScope.Children)]
[сборка: LevelOfParallelism (16)]

Нужен ли мне еще атрибут LevelOfParallelism?

15 июня 2017 года в 04:37 Джозеф Мюссер [email protected] написал:

[image: Boxbe] https://www.boxbe.com/overview Автоматическая очистка: сохранить
1 последний адрес электронной почты ([email protected]) Изменить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D & tc_serial = 30894750852 & tc_rand = 1847060911 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Удалить правило
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D & tc_serial = 30894750852 & tc_rand = 1847060911 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001
| Отметить как важное
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D% 26important% 3Dtrue% 26emlId% 3D61245244440 & tc_serial = 30894750852 & tc_rand = 1847060911 & utm_source = stf & utm_medium = email & utm_campaign = ANNO_CLEANUP_EDIT & utm_content = 001

@tparikka https://github.com/tparikka Я очень рекомендую именно это
подойти к себе.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/nunit/nunit/issues/164#issuecomment-308521058 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AAHNVmEzVDbw32Xx0jkYcGK9bZW3tLvXks5sECh8gaJpZM4CUZ8r
.

Я еще не изучал использование LevelOfParallelism . По умолчанию это количество ядер, которое у вас есть.

Если ваши тесты не привязаны к ЦП, имеет смысл более высокое значение. Но, как всегда с перфомансом, ответ настолько зависит от вашего сценария, что лучше измерить, чем угадать.

@CharliePoole Я использую TestcaseSource , но похоже, что полученные тестовые примеры на самом деле не выполняются параллельно. Ожидается, что что-то подобное будет работать:

`` С #
[TestFixture]
класс Десериализация
{
общедоступный статический IEnumerableShouldDeserializeAllCases () => Enumerable.Repeat (0, 5) .Select (x => TimeSpan.FromSeconds (2));

    [TestCaseSource("ShouldDeserializeAllCases"), Parallelizable(ParallelScope.Children)]
    public void ShouldDeserializeAll(TimeSpan t)
    {
        Thread.Sleep(t);
        Assert.AreEqual(1, 1);
    }
}

`` ''

Общее время составляет 10 секунд вместо ~ 2.

Я подумаю, что детей нет, так что в этом случае лучше использовать
[Parallelizable (ParallelScope.All)]
или переместите свой атрибут на уровень класса.

@ParanoikCZE Спасибо. На самом деле я не понимаю, что означает этот атрибут, поэтому я пробовал все значения перечисления там. Независимо от того, какие из All , Children , Fixture или Self я использую, время выполнения у меня составляет 10 секунд (по крайней мере, в Visual Studio).

Я просто попробовал перенести его в класс, но это тоже не помогает.

Попробуйте, это источник вдохновения :)

class Deserialization
{
    public static IEnumerable<TestCaseData> ShouldDeserializeAllCases
    {
        get
        {
            for (int i = 1; i <= 5; i++)
                yield return new TestCaseData(TimeSpan.FromSeconds(i)).SetName($"Thread_worker_{i}");
        }
    }

    [TestCaseSource(nameof(ShouldDeserializeAllCases)), Parallelizable(ParallelScope.Children)]
    public void ShouldDeserializeAll(TimeSpan t) => System.Threading.Thread.Sleep(t);
}

@ParanoikCZE Еще раз спасибо. Я тестировал это в Visual Studio, и визуализация стала намного яснее, но тесты по-прежнему выполняются последовательно. Легче увидеть это, если вы используете постоянный сон для каждого теста вместо увеличения шагов.

Попробуйте добавить [assembly: LevelOfParallelism (5)] в AssemblyInfo, я думаю, что есть какое-то значение по умолчанию, но, возможно, это как-то не сработает для вас. В любом случае, у меня нет идей. :)

Была ли эта страница полезной?
0 / 5 - 0 рейтинги