I am working on a large-scale .NET test automation project (over 2500 test cases) that interacts with an application API. My goal is to keep the database clean and isolated between test runs.
Here's my problem:
- When I run integration tests that directly execute SQL commands (using ADO.NET), I can successfully roll back changes at the end of each test by wrapping everything in a
TransactionScope. This keeps my database clean. - However, most of my tests interact with the application via its public API (for example, sending HTTP requests to the API endpoints). In these cases, the API code opens its own database connection/process and commits changes independently.
- Even though I create a
TransactionScopein the test code (before calling the API), any database changes performed by the application/API are not rolled back. Only changes made directly by the test code’s connection are rolled back.
The SQL Server database is quite large, with a high number of tables and a significant amount of data. As a result, approaches like truncating all tables or dropping & recreating them after each test are impractical because they add significant overhead and make test runs much slower. I am specifically looking for efficient strategies that work well with large and complex databases.
Is there a way to ensure all database changes (including those made by the application/API in response to test requests) are rolled back after each test without db restore?
I tried wrapping my test execution in a TransactionScope (in C#) so that all database changes made during a test would be rolled back at the end. This approach works perfectly if I execute SQL commands directly from the test code: those changes are rolled back when the transaction is disposed.
However, most of my tests interact with the application via its API endpoints (for example, by sending HTTP requests). In these cases, the API code runs in a different process, opens its own database connection, and commits changes outside of the test's TransactionScope. As a result, any database modifications made by the API are not rolled back, and the database state is not isolated between tests.
I was expecting that using a TransactionScope in my test code would also roll back any database changes made by the application in response to my API calls, but that is not happening. I am looking for a way to ensure all changes (including those from the API) can be rolled back or reset efficiently between tests.