Test unité de réussite incohérente ou d'échec
-
14-11-2019 - |
Question
Un de mes tests unitaires semble passer au hasard ou échouer lorsque je l'exécute. La seule chose qui a du sens pour moi de savoir pourquoi cela se produit, c'est si les données de la base de données entrent dans un état différent chaque fois que le test est effectué, mais j'utilise des transactions pour faire reculer la base de données dans chaque test - sauf si cela ne fonctionne pas correctement . Voici ma classe de test d'unité de base et la classe de test unitaire qui a le problème. Pouvez-vous voir quelque chose qui pourrait manquer ou ce que je devrais rechercher d'autre?
Cela se produit avec TestDriven.net et Le cadre de test d'unité 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
Et voici mon test unitaire:
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
La solution 3
J'ai finalement compris ce qui se passait. Cela n'avait rien à voir avec les transactions. Tout cela fonctionne très bien. C'était mon processus qui créait un comportement incohérent - par conception. Il y a eu une partie du processus qui avait un "classement aléatoire" pour déterminer la livraison de la livraison si aucun autre classement n'est trouvé. Le test unitaire doit être réécrit pour mieux refléter les règles commerciales.
Autres conseils
Cela a toujours fonctionné pour bien pour moi. La principale différence que je vois est d'utiliser 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();
}
}
Pourquoi utilisez-vous dataadapter.fill pour exécuter des mises à jour? Il est conçu pour remplir les données de données avec des instructions sélectionnées.
Je suppose que vous n'avez rien écrit dans la base de données en utilisant EXECSQL en premier lieu.
Et la deuxième chose. Cette affirmation est aussi illisible que possible. je voudrais changer
Assert.AreEqual(False, dt.Rows(0).IsNull("deliveryDate"));
à
Assert.IsFalse(dt.Rows(0).IsNull("deliveryDate"));
ou
Assert.That(dt.Rows(0)("deliveryDate"), Is.Not.Null));
Les tests illisibles sont l'une des raisons pour lesquelles certaines personnes disent que les tests unitaires sont mauvais car cela vous ralentit. Vous devez rendre les tests unitaires aussi faciles à lire et à comprendre que possible. Pour qu'ils n'aient pas d'arguments contre les tests unitaires;)
Il peut y avoir des fautes de frappe car je n'utilise pas VB.NET. Les exemples d'affirmation sont de Nunit.