简体   繁体   English

从命令提示符运行单元测试失败

[英]Running unit test from command prompt fails

Currently I am struggeling with some unit tests that run fine from within visual studio but fail in Teamcity 目前,我正在进行一些单元测试,这些测试在视觉工作室内运行良好但在Teamcity中失败

I tracked down the problem to mstests.exe 我将问题跟踪到mstests.exe

Let's say I do the following steps: 假设我执行以下步骤:

  1. Create a new Test project 创建一个新的测试项目
  2. Add a new Test class with the following test 使用以下测试添加新的Test类

     [TestMethod] public void TestCanCreateSqLiteConnection() { // Create the DbProviderFactory var factory = DbProviderFactories.GetFactory("System.Data.SQLite"); // Create the DbConnection. var connection = factory.CreateConnection(); // Assign connection string connection.ConnectionString = "Data Source=database.sqlite"; // check the result Assert.IsTrue(connection.GetType().Name.Equals("SQLiteConnection")); } 
  3. Add an app.config file and add this: 添加app.config文件并添加:

     <system.data> <DbProviderFactories> <remove invariant="System.Data.SQLite" /> <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /> </DbProviderFactories> </system.data> 
  4. Install "System.Data.SQLite (x86/x64)" via nuget 通过nuget安装“System.Data.SQLite(x86 / x64)”

  5. Run test from Visual Studio (2010). 从Visual Studio(2010)运行测试。 It should run fine: 应该运行正常:

Now I want to run the same test via mstest.exe so I: 现在我想通过mstest.exe运行相同的测试,所以我:

  1. Open a Visual Studio 2010 command prompt 打开Visual Studio 2010命令提示符

  2. Navigate to the bin\\debug folder 导航到bin \\ debug文件夹

  3. Execute 执行

     mstest.exe /testcontainer:TestProject1.dll /detail:errormessage 
  4. The test eventually failes with 测试最终会失败

     System.DllNotFoundException: Unable to load DLL 'SQLite.Interop.DLL': The specified module could not be found. (Exception from HRESULT:0x8007007E) 
  5. Now if I extend the call to mstest.exe with testsettings the test runs fine. 现在,如果我使用testsettings将调用扩展到mstest.exe,那么测试运行正常。

     mstest.exe /testcontainer:TestProject1.dll /detail:errormessage testsettings:..\\..\\..\\Local.testsettings 

The Local.testsettings contains nothing special, even if I create a new testsettings file and use this, the test passes. Local.testsettings没有任何特殊之处,即使我创建了一个新的testsettings文件并使用它,测试也会通过。

    <?xml version="1.0" encoding="UTF-8"?>
    <TestSettings id="fc837936-41d1-4987-8526-34f9336569f5" name="TestSettings1" enableDefaultDataCollectors="false" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
      <Description>default test run</Description>
      <Deployment enabled="false"/>
    </TestSettings>

So the main question is, why this has an impact on my test run, and how I can run my tests form commandline without specifying a *.testsettings file. 所以主要的问题是,为什么这会对我的测试运行产生影响,以及如何在不指定* .testsettings文件的情况下运行我的测试表单命令行。

You need to use a DeploymentItem to ensure the file is copied to the deployment directory when testing via the command line. 您需要使用DeploymentItem来确保在通过命令行进行测试时将文件复制到部署目录。 I created a base class for all of my test classes that depend on the SQLite database. 我为依赖于SQLite数据库的所有测试类创建了一个基类。

[TestClass]
[DeploymentItem("Resources\\empty-db.sqlite", "Resources")]
[DeploymentItem("x64\\SQLite.Interop.dll", "x64")]
[DeploymentItem("x86\\SQLite.Interop.dll", "x86")]
public class SQLiteTest
{
    [TestInitialize()]
    public void ClearDatabase()
    {
        File.Copy("Resources\\empty-db.sqlite", "test-db.sqlite", true);
    }
}

I encountered a similar error message a while back. 我不久前遇到了类似的错误消息。 If I remember correctly, the following was the crux of the issue: (it may not be 100% relevant for the OP, but it might be useful to somebody who hits this down the line). 如果我没记错的话,以下是问题的症结所在:(它可能与OP没有100%的相关性,但它可能对那些打击这个问题的人有用)。

The problem was that my unit tests all failed in Release mode with an exception complaining about the availability (or lack thereof) of the SQLite.Interop.dll. 问题是我的单元测试都在发布模式下失败,但有一个例外是抱怨SQLite.Interop.dll的可用性(或缺乏)。 I realised that when built in Debug mode, the bin\\Debug folder had 2 sub folders (x64 and x86) each with a copy of SQLite.Interop.dll but, in Release mode these files/folders did not exist. 我意识到,当在Debug模式下构建时,bin \\ Debug文件夹有2个子文件夹(x64和x86),每个子文件夹都有一个SQLite.Interop.dll副本,但是在Release模式下,这些文件/文件夹不存在。

To resolve it, I created the x64 and x86 folders in my project and added the appropriate version of SQLite.Interop.dll too them, setting the Copy to ouput setting to Copy if newer . 为了解决这个问题,我在项目中创建了x64和x86文件夹,并添加了相应版本的SQLite.Interop.dll,将Copy to ouput of Copy to ouput设置为Copy if newer (I had originally used 'Copy always' but it seems the MS Test engine doesn't shut down when the test run is complete - which can lock the file. Since the dll shouldn't change regularly the Copy if newer option was a suitable approach). (我最初使用'总是复制',但似乎MS测试引擎在测试运行完成时没有关闭 - 这可以锁定文件。由于dll不应该定期更改,因此Copy if newer选项是合适的方法)。

This enabled my unit tests to pass in release mode - but unfortunately (as in the OP's case) they did not work when run from the command line. 这使我的单元测试能够在释放模式下通过 - 但不幸的是(在OP的情况下),从命令行运行时它们不起作用。 Still trying to figure that one out - I think it's because MSTest is 32-bit and SQLite uses native code which is (maybe) 64-bit but the finer detail necessary to resolve this eludes me at present. 仍然试图找出那个 - 我认为这是因为MSTest是32位而SQLite使用本机代码(可能)是64位但是目前解决这个问题所需的更精细的细节使我望而却步。

Two year later and it is still a pain to get SQLite working in unit tests. 两年后,让SQLite在单元测试中工作仍然是一件痛苦的事。

Yesterday I included the current SQLite nuget package into a unit test project with <Deployment enabled="true"/> enabled and could not access sqlite by the dbproviderfactories method. 昨天我将当前的SQLite nuget包包含到单元测试项目中, <Deployment enabled="true"/><Deployment enabled="true"/>并且无法通过dbproviderfactories方法访问sqlite。

I included the SQLite interop directories with 我包含了SQLite互操作目录

<Deployment>
  <DeploymentItem filename="packages\System.Data.SQLite.Core.1.0.98.1\build\net40\" />
</Deployment>

But that was not enough. 但这还不够。 Accessing the provider with 使用访问提供程序

DbProviderFactories.GetFactory("System.Data.SQLite");

still threw an error Failed to find or load the registered .Net Data Provider error unless I made this call var factory = new System.Data.SQLite.SQLiteFactory(); 仍然抛出错误Failed to find or load the registered .Net Data Provider error除非我进行了此调用var factory = new System.Data.SQLite.SQLiteFactory(); After that I could acces SQLite witht the DbProviderFactories. 之后我可以使用DbProviderFactories访问SQLite。

I included this in the ClassInitialize method so is is only executed once. 我将它包含在ClassInitialize方法中,因此只执行一次。

I've encountered a similar issue where the tests run through fine in Visual Studio 2013 but if run directly by MSTest many would fail. 我遇到过一个类似的问题,在Visual Studio 2013中测试运行良好,但如果直接由MSTest运行,很多都会失败。 No SQL Lite used! 没有使用SQL Lite!

In the end I just added a default .testsettings file to the MSTest call and now the results are consistant. 最后,我刚刚在MSTest调用中添加了一个默认的.testsettings文件,现在结果是一致的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM