user3617723
user3617723

Reputation: 1395

Xamarin SQLite Unit Testing 64-Bit Windows

I'm developing a Xamarin application that uses a SQLite database, we have unit testing to cover this functionality.

These unit tests execute and pass on an OS X machine but we see SQLite related errors when running them on Windows 8 (64-Bit) VM (this acts as a slave within out CI infrastructure).

The error we see comes from NUnit (2.6.4) when the tests run

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)

Is this related to the fact that were using 64-bit windows?

Upvotes: 0

Views: 192

Answers (1)

Rob Prouse
Rob Prouse

Reputation: 22647

BadImageFormat is almost always because there is a mismatch between the bitness of the running process and the bitness of a dependent assembly. As you probably know, Sqlite is not AnyCPU, but x86 or x64. It is likely that your test suite is compiled AnyCPU but you are using the 32 bit version of Sqlite.

NUnit 3 will auto-detect the bitness of your test suite (but not dependent assemblies) and run it properly. NUnit 2 will not and you have to run your tests accordingly. From the NUnit 2.6 docs,

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.

Poorly written and we should probably fix it, but I would recommend two things;

  1. Ensure that your test assembly targets x86/x64 to match Sqlite
  2. If you are using x86, run your tests with nunit-console-x86.exe

Upvotes: 2

Related Questions