我正在尝试使用 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.");
}
读数:
单元测试错误 - 单元测试适配器无法连接到数据源或读取数据
数据驱动的单元测试问题
如何为Visual Studio测试项目创建启动和清理脚本?
MSTEST/Visual Studio 2008 团队测试如何决定测试方法的执行顺序?
Visual Studio 2010 旗舰版 - 数据生成计划为列设置不正确的数据类型
我应该如何对简单的 CRUD 类进行单元测试?
我今天淡出了一个相同的任务。经过一些头痛,我能够在没有app.config的情况下解决:
[TestMethod]
[DataSource("System.Data.OleDB",
@"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:SheetsDataSheet.xlsx; Extended Properties='Excel 12.0;HDR=yes';",
"Sheet1$",
DataAccessMethod.Sequential
)]
public void ChangePasswordTest()
{
//Arrange
//Act
//Assert
}
如果在测试项目中将 Excel 文件用作资源,则必须将文件的"复制到输出目录"属性设置为 Copy always
或 Copy 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
}
我自己用不同的方式解决了。欢迎其他答案。
参考:演练:使用配置文件定义数据源 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,使用的测试工具版本为 Version=10.0.0.0
虽然它与问题不是 100% 相关,也许有些微不足道,但我想在这个一般主题上投入我的两分钱(这是我能找到的最相关的问题(。
在我目前正在从事的项目中,我遇到了需要做一些简单的数据驱动的单元测试(例如,给定测试可能有 20 行左右(。我对数据驱动的"框架"的愿望清单是:
- 在Visual Studio测试资源管理器中很好地和容易集成
- 能够继续使用我现有的键盘快捷键来运行/调试光标所在的测试方法 无需
- 管理外部文件或数据库(即无需"数据源"(
- 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}
});
}
虽然它满足了我上面的所有愿望,但它也有缺点:
- 测试操作定义中需要强制转换(可能可以通过一些通用参数魔法修复( 更新
- 数据行中参数的顺序意味着还必须更新操作方法中的访问器
- 显然不适合大数据驱动的测试(例如,这个帮助程序对于超过 20 个测试行会很混乱(
- 显然缺乏"复杂性",即我确信像 xUnit 这样的库具有一些时髦的功能,这是它所没有的
- 它将所有行作为一个单元测试运行(即没有针对每个数据行的单独单元测试和报告(
无论如何,它以简单的方式解决了我的基本问题。我希望这能帮助像我一样寻找简单解决方案的人。毕竟,如果您发现需要大量测试行来测试方法,则可能值得考虑重构以将所测试的函数分解为更小的组件(然后与模拟/伪造,依赖注入等结合使用(。