Cómo: Escribir una prueba unitaria de base de datos que se ejecute en el ámbito de una transacción individual
Actualización: noviembre 2007
Puede modificar las pruebas unitarias para que se ejecuten dentro del ámbito de una transacción individual. Si utiliza este enfoque, puede revertir cualquier cambio activado por la prueba una vez finalizada. Los procedimientos siguientes explican la manera de:
Crear una transacción en el script de prueba Transact-SQL (T-SQL) que utilice BEGIN TRANSACTION y ROLLBACK TRANSACTION.
Crear una transacción para un método de prueba individual en una clase de prueba.
Crear una transacción para todos los métodos de prueba de una clase de prueba determinada.
Requisitos previos
Para algunos procedimientos de este tema, el servicio Coordinador de transacciones distribuidas debe estar en ejecución en el equipo en el que se ejecutan las pruebas unitarias. Para obtener más información, vea el procedimiento al final de este tema.
Para crear una transacción mediante T-SQL
Para crear una transacción mediante T-SQL
Abra una prueba unitaria en el Diseñador de pruebas unitarias de base de datos.
Especifique el tipo de script para el que desea crear la transacción. Por ejemplo, puede especificar un script de prueba, de ejecución previa a la prueba o de ejecución posterior a la prueba.
Escriba un script de prueba en el editor de T-SQL.
Inserte las instrucciones BEGIN TRANSACTION y ROLLBACK TRANSACTION como se indica en este ejemplo sencillo. El ejemplo se basa en la tabla de la base de datos Northwind, que contiene 50 filas de datos:
BEGIN TRANSACTION TestTransaction UPDATE "Order Details" set Quantity = Quantity + 10 IF @@ROWCOUNT!=50 RAISERROR('Row count does not equal 50',16,1) ROLLBACK TRANSACTION TestTransaction
Nota: No puede deshacer una transacción tras ejecutar una instrucción COMMIT TRANSACTION.
Para obtener más información sobre cómo funciona ROLLBACK TRANSACTION con procedimientos almacenados y desencadenadores, vea "ROLLBACK TRANSACTION (Transact-SQL)" en el sitio web de Microsoft.
Para crear una transacción para un método de prueba individual
En este ejemplo se usa una transacción de ambiente al emplear el tipo TransactionScope. De forma predeterminada, las conexiones Execution y Privileged no utilizarán la transacción de ambiente, porque se habrán creado antes de ejecutar el método. SqlConnection tiene un método EnlistTransaction, que asocia una conexión activa a una transacción. Cuando se crea una transacción de ambiente, se registra como la transacción actual y se puede tener acceso a ella a través de la propiedad Current. En este ejemplo, la transacción se revierte cuando se elimina la transacción de ambiente. Si desea confirmar cualquier modificación realizada cuando ejecutó la prueba unitaria, debe llamar al método Complete.
Para crear una transacción para un método de prueba individual
Abra el archivo de Visual Basic o C# de la prueba unitaria.
Incluya las acciones previas a la prueba y posteriores a la prueba, como se indica en el siguiente ejemplo de código Visual Basic:
<TestMethod()> _ Public Sub dbo_InsertTable1Test() Using ts as New System.Transactions.TransactionScope( System.Transactions.TransactionScopeOption.Required) ExecutionContext.Connection.EnlistTransaction(Transaction.Current) PrivilegedContext.Connection.EnlistTransaction(Transaction.Current) Dim testActions As DatabaseTestActions = Me.dbo_InsertTable1TestData 'Execute the pre-test script ' System.Diagnostics.Trace.WriteLineIf((Not (testActions.PretestAction) Is Nothing), "Executing pre-test script...") Dim pretestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PretestAction) 'Execute the test script System.Diagnostics.Trace.WriteLineIf((Not (testActions.TestAction) Is Nothing), "Executing test script...") Dim testResults() As ExecutionResult = TestService.Execute(ExecutionContext, Me.PrivilegedContext, testActions.TestAction) 'Execute the post-test script ' System.Diagnostics.Trace.WriteLineIf((Not (testActions.PosttestAction) Is Nothing), "Executing post-test script...") Dim posttestResults() As ExecutionResult = TestService.Execute(Me.PrivilegedContext, Me.PrivilegedContext, testActions.PosttestAction) 'Because the transaction is not explicitly committed, it 'is rolled back when the ambient transaction is 'disposed. 'To commit the transaction, remove the comment delimiter 'from the following statement: 'ts.Complete() End Sub Private dbo_InsertTable1TestData As DatabaseTestActions
Nota: Si utiliza Visual Basic, debe agregar Imports System.Transactions (además de Imports Microsoft.VisualStudio.TestTools.UnitTesting, Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTesting y Imports Microsoft.VisualStudio.TeamSystem.Data.UnitTest.Conditions). Si usa Visual C#, debe agregar using System.Transactions (además de instrucciones using para Microsoft.VisualStudio.TestTools, Microsoft.VisualStudio.TeamSystem.Data.UnitTesting y Microsoft.VisualStudio.TeamSystem.Data.UnitTesting.Conditions). También debe agregar a esos ensamblados una referencia al proyecto.
Para crear una transacción para todos los métodos de prueba de una clase de prueba
Para crear una transacción para todos los métodos de prueba de una clase de prueba
Abra el archivo de Visual Basic o C# de la prueba unitaria.
Cree la transacción en TestInitialize y elimínela en TestCleanup, como se muestra en el siguiente ejemplo de código Visual C#:
TransactionScope _trans; [TestInitialize()] public void Init() { _trans = new TransactionScope(); base.InitializeTest(); } [TestCleanup()] public void Cleanup() { base.CleanupTest(); _trans.Dispose(); } [TestMethod()] public void TransactedTest() { DatabaseTestActions testActions = this.DatabaseTestMethod1Data; // Execute the pre-test script // System.Diagnostics.Trace.WriteLineIf((testActions.PretestAction != null), "Executing pre-test script..."); ExecutionResult[] pretestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PretestAction); // Execute the test script // System.Diagnostics.Trace.WriteLineIf((testActions.TestAction != null), "Executing test script..."); ExecutionResult[] testResults = TestService.Execute(this.ExecutionContext, this.PrivilegedContext, testActions.TestAction); // Execute the post-test script // System.Diagnostics.Trace.WriteLineIf((testActions.PosttestAction != null), "Executing post-test script..."); ExecutionResult[] posttestResults = TestService.Execute(this.PrivilegedContext, this.PrivilegedContext, testActions.PosttestAction); }
Para iniciar el servicio Coordinador de transacciones distribuidas
Algunos procedimientos de este tema usan los tipos del ensamblado System.Transactions. Antes de seguir estos procedimientos, debe asegurarse de que el servicio Coordinador de transacciones distribuidas está en ejecución en el equipo donde ejecuta las pruebas unitarias. De lo contrario, se produce un error en las pruebas y aparece el mensaje de error siguiente: "El método de prueba nombreDeProyecto.nombreDePrueba.nombreDeMétodo produjo la excepción: System.Data.SqlClient.SqlException: MSDTC en el servidor 'nombreDeEquipo' no está disponible".
Para iniciar el servicio Coordinador de transacciones distribuidas
Abra el Panel de control.
En el Panel de control, abra Herramientas administrativas.
En Herramientas administrativas, abra Servicios.
En el panel Servicios, haga clic con el botón secundario del mouse en el servicio Coordinador de transacciones distribuidas y haga clic en Iniciar.
El estado del servicio debería actualizarse a Iniciado. Ahora debería ser posible ejecutar pruebas unitarias que utilizan System.Transactions.