So I have two classes, each consists of database integration tests. In each classes' constructor I put a method to reset the database:
public class FirstClassSpec {
public FirstClassSpec() {
var dataSetup = new DataSetup();
dataSetup.CleanTables();
}
[Fact]
public async Task FirstTest() {
using(var conn = new SqlConnection("connStringHere")){
var result = await conn.ExecuteAsync("someSqlCommand");
Assert.True(result > 0);
}
}
}
public class SecondClassSpec {
public SecondClassSpec() {
var dataSetup = new DataSetup();
dataSetup.CleanTables();
}
[Fact]
public async Task SecondTest() {
using(var conn = new SqlConnection("connStringHere")){
var result = await conn.ExecuteAsync("someSqlCommand");
Assert.True(result > 0);
}
}
}
public class DataSetup {
public void CleanTables() {
using(var conn = new SqlConnection("connStringHere")){
await conn.Execute("someSqlCommandToCleanTables");
}
}
}
In order to run the tests Visual Studio 2015, I use Run All Tests in Test Explorer. I got the message of
Transaction (Process ID {someID}) was deadlocked on lock resources with another process
This problem only happens if I run all of the tests. If I run each tests one by one or running many tests but from the same class, the deadlock never occurs.
I found out that the CleanTables() method which is called in the classes' constructor cause this. I assume the tests run in parallel, and CleanTables() was called on the same time by the two classes.
So then I tried to make CleanTables() into an async method:
public async Task<int> CleanTables() {
using(var conn = new SqlConnection("connStringHere")){
return await conn.Execute("someSqlCommandToCleanTables");
}
}
And then on the classes' constructor I call it like this:
public FirstClassSpec() {
var dataSetup = new DataSetup();
dataSetup.CleanTables().Wait();
}
public SecondClassSpec() {
var dataSetup = new DataSetup();
dataSetup.CleanTables().Wait();
}
But now when I try to Run All Tests, the tests were running but they never get done and I never get the result.
My question is, why the deadlock occurs? and why changing the CleanTables() method into async made the running tests never get done? I really need to clean the tables before each tests run.
----------------- UPDATE -----------------------
I've tried decorated all of the test classes with [Collection["CollectionName"]], with each classes has different name:
[Collection["FirstSpec"]]
public class FirstClassSpec {
//....
}
[Collection["SecondSpec"]]
public class FirstClassSpec {
//....
}
But the deadlock still occurs..
----------------- UPDATE 2 -----------------------
Turns out classes which have the same collection name would be executed sequentially and this solves the deadlock problem.