|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Nesting ambient transactions.. doable?transaction around each test and I'm trying to do that in my base class so that all my test can benefit from them. The problem is that I can't find a way to do both transactions. it's either around the whole fixture or around the test. is there a way to do both? here is my base test class: using System; using System.Transactions; using NUnit.Framework; namespace Library.Tests { public enum TestTransactionMode { None, AroundFixture, AroundTests } [TestFixture] public abstract class BaseFixtureWithTxRollback : BaseFixture { Transaction fixtureTransaction; Transaction testTransaction; private TestTransactionMode testTransactionMode = TestTransactionMode.AroundFixture; /// <summary> /// The transaction mode of the test /// </summary> public TestTransactionMode TestTransactionMode { get { return testTransactionMode; } set { testTransactionMode = value; } } [TestFixtureSetUp] public override void TestFixtureSetUp() { base.TestFixtureSetUp(); if (testTransactionMode == TestTransactionMode.AroundFixture) { fixtureTransaction = new CommittableTransaction(); Transaction.Current = fixtureTransaction; } } [TestFixtureTearDown] public override void TestFixtureTearDown() { if (fixtureTransaction != null) { fixtureTransaction.Rollback(); } } [SetUp] public override void TestSetUp() { base.TestSetUp(); if (testTransactionMode == TestTransactionMode.AroundTests) { testTransaction = new CommittableTransaction(); Transaction.Current = testTransaction; } } [TearDown] public override void TestTearDown() { base.TestTearDown(); if (testTransaction != null) { testTransaction.Rollback(); } } } } So basically i want to have another TestTransactionMode.AroundTestAndFixture. I found SubordinateTransaction class which takes ISimpleTransactionSuperior in its constructor but there is no implementation for this interface. Look at the book Test Driven Development in .NET. It has a neat way of
handling this issue with base classes. It does not nest .NET transactions, however. The concept is to pull all work for a single TestFixture on the same transaction, no matter where it occurs in the class. Very neat way of rolling back database work after testing. There are issues with transactions nested in code, largely due to SQL Server isolation levels. This may be different for other databases, but lock escalation could create deadlocks if you are testing load on the same database you are testing your unit tests (yes, I know it is a bad practice, but it does sometimes happen). If you still desire to nest transactions, be sure to explicitly name each one so multiple transactions on a single connection object can be committed or rolled back independently. SqlTransaction outerTransaction = connection.BeginTransaction("outer"); Apologies for not escavating the code and providing specific guidance. :-) -- Show quoteGregory A. Beamer MVP; MCP: +I, SE, SD, DBA *************************** Think Outside the Box! *************************** "eacsub" wrote: > im trying to put a transaction around my NUnit tests fixtures and a seperate > transaction around each test and I'm trying to do that in my base class so > that all my test can benefit from them. > > The problem is that I can't find a way to do both transactions. it's either > around the whole fixture or around the test. is there a way to do both? > > here is my base test class: > > using System; > using System.Transactions; > using NUnit.Framework; > > namespace Library.Tests > { > public enum TestTransactionMode > { > None, > AroundFixture, > AroundTests > } > > > [TestFixture] > public abstract class BaseFixtureWithTxRollback : BaseFixture > { > Transaction fixtureTransaction; > Transaction testTransaction; > > private TestTransactionMode testTransactionMode = > TestTransactionMode.AroundFixture; > > /// <summary> > /// The transaction mode of the test > /// </summary> > public TestTransactionMode TestTransactionMode > { > get { return testTransactionMode; } > set { testTransactionMode = value; } > } > > [TestFixtureSetUp] > public override void TestFixtureSetUp() > { > base.TestFixtureSetUp(); > > if (testTransactionMode == TestTransactionMode.AroundFixture) > { > fixtureTransaction = new CommittableTransaction(); > Transaction.Current = fixtureTransaction; > } > } > > [TestFixtureTearDown] > public override void TestFixtureTearDown() > { > if (fixtureTransaction != null) > { > fixtureTransaction.Rollback(); > } > } > > [SetUp] > public override void TestSetUp() > { > base.TestSetUp(); > > if (testTransactionMode == TestTransactionMode.AroundTests) > { > testTransaction = new CommittableTransaction(); > Transaction.Current = testTransaction; > } > } > > [TearDown] > public override void TestTearDown() > { > base.TestTearDown(); > > if (testTransaction != null) > { > testTransaction.Rollback(); > } > } > } > } > > So basically i want to have another > TestTransactionMode.AroundTestAndFixture. I found SubordinateTransaction > class which takes ISimpleTransactionSuperior in its constructor but there is > no implementation for this interface. I'm not sure what you mean by "pulling all work for a single TestFixture" but
i think that's what i'm doing by assigning a new commitable transaction to Transaction.Current in the [TestFixtureSetup]. You're maybe right regarding deadlocks, but it's needed to seperate the tests from each other in their own transaction so that they don't conflic with each other. |
|||||||||||||||||||||||