Nunit: Неудачные модульные тесты в nunit.framework.tests после нового клона

Созданный на 25 июн. 2018  ·  31Комментарии  ·  Источник: nunit/nunit

Я только что взял свежий клон nunit и открыл решение в Visual Studio 2017 (Сообщество 15.7.4) с последним тестовым адаптером NUnit 3 (3.10 с параллельным запуском тестов), работающим в Windows 10 Professional, и выбрал «Debug-AnyCPU» "и нажмите build.

После прочтения BUILDING.md мне кажется, что я должен игнорировать любые сбои, не связанные с nunit.framework.tests- * и nunitlite.tests- *

Однако из-за ворот я получаю 2 отказа от nunit.framework.tests- *

Первая ошибка:

Test Name:  TestCaseSourceCanAccessWorkDirectory("C:\\Users\\ace.olszowka\\source\\nunit\\bin\\Debug\\net20")
Test FullName:  NUnit.Framework.TestContextTests.TestCaseSourceCanAccessWorkDirectory("C:\\Users\\ace.olszowka\\source\\nunit\\bin\\Debug\\net20")
Test Source:    C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\TestContextTests.cs : line 110
Test Outcome:   Failed
Test Duration:  0:00:00.001

Result StackTrace:  at NUnit.Framework.TestContextTests.TestCaseSourceCanAccessWorkDirectory(String workDirectory) in C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\TestContextTests.cs:line 112
Result Message: 
Expected string length 34 but was 50. Strings differ at index 34.
  Expected: "C:\\Users\\ace.olszowka\\source\\nunit"
  But was:  "C:\\Users\\ace.olszowka\\source\\nunit\\bin\\Debug\\net20"
  -------------------------------------------------^

Глядя на источник, я не понимаю, как это было возможно, насколько я могу судить, эти значения должны были быть идентичными ( _workDirectory и тестовые данные оба установлены на TestContext.CurrentContext.WorkDirectory ) мой единственный угадайте, это какое-то состояние гонки, может быть, из-за плохой конфигурации на моем конце?

Вторая ошибка:

Test Name:  StackTracesAreFiltered("WarningInBeginInvoke",4)
Test FullName:  NUnit.Framework.Assertions.WarningTests.StackTracesAreFiltered("WarningInBeginInvoke",4)
Test Source:    C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\Assertions\WarningTests.cs : line 292
Test Outcome:   Failed
Test Duration:  0:00:00.004

Result StackTrace:  at NUnit.Framework.Assertions.WarningTests.StackTracesAreFiltered(String methodName, Int32 maxLineCount) in C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\Assertions\WarningTests.cs:line 310
Result Message: 
Multiple failures or warnings in test:
  1) (Warning message)
  2) Expected the number of lines to be no more than 4, but it was 5:

 1. at NUnit.TestData.WarningFixture.<>c__DisplayClass45_0.<WarningInBeginInvoke>b__0()
 2. at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
 3. at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
 4. at System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(Object o)
 5. at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
(end)

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

Я также получаю каждый тестовый пример с ошибкой в ​​NUnitLite.Tests.CommandLineTests. Я был бы рад покопаться там, если это неожиданно.

Поскольку сборка проходит в CI, это, вероятно, просто проблемы с конфигурацией с моей стороны, но в BUILDING.md об этом ничего не упоминалось, поэтому я решил, что отчет того стоит.

bug normal

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

Спасибо за отчет! Я подтвердил, что TestCaseSourceCanAccessWorkDirectory и CommandLineTests не работают в обозревателе тестов. Нам нужно найти способ сделать их независимыми от раннера и параллелизма. @ nunit / framework-team Есть идеи?

Для второй ошибки это тест на запах. Имеет смысл поднять это число до 5.

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

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

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

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

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

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

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

  1. Клонировать код
  2. Прочтите README.md/BUILD.md/HACKING.md
  3. Попытка сборки (без изменений)
  4. Запустите модульные тесты (через встроенный Runner).
  5. Если все работает, начинайте играть с разными вещами.

Раньше это был dotCover от ReSharper, но мы пытались отучить себя от него, поскольку затраты на лицензирование просто сумасшедшие для небольших магазинов / индивидуальных разработчиков, когда есть альтернативы бесплатному / открытому программному обеспечению, которые «в основном работают».

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

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

