Создание настраиваемого атрибута, производного от TestActionAttribute
, а затем использование этого атрибута из тестовой библиотеки, которая использует более новую версию NUnit, приведет к тому, что NUnit не выполнит тест, поскольку не сможет загрузить старую библиотеку NUnit. Использование app.config
для перенаправления на более новую версию NUnit устраняет проблему, и тесты запускаются должным образом.
Проблема не очевидна, потому что обычные тесты не запускаются (статус: неубедительно). Это было причиной проблемы NUnit.ApplicationDomain № 25: невозможно запустить с помощью средства запуска тестов VS2017, и я обнаружил корень проблемы только потому, что одно из параметризованных тестовых приспособлений дало следующую трассировку стека:
An exception was thrown while loading the test.
System.IO.FileLoadException: Could not load file or assembly 'nunit.framework, Version=3.7.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'nunit.framework, Version=3.7.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb'
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.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
at NUnit.Framework.Internal.TypeWrapper.GetCustomAttributes[T](Boolean inherit)
at NUnit.Framework.Internal.Builders.DefaultSuiteBuilder.GetFixtureBuilderAttributes(ITypeInfo typeInfo)
at NUnit.Framework.Internal.Builders.DefaultSuiteBuilder.BuildFrom(ITypeInfo typeInfo)
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].
Exception doesn't have a stacktrace
Основная проблема - ссылка на более старую версию NUnit для атрибутов - может быть закрыта как «не будет исправлять», но я думаю, что для пользователей может быть полезно иметь какое-то сообщение об ошибке вместо того, чтобы тесты, казалось бы, отказываются выполнять .
Я создал решение для воспроизведения через @ _repo_NUnitAttributesTargettingDifferentVersion
Я согласен с выводом: тот факт, что настраиваемые атрибуты заблокированы в версии NUnit, которую они расширяют, не нов, но также нелегко обнаружить. Мы должны просмотреть документацию, чтобы убедиться, что это ясно, а также попытаться найти способ для обнаружения конфликтующих версий фреймворка и выдачи сообщения об ошибке.
Кроме того, насколько это возможно, мы должны задокументировать, как писать настраиваемые атрибуты, которые будут обратно совместимы. Я считаю, что полагаться исключительно на наши неизменные интерфейсы и использовать перенаправление привязки в файле конфигурации поможет, но кто-то должен сначала попробовать это.
Я помечаю это как оба документа, чтобы мы могли просмотреть их и улучшить, чтобы исследовать обнаружение конфликтующих версий и, возможно, рекомендовать перенаправление привязки.
Я не так хорошо разбираюсь в Roslyn, но может ли это обнаружить анализатор? Или это должна быть проверка во время выполнения (улучшенный обмен сообщениями об ошибках)
Самый полезный комментарий
Я согласен с выводом: тот факт, что настраиваемые атрибуты заблокированы в версии NUnit, которую они расширяют, не нов, но также нелегко обнаружить. Мы должны просмотреть документацию, чтобы убедиться, что это ясно, а также попытаться найти способ для обнаружения конфликтующих версий фреймворка и выдачи сообщения об ошибке.
Кроме того, насколько это возможно, мы должны задокументировать, как писать настраиваемые атрибуты, которые будут обратно совместимы. Я считаю, что полагаться исключительно на наши неизменные интерфейсы и использовать перенаправление привязки в файле конфигурации поможет, но кто-то должен сначала попробовать это.