64 位机器上的 nUnit 异常
我有一个 MVC 3.0 应用程序。我的测试框架是nUnit 2.4.8.0。我在 32 位机器上开始这段代码,最近开始使用 64 位机器。我最近将项目升级到.NET 4.0。
我的应用程序运行良好 - 我能够适当地从数据库中水合我的对象。问题是当我运行集成测试时。
测试失败,并给出了一个我以前从未见过的异常:
NHibernate.ADOException : cannot open connection
----> System.BadImageFormatException : An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
我在网上搜索了这个异常 - 这当然是 nUnit 的问题,尽管 NHibernate 异常(记住,NHibernate 允许我在运行时水合并持久化对象)应用程序)。
我将 nUnit 程序集升级到最新版本 2.5.10,并将项目中的引用更新为 nUnit zip 文件的“net-2.0”文件夹下的程序集。我再次运行测试,并收到相同的异常。
程序集、代码和 ASP.NET 开发服务器之间似乎存在某种 32 位与 64 位冲突。
我没有任何处理 32 位与 64 位问题的经验,所以我不知道是否还有其他相关的堆栈溢出问题(我见过的问题似乎不相关)。我有一些想法,但没有答案:
- 我需要不同的 nUnit 程序集吗?
- 我需要更改 VS2010 中的解决方案平台设置吗? (目前位于“任何 CPU”上)
- 我是否需要更改集成测试项目的构建属性?
- 我需要更改解决方案的配置设置吗?
不幸的是,我目前没有 32 位机器来测试代码。上述问题是否是解决此问题的正确途径?您能提供任何指导吗?
谢谢。
更新: 我真的希望能够使用 TestDriven.NET 在 Visual Studio 中运行测试。我不想必须开始使用 nunit UI 来运行我的测试。
更新2: 抱歉,我可能没说清楚。我还没有使用TestDriven.NET,我说的是我希望使用它,但我还没有在新的x64机器上安装它。此时,我尝试通过单击 Visual Studio IDE 内的可视图标来运行测试,如下图所示:
执行该操作后,测试失败,弹出的对话框显示以下内容:
那就是我上面引用的例外。没有对尚未加载的程序集的引用。
起初我不相信我使用的 NHibernate (2.0.1.4000) 版本有什么关系;我这样说是因为提供程序能够在应用程序运行时从数据库返回所需的对象。但是,当我调试测试时,我发现我的提供程序中抛出了异常。当深入挖掘时,它的来源似乎是我的 SQLite 程序集。但同样,这与我运行项目时可以工作的程序集相同 - 为什么当我运行集成测试时它不能工作?
I have an MVC 3.0 app. My testing framework is nUnit 2.4.8.0. I started this code on a 32 bit machine, and recently started using a 64 bit machine. I just as recently upgraded the project to .NET 4.0.
My application runs fine - I am able to hydrate my objects from the database appropriately. The issue is when I run my integration tests.
The tests fail, and give an exception I've never seen before:
NHibernate.ADOException : cannot open connection
----> System.BadImageFormatException : An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
I've searched online for this exception - It's of course a problem with nUnit, despite the NHibernate exception (remember, NHibernate allows me to hydrate and persist objects when I run the app).
I upgraded my nUnit assembly to the most recent release, version 2.5.10, and updated the reference in the project to the assembly under the 'net-2.0' folder of the nUnit zip file. I ran the tests again, and received the same exception.
It seems that there is some sort of 32-bit vs 64-bit conflict between assemblies, code, and the ASP.NET Development Server.
I don't have any experience dealing with 32-bit vs 64-bit issues, so I don't know if there are other questions on stack overflow that are relevant (the ones I've seen seem not to be). I have some ideas, but no answers:
- Do I need a different nUnit assembly?
- Do I need to change the Solution Platform setting in VS2010? (It's currently on "Any CPU")
- Do I need to change build properties of my integration tests project?
- Do I need to change configuration settings of my solution?
Unfortunately I don't have a 32-bit machine around to test the code on at the moment. Are any of the above questions on the right path to solving this? Can you offer any guidance?
Thanks.
UPDATE:
I'm really hoping to be able to run the tests from within Visual Studio using TestDriven.NET. I don't want to have to start using the nunit UI to run my tests.
UPDATE 2:
Sorry, I may not have been clear. I'm not yet using TestDriven.NET, what I said is that I'm hoping to use it, but I haven't installed it yet on the new x64 machine. At this moment, I'm trying to run the tests by clicking on the visual icon inside the Visual Studio IDE, as in the image below:
Following through with that action, the tests fail, and the dialog that pops up displays the following:
That is the exception that I quoted up above. There is no reference to assemblies that haven't loaded.
At first I didn't believe that the version of NHibernate (2.0.1.4000) I am using would matter; I say this because the providers are able to return the desired objects from the database when the app is run. However, When I debug the test, I see that the exception is being thrown in my provider. When digging down a bit, It seems the source of this is my SQLite assembly. But again, this is the same assembly that works when I run the project - why would it not work when I run the integration tests?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
nUnit-x86.exe 是 32 位可执行文件,而 nUnit.exe 是 64 位可执行文件。因此,请使用 32 位可执行文件来查看是否可以解决问题。
将 AnyCPU 用于 DLL。导致此问题的原因是加载 dll 的 exe 的设置。 (32 位 exe 无法加载 64 位 dll,反之亦然)。
The nUnit-x86.exe is the 32 bit executable whereas nUnit.exe is the 64-bit one. So use the 32-bit executable to see if that solves things.
Use AnyCPU for DLLs. It's the setting for the exe that loads the dll that causes this problem. (32 bit exe cannot load 64 bit dlls or vice versa).
这是我经常遇到的问题。
System.Data.SQLite 是一个 32 或 64 位特定程序集,因为它将 SQLite 的本机映像捆绑在 DLL 内。 NUnit 测试运行程序试图以错误的模式运行它,即 32 位测试运行程序中的 64 位程序集,并且当它尝试对 SQLite C API 进行本机调用时,它会崩溃。 Windows 无法做到这一点。
我建议您在 32 位或 64 位(即您的开发环境和部署环境)上的所有平台上进行标准化。
中间修复方法是将 SQLite DLL 替换为 64 位 DLL,可从此处获取:http://system .data.sqlite.org/。然而,这可能会在部署时中断,此时您需要为您的实时环境创建一个构建配置,该配置提供正确的 DLL 版本(32/64 位)。
让 NUnit 在 32 位或 64 位模式下确定性地运行是一件痛苦的事情,所以我个人不会为此烦恼。
This is a problem I get regularly.
System.Data.SQLite is a 32 or 64 bit specific assembly as it bundles a native image for SQLite inside the DLL. The NUnit test runner is trying to run it in the wrong mode i.e. a 64-bit assembly in a 32-bit test runner and it's going bang when it tries to make a native call to the SQLite C API. Windows can't do that.
I suggest you standardise across all platforms on either 32-bit or 64-bit i.e. your dev environment and your deployment environment.
An intermediate fix will be to replace the SQLite DLL with a 64-bit one as available from here: http://system.data.sqlite.org/. this may however break at deploy time at which point you will need to create a build configuration for your live environment which ships the right DLL version (32/64-bit).
Getting NUnit to deterministically run in either 32 or 64 bit mode is a pain so I wouldn't bother with that personally.
从您的屏幕截图来看,您正在使用 Resharper 测试运行程序。
根据我的经验,Resharper 的测试运行程序使用主机环境中加载的测试程序集指定的适当位数。
因此,如果您的测试堆栈中有一个项目依赖于 32 位(即 x86)某些东西(例如在当前构建配置中设置为构建为 x86 的测试项目,或者引用了程序集标记为 x86),那么您最好将消耗该东西(包括测试项目)的所有内容标记为 x86。
通过 Visual Studio resharper 测试运行程序运行设置为 x86 构建的测试项目似乎会加载到 32 位进程中,并在也标记为 x86 的程序集上成功运行测试。
啊,支持多平台的问题。
It appears from your screenshots that you are using the Resharper test runner.
In my experience Resharper's test runner uses the appropriate bitness as specified by the test assembly being loaded in the host environment.
As such, if you have a project in your tested stack that depends on a 32-bit (i.e. x86) something (such as a project under test set to build as x86 in the current build configuration, or a project with a reference to an assembly marked as x86) then you would do well to mark everything that consumes that thing (including test projects) to build as x86.
Running a test project set to build as x86 through the visual studio resharper test runner appears to load in a 32-bit process and successfully run tests on an assembly that is also marked as x86.
Ah, the problems of supporting multiple platforms.