Если вы разрабатываете NUnit, работая над фреймворком, я думаю, что смешивание в любых бегунах, которые делают что-то особым образом (R #, наш собственный адаптер), может запутать проблему. Мне нравится знать, что фреймворк корректно работает изолированно, прежде чем тестировать его на бегунах. Поэтому в своей работе я использую nunitlite для тестирования по мере разработки, а затем запускаю CI локально. Если кто-то хочет разработать NUnit в Test Explorer, я бы сказал, что он все равно должен запускать CI локально, а также должен вернуться к nunitlite или nunit3-console, когда что-то выглядит изворотливым.

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

Мы должны сделать CI каноническим, возможно, с помощью NUnitLite для всех тестов фреймворка, а затем консоли, адаптера VSTest и средства выполнения UWP для сквозных тестов.

Предполагая, что CI надежен, мне кажется, что есть тонкие различия между Test Explorer, ReSharper, NCrunch и нашим сценарием CI. Сказать, что эти встроенные в IDE инструменты следует игнорировать, - это то, что я считаю препятствием для участия и ложным, поскольку это даже не мой рабочий процесс. Мой идеальный рабочий процесс:

  1. Найдите существующие тесты или напишите новые тесты
  2. Закрепите это приспособление для тестирования, чтобы можно было быстро повторно запускать тесты во время набора текста (еще лучше, начать непрерывное тестирование)
  3. Внести изменение
  4. Перед созданием фиксации Git запустите .\build.ps1 -t test чтобы убедиться, что проходы и сбои соответствуют ожидаемым.
  5. Если есть какие-то сюрпризы, найдите и закрепите затронутые тесты, о которых я не знал, и переходите к шагу 3.

В редких случаях, когда тесты чувствительны к бегунам, я не уверен, что сложно сделать их нечувствительными к бегунам. Это не может быть хуже интеграционных тестов, которые я написал для ILMerge, которые я сделал устойчивыми к теневым копиям ReSharper и NCrunch.

@aolszowka Я на 100% согласен с вашим мнением о том, что, что бы мы ни делали, мы должны уважать время участников, поддерживая удобство использования и актуальность документации для вкладов.

@ jnm2 Мне нравится ваш "канонический" подход. Я сомневаюсь, что в Test Explorer будет легко заставить все работать плавно, но попробовать стоит.

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

Самое большое, что мы могли бы сделать, чтобы продвинуть эту идею вперед, ИМО, - это создать отдельную систему и, возможно, интеграционные тесты.

Это может быть основной причиной. При написании тестов для получения XML из FrameworkController я заметил, что TestContext.WorkDirectory заменяется на C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE :

https://github.com/nunit/nunit/blob/81fcc7c047c09fcb5a86989d0829716ca7d08e1e/src/NUnitFramework/framework/Api/DefaultTestAssemblyBuilder.cs#L137

Стек вызовов:

>   nunit.framework.dll!NUnit.Framework.Api.DefaultTestAssemblyBuilder.Build(System.Reflection.Assembly assembly, string suiteName, System.Collections.Generic.IDictionary<string, object> options) Line 137    C#
    nunit.framework.dll!NUnit.Framework.Api.DefaultTestAssemblyBuilder.Build(string assemblyNameOrPath, System.Collections.Generic.IDictionary<string, object> options) Line 114    C#
    nunit.framework.dll!NUnit.Framework.Api.NUnitTestAssemblyRunner.Load(string assemblyNameOrPath, System.Collections.Generic.IDictionary<string, object> settings) Line 154   C#
    nunit.framework.dll!NUnit.Framework.Api.FrameworkController.LoadTests() Line 204    C#

Это потому, что TestContext.WorkDirectory - статическое изменяемое состояние:

https://github.com/nunit/nunit/blob/81fcc7c047c09fcb5a86989d0829716ca7d08e1e/src/NUnitFramework/framework/TestContext.cs#L96 -L101

Значит, он используется всеми тестами (!), В том числе и параллельными. Любой тест, основанный на WorkDirectory, должен быть помечен как [NonParallelizable] , чтобы быть правильным.

Я давно заметил эту проблему. Где-то есть проблема.

Непараллелизируемого недостаточно. Если какой-либо тест изменяет WorkDirectory (как это делают многие тесты NUnit), существует разумная вероятность того, что другие тесты, которые полагаются на него, потерпят неудачу.

Все зависит от порядка выполнения тестов, который не определен в NUnit.

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

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

@CharliePoole Как нам сделать это реальностью? Мы находимся в особом положении, так как фреймворк тестирует тестовый FrameworkController, контроллер, запускаемый внутри контроллера.

Если оставить в стороне наши тесты, WorkDirectory означает «каталог, установленный пользователем для получения всех выходных файлов для выполнения». Так что тест не должен его изменить.

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

В крайнем случае, мы могли бы сделать его неизменным и прекратить тестирование. <ducks>

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

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

@oznetmaster Я искал, но не нашел ни одного теста NUnit, который меняет его, кроме как случайно. У тебя есть под рукой?

Придется поискать в своих архивах.

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

                if (options.ContainsKey (FrameworkPackageSettings.WorkDirectory))
                    TestContext.DefaultWorkDirectory = options[FrameworkPackageSettings.WorkDirectory] as string;
                else
                    if (TestContext.DefaultWorkDirectory == null)
                        TestContext.DefaultWorkDirectory = Directory.GetCurrentDirectory ();

Проблемными были те тесты, которые вызывали DefaultTestAssemblyBuilder.Build с параметрами, которые не включали FrameworkPackageSettings.WorkDirectory, в результате чего TestContext.DefaultWorkDirectory был перезаписан CurrentDirectory. Это означало, что если WorkDirectory был установлен на выполнение верхнего уровня, он будет перезаписан тестом и никогда не будет восстановлен.

Похоже, тогда было бы хорошо применить такой же подход?

Работает для меня. Моя сборка CF проходит 100% тестов NUnit.

@OmicronPersei Если вы будете здесь в ближайшие несколько дней, можете ли вы попробовать исправить ?

Да! Попробую этим вечером

Я не могу воспроизвести эту ошибку, потому что nunit3-vs-adapter # 528 вызывает другие проблемы. Идеи?

@OmicronPersei О. Я не знаю. Будет ли использование .runsettings с правильной настройкой WorkDirectory хорошим обходным путем?

Хорошо, я пробовал это. TestCaseSourceCanAccessWorkDirectory завершается успешно, но StackTracesAreFiltered терпит неудачу с тем же сообщением / трассировкой стека в OP.

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

А как насчет TestCaseSourceCanAccessWorkDirectory , или это все еще в рамках этого PR?

ForTestCaseCanAccessWorkDirectory, исправление @oznetmaster решает эту проблему? Если нет, нам придется продолжить расследование.

Я не могу воспроизвести проблему на своей машине, тест прошел для меня.

Не беспокойтесь, это может сделать кто-то другой. Мне тоже нравятся небольшие PR.

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

Нет, спасибо, что указали на это. Закрытие.

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