Xamarin SQLite 单元测试 64 位 Windows

Xamarin SQLite Unit Testing 64-Bit Windows

我正在开发一个使用 SQLite 数据库的 Xamarin 应用程序,我们有单元测试来涵盖此功能。

这些单元测试在 OS X 机器上执行并传递,但是当 运行 在 Windows 8(64 位)VM 上运行它们时我们看到 SQLite 相关错误(这作为 CI 基础设施内的奴隶)。

当测试 运行

时,我们看到的错误来自 NUnit (2.6.4)
ProcessModel: Default    DomainUsage: Single
Execution Runtime: net-4.5
Unhandled Exception:
System.BadImageFormatException: Could not load file or assembly 'App.Core.Tests, Version=1.0.5900.25009, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.
File name: 'App.Core.Tests, Version=1.0.5900.25009, Culture=neutral, PublicKeyToken=null'

Server stack trace: 
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String  codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
at NUnit.Core.Builders.TestAssemblyBuilder.Load(String path)
at NUnit.Core.Builders.TestAssemblyBuilder.Build(String assemblyName, Boolean autoSuites)
at NUnit.Core.Builders.TestAssemblyBuilder.Build(String assemblyName, String testName, Boolean autoSuites)
at NUnit.Core.TestSuiteBuilder.BuildSingleAssembly(TestPackage package)
at NUnit.Core.TestSuiteBuilder.Build(TestPackage package)
at NUnit.Core.SimpleTestRunner.Load(TestPackage package)
at NUnit.Core.ProxyTestRunner.Load(TestPackage package)
at NUnit.Core.ProxyTestRunner.Load(TestPackage package)
at NUnit.Core.RemoteTestRunner.Load(TestPackage package)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(RuntimeMethodHandle md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
 at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
 at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
 at NUnit.Core.TestRunner.Load(TestPackage package)
 at NUnit.Util.TestDomain.Load(TestPackage package)
 at NUnit.ConsoleRunner.ConsoleUi.Execute(ConsoleOptions options)
 at NUnit.ConsoleRunner.Runner.Main(String[] args)

这与使用 64 位 windows 的事实有关吗?

BadImageFormat 几乎总是因为 运行ning 进程的位数与依赖程序集的位数不匹配。你可能知道,Sqlite 不是 AnyCPU,而是 x86 或 x64。您的测试套件很可能是 AnyCPU 编译的,但您使用的是 32 位版本的 Sqlite。

NUnit 3 将自动检测您的测试套件(但不包括依赖程序集)的位数,并且 运行 它会正确地检测出来。 NUnit 2 不会,您必须相应地 运行 您的测试。来自 NUnit 2.6 文档,

The .NET 2.0 version of the nunit-console program is built using /platform:anycpu, which causes it to be jit-compiled to 32-bit code on a 32-bit system and 64-bit code on a 64 bit system. This causes an exception when NUnit is used to test a 32-bit application on a 64-bit system. To avoid this problem, use the nunit-console-x86 program, which is built using /platform:x86, when testing 32-bit code on a 64-bit system.

写得不好,我们可能应该修复它,但我会推荐两件事;

  1. 确保您的测试程序集目标 x86/x64 以匹配 Sqlite
  2. 如果您使用的是 x86,运行 您使用 nunit-console-x86.exe
  3. 进行测试