TeamCity - NUnit Console Runner не находит все модульные тесты при использовании Kentico Fakes - PullRequest
0 голосов
/ 15 января 2019

У меня есть 3 тестовые сборки NUnit, которые тестируют мой пользовательский код, написанный для платформы Kentico CMS. Я могу запустить эти тесты как в Visual Studio (с помощью адаптера NUnit), так и в консоли запуска NUnit. Сейчас я пытаюсь запустить эти тесты на моем сервере сборки TeamCity. У меня есть настройка бегуна NUnit, и он возвращает некоторые результаты, но я обнаружил, что не все тесты выполняются. В одном случае один из моих сборочных отчетов не имеет тестовых приборов, несмотря на то, что я точно знаю, что они есть.

Сведения о системе

  • TeamCity v10.0.5 (сборка 42677)
  • Nunit 3.8.1
  • Nunit.ConsoleRunner 3.8.0
  • Кентико 11
    • Kentico.Libraries - 11.0.35
    • Kentico.Libraries.Tests - 11.0.35

Задача 1

У меня есть тестовая сборка под названием gto.ecommerce.core.tests.dll. Когда он запускается на сервере TeamCity, я получаю следующий вывод (прямо из консоли NUnit):

NUnit Console Runner 3.8.0
Copyright (c) 2018 Charlie Poole, Rob Prouse

Runtime Environment
   OS Version: Microsoft Windows NT 6.3.9600.0
  CLR Version: 4.0.30319.42000

Test Files
    D:\TeamCity\buildAgent\work\4a231fb0e41e27f5\Tests\gto.ecommerce.core.tests\bin\Build\gto.ecommerce.core.tests.dll


Run Settings
    DisposeRunners: True
    WorkDirectory: D:\TeamCity\buildAgent\work\4a231fb0e41e27f5\packages\NUnit.ConsoleRunner.3.8.0\tools
    ImageRuntimeVersion: 4.0.30319
    ImageTargetFrameworkName: .NETFramework,Version=v4.6
    ImageRequiresX86: False
    ImageRequiresDefaultAppDomainAssemblyResolver: False
    NumberOfTestWorkers: 8

Test Run Summary
  Overall result: Passed
  Test Count: 6, Passed: 6, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
  Start time: 2019-01-15 10:16:53Z
    End time: 2019-01-15 10:16:54Z
    Duration: 1.219 seconds

Results (nunit3) saved as TestResult.xml

Это точно такие же результаты, которые возвращаются при выполнении шага сборки TeamCity.

Однако здесь должно быть больше тестов. Если я скопирую двоичные файлы, созданные TeamCity, на мой локальный компьютер и запуском той же команды запуска консоли NUnit, я получу следующие результаты:

NUnit Console Runner 3.8.0 
Copyright (c) 2018 Charlie Poole, Rob Prouse

Runtime Environment
   OS Version: Microsoft Windows NT 10.0.14393.0
  CLR Version: 4.0.30319.42000

Test Files
    C:\temp\gto-gtoengineering\TeamCity\gto.ecommerce.core.tests\Build\gto.ecommerce.core.tests.dll


Run Settings
    DisposeRunners: True
    WorkDirectory: Z:\
    ImageRuntimeVersion: 4.0.30319
    ImageTargetFrameworkName: .NETFramework,Version=v4.6
    ImageRequiresX86: False
    ImageRequiresDefaultAppDomainAssemblyResolver: False
    NumberOfTestWorkers: 8

Test Run Summary
  Overall result: Passed
  Test Count: 33, Passed: 33, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
  Start time: 2019-01-15 10:19:31Z
    End time: 2019-01-15 10:19:35Z
    Duration: 4.494 seconds

Results (nunit3) saved as TestResult.xml

Обратите внимание, что на моем аппарате всего 33 теста, что является правильным числом.

Задача 2

Если я запускаю те же сценарии на другой моей сборке, rwy.common.core.tests, то это результат сервера TeamCity:

NUnit Console Runner 3.8.0
Copyright (c) 2018 Charlie Poole, Rob Prouse

Runtime Environment
   OS Version: Microsoft Windows NT 6.3.9600.0
  CLR Version: 4.0.30319.42000

Test Files
    D:\TeamCity\buildAgent\work\4a231fb0e41e27f5\Tests\rwy.common.core.tests\bin\Build\rwy.common.core.tests.dll


Errors, Failures and Warnings

1) Invalid : D:\TeamCity\buildAgent\work\4a231fb0e41e27f5\Tests\rwy.common.core.tests\bin\Build\rwy.common.core.tests.dl
l
Has no TestFixtures

Run Settings
    DisposeRunners: True
    WorkDirectory: D:\TeamCity\buildAgent\work\4a231fb0e41e27f5\packages\NUnit.ConsoleRunner.3.8.0\tools
    ImageRuntimeVersion: 4.0.30319
    ImageTargetFrameworkName: .NETFramework,Version=v4.6
    ImageRequiresX86: False
    ImageRequiresDefaultAppDomainAssemblyResolver: False
    NumberOfTestWorkers: 8

