0

我運行它時,其中一個單元測試似乎隨機通過或失敗。對我來說,唯一有意義的是,如果數據庫中的數據在每次運行測試時都進入不同的狀態,但我使用事務來回滾每個測試中的數據庫 - 除非它沒有正常工作。這是我的基本單元測試類和有問題的單元測試類。你能看到我可能會失蹤的任何東西,或者我應該尋找什麼?單元測試通過或失敗結果不一致

這發生在TestDriven.Net Visual Studio單元測試框架中。

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 

這是我的單元測試:

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 
+1

正在運行一整套測試或者只是這個測試一遍又一遍嗎?您可能想要反覆運行此測試以查看它是否仍然不一致。如果它在獨立運行時工作正常,那麼您可能會有另一個測試不適當地清理數據庫狀態。 – 2011-05-16 18:10:35

+0

不,我一次又一次地運行這個測試。 – adam0101 2011-05-16 18:19:29

回答

0

我終於搞清楚發生了什麼事。它與交易無關。這一切都很好。這是我的過程造成了不一致的行爲 - 按設計。如果沒有找到其他排名,則有一部分流程有「隨機排名」來確定deliveryDate。單元測試需要重寫,以更好地反映業務規則。

1

這一貫致力於對我罰款。我看到的主要區別是使用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(); 
    } 
} 
+0

不幸的是,如果我將它更改爲Required,它仍然會發生。 – adam0101 2011-05-17 13:32:23

0

爲什麼使用DataAdapter.Fill執行更新?它旨在用選擇語句填充DataTable。

我的猜測是,你沒有寫任何東西到數據庫首先使用ExecSql。

而第二件事。該斷言儘可能無法閱讀。 我會改變

Assert.AreEqual(False, dt.Rows(0).IsNull("deliveryDate"));

Assert.IsFalse(dt.Rows(0).IsNull("deliveryDate"));

Assert.That(dt.Rows(0)("deliveryDate"), Is.Not.Null));

不可讀測試的原因,有人說單元測試是不好的,因爲它會降低你的一個。你必須使單元測試儘可能容易閱讀和理解。所以他們沒有針對單元測試的爭論;)

由於我不使用VB.NET,可能會有一些錯別字。斷言示例來自NUnit。

+0

感謝格式化提示,但這真的不能回答我的問題。 – adam0101 2011-05-17 12:59:30

+0

格式化評論是一項獎勵。我說了我認爲你做錯了。但你不聽。 DataAdapter.Fill不適用於將數據發送到數據庫。如果你沒有顯示服務中有什麼,你如何期待好的答案。過程?我認爲downvote在這裏很粗魯。 – 2011-05-17 17:07:55