5

我正在尝试使用 Excel 作为数据源进行单元测试。我收到以下异常。我们如何纠正它?

单元测试适配器连接数据源或读取数据失败。有关解决此错误的更多信息,请参阅“数据驱动单元测试故障排除”


  [TestMethod]
  [Owner("Lijo ")]
  [TestProperty("TestCategory", "Developer"), 
      DataSource("Microsoft.ACE.OLEDB.12.0", 
     "Data Source=C:/Sheets/DataSheet.xlsx;Extended Properties=Excel 12.0;",
     "[Sheet1$]", 
     DataAccessMethod.Sequential)]
  public void ChangePasswordTest()
  {

     int a = Convert.ToInt32(TestContext.DataRow[0]); //(int)Column.UserId
     int b = Convert.ToInt32(TestContext.DataRow[1]);
     int expectedResult = Convert.ToInt32(TestContext.DataRow[2]);

     MyClass myObj = new MyClass(1, "P@ssw0rd");
     int actualResult = myObj.GetAdditionResult(a, b);
     Assert.AreEqual<int>(expectedResult, actualResult, "The addition result is incorrect.");

  }

读数:

  1. 单元测试错误 - 单元测试适配器未能连接到数据源或读取数据

  2. 数据驱动的单元测试问题

  3. 如何为 Visual Studio 测试项目创建启动和清理脚本?

  4. MSTEST/Visual Studio 2008 Team Test 如何决定测试方法的执行顺序?

  5. Visual Studio 2010 Ultimate - 数据生成计划为列设置不正确的数据类型

  6. 我应该如何对一个简单的 CRUD 类进行单元测试?

4

3 回答 3

5

我今天淡化了同样的任务。经过一些头痛后,我能够在没有 app.config 的情况下解决:

[TestMethod]
[DataSource("System.Data.OleDB",
  @"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\Sheets\DataSheet.xlsx; Extended Properties='Excel 12.0;HDR=yes';",
  "Sheet1$",
  DataAccessMethod.Sequential
)]       
public void ChangePasswordTest()
{
 //Arrange

 //Act

 //Assert

}

如果您在测试项目中使用 excel 文件作为资源,则必须将文件的 Copy to Output Directory 属性设置为Copy alwaysCopy if newer。并将DeploymentItem属性添加到您的测试中:

[TestMethod]
[DataSource("System.Data.OleDB",
  @"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=.\DataSheet.xlsx; Extended Properties='Excel 12.0;HDR=yes';",
  "Sheet1$",
  DataAccessMethod.Sequential
)]       
[DeploymentItem(".\DataSheet.xlsx")]
public void ChangePasswordTest()
{
 //Arrange

 //Act

 //Assert

}
于 2013-03-23T17:41:13.643 回答
4

自己以不同的方式解决了它。欢迎其他答案。

请参阅:演练:使用配置文件定义数据源 http://msdn.microsoft.com/en-us/library/ms243192.aspx

  [TestMethod]
  [DeploymentItem("C:/Sheets/DataSheet.xlsx")]
  [DataSource("MyExcelDataSource")]
  public void ChangePasswordTest()
  {

     int a = Convert.ToInt32(TestContext.DataRow[0]); //(int)Column.UserId
     int b = Convert.ToInt32(TestContext.DataRow[1]);
     int expectedResult = Convert.ToInt32(TestContext.DataRow[2]);

     MyClass myObj = new MyClass(1, "P@ssw0rd");
     int actualResult = myObj.GetAdditionResult(a, b);
     Assert.AreEqual<int>(expectedResult, actualResult, "The addition result is incorrect.");

  }

应用程序配置

<configuration>


<configSections>

<section name="microsoft.visualstudio.testtools" 
 type="Microsoft.VisualStudio.TestTools.UnitTesting.TestConfigurationSection, Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>

 </configSections>



 <connectionStrings>

<add name="MyExcelConn" 
     connectionString="Dsn=Excel Files;dbq=C:/Sheets/DataSheet.xlsx;defaultdir=.; driverid=790;maxbuffersize=2048;pagetimeout=5" providerName="System.Data.Odbc" />

 </connectionStrings>


 <microsoft.visualstudio.testtools>


  <dataSources>

      <add name="MyExcelDataSource" 
      connectionString="MyExcelConn" 
      dataTableName="Sheet1$" 
      dataAccessMethod="Sequential"/>

  </dataSources>


</microsoft.visualstudio.testtools>

</configuration>

对于 VS 2010,使用的 TestTools 版本是 Version=10.0.0.0

于 2012-05-21T12:55:09.320 回答
3

尽管它与问题不是 100% 相关,而且可能有些微不足道,但我想在这个一般主题上投入两分钱(这是我能找到的最相关的问题)。

在我目前正在进行的项目中,我遇到了做一些简单的数据驱动单元测试的需求(例如,对于给定的测试,可能需要 20 行左右)。我对数据驱动的“框架”的愿望清单是:

  1. 在 Visual Studio 测试资源管理器中轻松集成
  2. 能够继续使用我现有的键盘快捷键来运行/调试光标所在的测试方法
  3. 无需管理外部文件或数据库(即没有“数据源”)
  4. C# 和 Visual Studio 中的“本机”支持,即不需要额外的包

尽管希望 #4,我还是研究了 xUnit 和 NUnit 等外部库。他们似乎解决了愿望 #3,但在愿望 #1 和 #2 方面做得并不好。

由于缺乏简单的解决方案而感到沮丧,我决定自己实现一个非常基本的数据驱动助手:

    public static void DataDrivenTest(Action<List<object>> testAction, List<List<object>> dataRows)
    {
        foreach (var dataRow in dataRows)
            testAction(dataRow);
    }

我这样使用它:

    [TestMethod]
    public void Unit_Can_Add_Two_Numbers()
    {
        UnitTestUtilities.DataDrivenTest(
            dataRow =>
            {
                // Tests a+b=c
                var a = (int)dataRow[0];
                var b = (int)dataRow[1];
                var c = (int)dataRow[2];
                Assert.AreEqual(a + b, c);
            },
            new List<List<object>>
                {
                    // Rows of arguments a,b,c respectively
                    new List<object>{1,2,3},
                    new List<object>{4,5,9}
                });
    }

虽然它满足了我上面的所有愿望,但它也有缺点:

  1. 测试动作定义中需要强制转换(可能可以通过一些通用参数魔术来修复)
  2. 更新数据行中参数的顺序意味着操作方法中的访问器也必须更新
  3. 显然不适合大型数据驱动的测试(例如,对于超过 20 个测试行,这个助手会很混乱)
  4. 显然缺乏“复杂性”,即我确信像 xUnit 这样的库有一些它没有的时髦特性
  5. 它将所有行作为一个单元测试运行(即每个数据行没有单独的单元测试和报告)

无论如何,它以一种简单的方式解决了我的基本问题。我希望这可以帮助像我一样寻找简单解决方案的人。毕竟,如果你发现你需要大量的测试行来测试一个方法,那么可能值得考虑进行重构,将被测函数分解成更小的组件(然后与 mocks/fakes、依赖注入等结合使用) )。

于 2014-05-01T14:31:17.600 回答