BadImageFormatException, когда тестовая сборка AnyCPU реализует интерфейс из производственной сборки x64 - PullRequest
24 голосов
/ 09 февраля 2012

Кажется, я столкнулся со сценарием, когда при запуске mstest для сборки AnyCPU, которая ссылается на сборку x64, я получаю исключение BadImageFormatException.

Проблема возникает, когда интерфейс в x64Production.dll реализован (даже если он не используется) тестовой сборкой AnyCPUTestingx64Production.dll:

Unable to load the test container 'D:\AnyCPUTestingx64Production.dll' 
or one of its dependencies. error details:
System.BadImageFormatException: 
    Could not load file or assembly 'x64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.
  • mstest работает на 64-битной Windows 7
  • тестовая сборка построена как AnyCPU, чтобы она работала в 64-битной среде на 64-битном хосте (как указано здесь )
  • файл testsettings указывает
  • peverify и corflags ничего интересного не показывают
  • это легко воспроизвести в игрушечном растворе, то есть где
    • x64Production
      • ссылки нет других сборок
      • включает только пустой открытый интерфейс IExampleInterface
      • имеет , установленное на x64
    • AnyCPUTestingx64Production
      • ссылается только на x64Production.dll (т.е. эта проблема присутствует даже без ссылки на Microsoft.VisualStudio.QualityTools.UnitTestFramework)
      • включает только пустую реализацию x64Production.IExampleInterface
      • имеет для x64
  • nunit может загрузить и запустить тестовую сборку (после того, как я преобразовал все атрибуты теста)
    • но не является хорошим краткосрочным решением более крупной проблемы (которая включает в себя огромное количество файлов проекта)
  • та же проблема возникает, если проекты нацелены на 3,5 или 4,0
  • одинаковые проблемы возникают при использовании компилятора VS2008 или VS2010 c #
  • та же проблема возникает, если используется mstest от VS2010 или Test Agents
  • это mstest, который завершается неудачно при загрузке AnyCPUTestingx64Production - т.е. это не проблема при попытке загрузить сборку в неправильный QTAgent (в Process Monitor ничего не отображается, и переименование QTAgent32.exe не имеет никакого эффекта):
    *** Assembly Binder Log Entry  (09/02/2012 @ 09:44:26) ***

    The operation failed.
    Bind result: hr = 0x8007000b. An attempt was made to load a program with an incorrect format.

    Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
    Running under executable  C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe
    --- A detailed error log follows. 

    === Pre-bind state information ===
    LOG: User = David
    LOG: DisplayName = x64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
     (Fully-specified)
    LOG: Appbase = file:///D:/
    LOG: Initial PrivatePath = NULL
    LOG: Dynamic Base = NULL
    LOG: Cache Base = NULL
    LOG: AppName = MSTest.exe
    Calling assembly : AnyCPUTestingx64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
    ===
    LOG: This bind starts in default load context.
    LOG: Using application configuration file: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe.Config
    LOG: Using host configuration file: 
    LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
    LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
    LOG: Attempting download of new URL file:///D:/x64Production.DLL.
    LOG: Assembly download was successful. Attempting setup of file: D:\x64Production.dll
    LOG: Entering run-from-source setup phase.
    LOG: Assembly Name is: x64Production, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
    ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated.

Кто-нибудь еще установил, действительно ли это просто не поддерживается в тесте VS2010 mstest?

Ответы [ 10 ]

32 голосов
/ 27 декабря 2012

Я пришел сюда в поисках решения для аналогичной проблемы.Размещение этого ответа на случай, если найденное мной решение поможет кому-то другому.Это решило это для меня в Visual Studio (2012):

Добавить новый элемент -> Параметры теста Add Test Setting Item Изменить настройки теста Run test in 64 bit process По умолчанию установлено значение "Принудительное выполнение теста в 32bit process "

Из меню: Тест -> Настройки теста -> Выбрать файл настроек теста -> Выберите созданный файл настроек теста.

Теперь запустите тесты.

18 голосов
/ 07 января 2014

Теперь с Visual Studio 2013 (по крайней мере, не пробовал в 2012 году) мне не нужно было ничего делать, кроме как выбрать Тест-> Параметры теста-> Архитектура процессора по умолчанию-> x64.Можно также использовать файл настроек теста для достижения того же результата.Ни один из этих старых клугесов не нужен в других ответах и ​​различных публикациях в Интернете.Поскольку мои вещи должны использовать x64, я также добавил эти тестовые примеры, чтобы напомнить мне, если у меня неправильные настройки.

    [TestMethod]
    public void Running_64Bit_OS()
    {
        // It was determined to run only in 64 bits.
        bool is64BitOS = System.Environment.Is64BitOperatingSystem;
        Assert.AreEqual(is64BitOS, true);
    }

    [TestMethod]
    public void Running_64Bit_Process()
    {
        // We have a requirement that one of the unmanaged DLL is built for 64 bits.
        // If you are running MS Test in Visual Studio 2013 and this
        // is failing, go to Test->Test Settings->Default Processor Architecture and
        // chose x64, then run the tests again.  This is not the only method.  You
        // could also use a test settings file.
        bool is64BitProcess = System.Environment.Is64BitProcess;
        Assert.AreEqual(is64BitProcess, true);
    }
13 голосов
/ 20 августа 2015

Также вы можете перейти в меню Test-> Test Settings-> Default Procesor Architecture-> X64Это может сработать.

12 голосов
/ 09 февраля 2012

После прочтения MSTest.exe становится 32-битным.

3 голосов
/ 30 апреля 2015

В моем случае это не имело ничего общего с платформой x86 или x64 или настройками конфигурации тестирования или версией .NET проекта. Кстати, ошибка BadImageFormatException, которую я получил, также упоминала что-то о «подпись неверна».

Проблема заключалась в том, что при использовании Moq нам нужно добавить отсутствующие ссылки в проект модульного теста для классов / интерфейсов, которые зависят от объекта, который мы пытаемся смоделировать. Посмотрите ссылки на проект, который вы тестируете, чтобы понять, какие сборки могут отсутствовать, связанные с объектом, над которым вы работаете.

http://vibrantcode.com/2012/05/18/badimageformatexception-the-signature-is-incorrect/

2 голосов
/ 24 декабря 2014

Если у вас установлен ReSharper, обратитесь к следующей ссылке

Как правило, вам нужно создать тестовый файл настроек в вашем решении, как указано в других ответах, затем обновить параметр ReSharperчтобы MsTest указывал на тот же файл настроек.

Я справляюсь с этой проблемой, используя Visual Studio 2013 Update 4 и Resharper 8.2.

1 голос
/ 28 апреля 2018

Как настроить MSTest для тестирования 64-битной сборки

В дополнение к информации .testsettings, предоставленной другими ответчиками по этому вопросу, этот ответ покрывает некоторые особенности Visual Studio 2015 и более ранних версий Visual Studio 2017, это исправление также может работать для Visual Studio 2013, но я не у меня нет машины для тестирования.

1. Добавить файл .testsettings

Щелкните правой кнопкой мыши на Solution (не на модульном тестовом проекте), затем в категории «Настройки теста» добавьте файл .testsettings. Его можно назвать как угодно.

Add test settings window screenshot


2. Сконфигурируйте файл .testsettings для использования 64-битного процесса

В появившемся мастере «Настройки теста» единственная вещь, которую вы должны настроить, - на вкладке «Хосты» установите «Запуск тестов в 32-битном или 64-битном процессе» на «Запуск тестов в 64-битном процессе». на 64-битной машине ". Пока вы здесь, возможно, стоит проверить настройки по умолчанию, чтобы убедиться, что они имеют смысл. Нажмите Apply, затем Close, когда вы закончите.

Test settings configuration window, showing where to set it to 64 bit

Теперь ваш файл .testsettings будет отображаться в обозревателе решений.

Image showing the test settings file in the solution explorer


Дополнительный обход ошибки в Visual Studio 2015

  • Похоже, что Visual Studio 2017 (протестировано с использованием версии 15.3.3 Community) сделала шаги 3 и 4 ненужными. Я оставлю эти шаги здесь для тех из вас, кто использует более старые версии Visual Studio, или если есть способ воспроизвести поведение.

  • В Visual Studio 2015, если вы просто установите архитектуру процессора по умолчанию через Тест -> Параметры теста -> Архитектура процессора по умолчанию -> x64, Visual Studio забудет ваши настройки ( см. Этот отчет об ошибке ). Это было протестировано в Visual Studio 2015 Professional Update 3.

  • Из того, что я прочитал, Visual Studio 2013 имеет ошибку, аналогичную Visual Studio 2015, когда речь идет о запоминании архитектуры процессора. Я не проверял это в Visual Studio 2013 (у меня его нет), но, возможно, стоит попробовать.