Test Run Summary
  Overall result: Failed
  Test Count: 0, Passed: 0, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
  Start time: 2019-01-15 10:21:16Z
    End time: 2019-01-15 10:21:17Z
    Duration: 1.046 seconds

Results (nunit3) saved as TestResult.xml

Но опять же, я копирую те же двоичные файлы на локальный компьютер и получаю следующий результат:

NUnit Console Runner 3.8.0 
Copyright (c) 2018 Charlie Poole, Rob Prouse

Runtime Environment
   OS Version: Microsoft Windows NT 10.0.14393.0
  CLR Version: 4.0.30319.42000

Test Files
    C:\temp\gto-gtoengineering\TeamCity\rwy.common.core.tests\Build\rwy.common.core.tests.dll


Run Settings
    DisposeRunners: True
    WorkDirectory: Z:\
    ImageRuntimeVersion: 4.0.30319
    ImageTargetFrameworkName: .NETFramework,Version=v4.6
    ImageRequiresX86: False
    ImageRequiresDefaultAppDomainAssemblyResolver: False
    NumberOfTestWorkers: 8

Test Run Summary
  Overall result: Passed
  Test Count: 20, Passed: 20, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
  Start time: 2019-01-15 10:22:55Z
    End time: 2019-01-15 10:23:00Z
    Duration: 4.242 seconds

Results (nunit3) saved as TestResult.xml

Определенно должно быть доступно 20 тестов, но при запуске на сервере TeamCity он говорит, что не может найти ни одного.

Краткое описание

Так кто-нибудь знает, почему две разные машины, работающие, как я полагаю, с одинаковыми версиями NUnit и консольного бегуна, дают совершенно разные результаты? Я не вижу никаких очевидных различий в номерах версий, кроме Windows, но я думаю, что должна использоваться та же платформа .NET.

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

1 Ответ

0 голосов
/ 16 января 2019

После долгого отслеживания я обнаружил, что причина не в NUnit или TeamCity, а скорее в том, что я использовал библиотеки из Kentico , в частности, я использовал библиотеку Kentico CMS.Tests для помощи модульное тестирование моего пользовательского кода Kentico как объяснено здесь .

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

Определить первопричину

После небольшого поиска в Интернете я обнаружил, что в консоли NUnit есть опция командной строки --trace . Передав --trace=Verbose, я смог получить файлы трассировки, записанные в рабочий каталог, установленный для консоли, и затем сравнить две машины. Моя локальная машина разработки показала, что все приборы были найдены правильно, но сервер TeamCity будет генерировать файлы трассировки, которые выводили примерно так:

InternalTrace: Initializing at level Debug
14:41:48.559 Debug [ 5] DefaultTestAssemblyBuilder: Loading D:\TeamCity\buildAgent\work\4a231fb0e41e27f5\Tests\rwy.common.core.tests\bin\Build\rwy.common.core.tests.dll in AppDomain domain-
14:41:48.570 Debug [ 5] DefaultTestAssemblyBuilder: Examining assembly for test fixtures
14:41:48.579 Debug [ 5] DefaultTestAssemblyBuilder: Found 12 classes to examine
14:41:48.691 Error [ 5] DefaultTestAssemblyBuilder: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
   at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
   at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
   at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg)
   at System.Reflection.CustomAttribute.IsCustomAttributeDefined(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Int32 attributeCtorToken, Boolean mustBeInheritable)
   at System.Reflection.CustomAttribute.IsDefined(RuntimeMethodInfo method, RuntimeType caType, Boolean inherit)
   at NUnit.Framework.Internal.Reflect.GetMethodsWithAttribute(Type fixtureType, Type attributeType, Boolean inherit)
   at NUnit.Framework.Internal.TestFixture..ctor(ITypeInfo fixtureType, Object[] arguments)
   at NUnit.Framework.Internal.Builders.DefaultSuiteBuilder.BuildFrom(ITypeInfo typeInfo)
   at NUnit.Framework.Api.DefaultTestAssemblyBuilder.GetFixtures(Assembly assembly, IList names)

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

Часть, которую я не понял, была ссылкой на Microsoft.VisualStudio.QualityTools.UnitTestFramework, потому что это не имеет ничего общего с NUnit - это библиотека MSTest, и у меня вообще не было модульных тестов MSTest в моем проекте.

Именно тогда я понял, что это проблема Kentico - потому что Kentico CMS.Tests.dll, на который ссылаются, чтобы помочь написать поддельные объекты Info и провайдеры , работает как для NUnit , так и MSTest.

На моей машине для разработки Microsoft.VisualStudio.QualityTools.UnitTestFramework устанавливается вместе с Visual Studio, как объяснено в в этом вопросе , что означает, что каждый раз, когда я запускаю тесты, проблем не возникает - в моей системе может быть найдена зависимая DLL. Однако, это никогда не доступно на сервере сборки, если не установлено явно.

Решение

Чтобы решить эту проблему, я последовал этому совету :

  1. Скопировал Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll в мое решение и передал его в мой репо.
  2. Включите ссылку на эту сборку во все мои тестовые проекты, убедившись, что Copy Local соответствует действительности.

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

...