Vb.net 单元测试不一致的通过或失败结果
我的一个单元测试在运行时似乎随机通过或失败。对于发生这种情况的原因,对我来说唯一有意义的是,如果每次运行测试时数据库中的数据都进入不同的状态,但我在每次测试中都使用事务回滚数据库,除非它工作不正常。这是我的基本单元测试类和有问题的单元测试类。你能看到我可能丢失的东西吗?或者我应该找什么 这在TestDriven.Net和VisualStudio单元测试框架中发生Vb.net 单元测试不一致的通过或失败结果,vb.net,visual-studio-2010,unit-testing,transactions,testdriven.net,Vb.net,Visual Studio 2010,Unit Testing,Transactions,Testdriven.net,我的一个单元测试在运行时似乎随机通过或失败。对于发生这种情况的原因,对我来说唯一有意义的是,如果每次运行测试时数据库中的数据都进入不同的状态,但我在每次测试中都使用事务回滚数据库,除非它工作不正常。这是我的基本单元测试类和有问题的单元测试类。你能看到我可能丢失的东西吗?或者我应该找什么 这在TestDriven.Net和VisualStudio单元测试框架中发生 Partial Public MustInherit Class TestBase Private _scope As Tr
Partial Public MustInherit Class TestBase
Private _scope As Transactions.TransactionScope
<DebuggerStepThrough()> _
<TestInitialize()> _
Public Sub Setup()
//'Start the Distribution Transaction Coordinator, if it's not already running.
Using dtcService As New System.ServiceProcess.ServiceController("Distributed Transaction Coordinator", My.Computer.Name)
If dtcService.Status = ServiceProcess.ServiceControllerStatus.Stopped Then
dtcService.Start()
End If
End Using
_scope = New TransactionScope(TransactionScopeOption.RequiresNew, New TimeSpan(0))
End Sub
<DebuggerStepThrough()> _
<TestCleanup()>
Public Sub Teardown()
If _scope IsNot Nothing Then
_scope.Dispose()
End If
End Sub
<System.Diagnostics.DebuggerStepThrough()> _
Public Shared Function ExecSql(ByVal sql As String) As System.Data.DataTable
Dim connStr = GlobalSettings.GetConnectionString()
Using conn As New System.Data.SqlClient.SqlConnection(connStr)
conn.Open()
Dim cmd As New System.Data.SqlClient.SqlCommand(sql.ToString, conn)
Dim adapter As System.Data.SqlClient.SqlDataAdapter = New System.Data.SqlClient.SqlDataAdapter(cmd)
Dim dt As System.Data.DataTable = New System.Data.DataTable
adapter.Fill(dt)
Return dt
If conn.State <> System.Data.ConnectionState.Closed Then
conn.Close()
End If
conn.Dispose()
End Using
End Function
End Class
部分公共MustInherit类TestBase
私有范围作为事务。事务范围
_
_
公共子设置()
//'启动分发事务协调器(如果尚未运行)。
将dtcService用作新的System.ServiceProcess.ServiceController(“分布式事务协调器”,My.Computer.Name)
如果dtcService.Status=ServiceProcess.ServiceControllerStatus.Stopped,则
dtcService.Start()
如果结束
终端使用
_范围=新TransactionScope(TransactionScopeOption.RequiresNew,新时间跨度(0))
端接头
_
公共子拆卸()
如果范围不是零,那么
_scope.Dispose()
如果结束
端接头
_
公共共享函数ExecSql(ByVal sql作为字符串)作为System.Data.DataTable
Dim connStr=GlobalSettings.GetConnectionString()
将conn用作新的System.Data.SqlClient.SqlConnection(connStr)
康涅狄格州公开赛
Dim cmd作为新的System.Data.SqlClient.SqlCommand(sql.ToString,conn)
Dim适配器为System.Data.SqlClient.SqlDataAdapter=New System.Data.SqlClient.SqlDataAdapter(cmd)
Dim dt As System.Data.DataTable=新System.Data.DataTable
适配器填充(dt)
返回dt
如果连接状态System.Data.ConnectionState.Closed,则
康涅狄格州关闭
如果结束
康涅狄格州
终端使用
端函数
末级
下面是我的单元测试:
Partial Public Class CampaignEmailSendLimitServiceTests
Inherits TestBase
Private _service = ServiceManager.Current.MyService
<TestMethod()> _
Public Sub MyTest()
//' Set the pre-test condition.
ExecSql("update base.dbo.tblTableA set someDate = '2010-06-28' where id = 56937 ")
//' Run the service
_service.Process()
//' Verify the expected result
Dim dt = ExecSql("select deliveryDate from tblTableB ")
Assert.AreEqual(False, dt.Rows(0).IsNull("deliveryDate"))
End Sub
End Class
部分公共类活动EmailSendLimitServiceTests
继承TestBase
Private\u service=ServiceManager.Current.MyService
_
公共子测试()
//'设置预测试条件。
ExecSql(“updatebase.dbo.tblTableA set someDate='2010-06-28',其中id=56937”)
//“运行服务
_服务流程()
//'验证预期结果
Dim dt=ExecSql(“从tblTableB中选择交货日期”)
Assert.AreEqual(False,dt.Rows(0).IsNull(“deliveryDate”))
端接头
末级
这对我来说一直很好。我看到的主要区别是使用TransactionScopeOption.Required
[TestClass()]
public class MyTest: DatabaseTestClass
{
public MyTest()
{
InitializeComponent();
}
TransactionScope ambientTransaction;
[TestInitialize()]
public void TestInitialize()
{
ambientTransaction = new TransactionScope(TransactionScopeOption.Required);
base.InitializeTest();
}
[TestCleanup()]
public void TestCleanup()
{
ambientTransaction.Dispose();
base.CleanupTest();
}
}
为什么要使用DataAdapter.Fill执行更新?它被设计为用select语句填充数据表 我的猜测是,您最初并没有使用ExecSql向数据库写入任何内容 第二件事。那个断言尽可能不可读。 我会改变
Assert.AreEqual(False, dt.Rows(0).IsNull("deliveryDate"));
到
或
不可读的测试是一些人说单元测试不好的原因之一,因为它会减慢你的速度。您必须使单元测试尽可能容易阅读和理解。这样他们就不会反对单元测试;)
可能会有一些打字错误,因为我不使用VB.NET。断言示例来自NUnit。我终于弄明白了到底发生了什么。这与交易无关。一切都很好。这是我的过程,创造了不一致的行为-通过设计。在这个过程中,有一部分是“随机排名”的,如果没有其他排名的话,就可以确定交货日期。需要重写单元测试以更好地反映业务规则。是在运行一整套测试,还是只是反复运行此测试?您可能想反复运行这个测试,看看它是否仍然不一致。如果它在单独运行时工作正常,那么您可能会遇到另一个测试,该测试没有适当地清理数据库状态。不,我只是反复运行此测试。感谢您提供的格式化提示,但这并不能回答我的问题。格式化注释是一个额外的功能。我说了我认为你做错的事。但你不听。DataAdapter.Fill不用于向数据库发送数据。如果您不展示服务流程中的内容,您如何期望得到好的答案?我认为否决票在这里是很不礼貌的。不幸的是,如果我把它改为必选票,这种情况仍然会发生。
Assert.IsFalse(dt.Rows(0).IsNull("deliveryDate"));
Assert.That(dt.Rows(0)("deliveryDate"), Is.Not.Null));