3. Добавьте файл .runsettings, чтобы сделать ваши тесты постоянно 64-битными

Откройте блокнот (или выбранный вами редактор XML-файлов) и вставьте его в него.

<?xml version="1.0" encoding="utf-8"?>  
<RunSettings>  
    <!-- Configurations that affect the Test Framework -->  
    <RunConfiguration>  
        <!-- [x86] | x64 -->  
        <TargetPlatform>x64</TargetPlatform> 
    </RunConfiguration> 
</RunSettings> 

Затем сохраните файл, я сохранил его как DemoTest.runsettings в каталоге моего решения вместе с DemoTest.testsettings.

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

  • Примечание. Безопасно иметь файл .runsettings, содержащий только эту запись, потому что ...

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

  • Я рекомендую добавить ваш файл .runsettings в ваше решение, чтобы разработчики могли видеть его в Solution Explorer, хотя это никак не влияет на функциональность.


4. Загрузите ваш файл .runsettings

В строке меню выберите Тест -> Настройки теста -> Выбрать файл настроек теста

Image showing how to load a test settings file using the Test menu

Выберите файл runsettings . Не ваш файл testsettings.


Теперь вы сможете запускать тесты без проблем.

image showing that the tests are okay

Ограничения MSTest

  • Обратите внимание, что MSTest будет работать только с проектами модульного тестирования, скомпилированными как Любой ЦП. Тестовый проект x64 не будет показывать никаких тестов в Test Explorer.

  • Проверяемая сборка может быть x64, но сама библиотека модульного тестирования должна быть Любой ЦП.

Configuration manager showing that the unit test library must be built as Any CPU

1 голос
/ 10 февраля 2012

Следуя этой записи в блоге , следующее, запускаемое из командной строки VS (так что CorFlags.exe находится в PATH), запускает тесты для моего игрушечного решения:

@echo off
REM remove the 32Bit flag, forcing the executable to be 64-bit when run on a 64 bit os.
REM Expect the following output:
REM "
REM corflags : warning CF011 : The specified file is strong name signed.  Using /Force will invalidate the signature of this image and will require the assembly to be resigned.
REM "
CorFlags.exe "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe" /32BIT- /Force

REM skip the strong name verification, because the 32-bit flag was modified 
reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\StrongName\Verification\MSTest,b03f5f7f11d50a3a /f

REM copy over registry keys to the 64-bit shadow registry.
REM Without the "{13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b}\Extensions" subkey, mstest will output
REM "
REM File extension specified '.dll' is not a valid test extension.
REM "
reg copy HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\EnterpriseTools\QualityTools\TestTypes HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\EnterpriseTools\QualityTools\TestTypes /s /f

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

0 голосов
/ 05 августа 2015

В дополнение к решению @Anupam на VS2013 вы можете перейти к ТЕСТ> Настройки теста> Архитектура процессора по умолчанию и изменить значение между X86 и X64 . Это почти то же самое, что и выбор файла настроек теста, за исключением того, что вам не нужен файл только для указания тестовой платформы.

0 голосов
/ 08 июля 2015

Спасибо за совет по Resharper, потому что он указал, что проблемы можно избежать, переключившись на MSTest.Я не мог заставить Решарпера работать.Тестирование 64-битной сторонней 64-битной DLL, даже если вы только издеваетесь над ней (все еще нужно ее загрузить), похоже, работает только с MsTest в 64-битном режиме.Параметр Resharper для MSTest «Использовать эту конфигурацию тестового запуска» имеет только «По умолчанию» в качестве параметра раскрывающегося списка, а «Редактировать» отображается серым цветом.Другой параметр «Использовать конфигурацию тестового запуска, указанный в файле метаданных» также не работает, и это предполагает, что кто-то знает, что или где находится этот файл метаданных.Resharper не будет работать в 64-битном режиме, что подтверждается приведенной выше переменной среды Is64BitProcess.(VS 2013, обновление 4, Resharper 8.2)

...