My team has been using SpecFlow to verify that our data access components are working correctly. In an effort to write repeatable tests that won’t pollute the database, we’ve decided to wrap each scenario in a transaction.
Creating and rolling back the transactions is very simple to do with SpecFlow’s BeforeScenario & AfterScenario hooks.
using System.Transactions; [Binding] public class TransactionHooks { private TransactionScope _transactionScope; [BeforeScenario] public void BeforeScenario() { _transactionScope = new TransactionScope(); } [AfterScenario] public void AfterScenario() { _transactionScope.Dispose(); } }
By including these hooks, you’re placing your test scenarios in the loving embrace of a transaction scope. The act of instantiating the TransactionScope will update the ambient transaction that will be used by all subsequent code unless you explicitly tell it to do otherwise.
If you’re testing code that uses TransactionScope itself, using TransactionScopeOption.Required will allow the code to use the ambient transaction if one exists. Note that this is the default value, so it’s what you’re using if you’re not explicitly specifying an option. However, the other TransactionScopeOption values will cause code to execute outside your test scenario’s ambient transaction by either creating a new/different transaction (RequiredNew) or executing outside the transaction (Suppress).
Hey Adam, thanks for sharing this. I tried this too, but it never get rolled back after the dispose(). Im using dapper, I know this article was made 5 years ago but do you have any idea what caused it?
Thanks