1

We have a great unit test suite in that it is very fast (many tests per second, not many seconds per test!). We also have automated UI (browser, selenium based) tests.

However this now seems to have come at an interesting cost. We have interfaces to populate consumer data from other services and then integrating it with our HTML forms.

We've had more than 5 different incidents recently of having thousands of duplicate records (duplicate for the key fields, not all fields). Not just one table either but 4 different tables.

It seems that our unit tests don't check the database and our UI tests often don't show duplicate records that are not showing up in the UI but exist in the database.

What approaches and techniques can we use to avoid this happening within the limitation of generally very fast unit tests to enable a good TDD/BDD workflow?

  • I do not understand the 3rd paragraph, can you please elaborate? We've had more than 5 different incidents recently of having thousands of duplicate records (duplicate for the key fields, not all fields). Not just one table either but 4 different tables. – Yu Zhang Nov 1 '16 at 4:48
1

Depending on how you're implementing the testing framework you can start a transaction in the test setup methods and then rollback in the teardown methods.

By doing this, you are executing the code against your database but since you rollback the transaction it is going to clean it up after your done.

Another option is to use a seperate database which you can restore from a save or from a more stable, manual environment. This will allow you to not have to worry about dirty data in your database due to Integration level tests.

A sample of my Specflow code is below:

    [BeforeScenario]
    public void BeforeScenario()
    {
        testBase = new IntegrationTestBase();
        objectContainer.RegisterInstanceAs<IntegrationTestBase>(testBase);
    }

    [AfterScenario("rollback")]
    public void AfterScenario()
    {
        testBase.dbContextTransaction.Rollback();
    }

    [AfterScenario("commit")]
    public void commitData()
    {
        testBase.dbContextTransaction.Commit();
    }

The integration test base starts the transaction when the dbContext is created. If the test is tagged rollback, it will rollback all changes when the test is done. If the test is to be commited, it will commit when completed.

0

First, write tests for your database access layer to ensure that a bug in the database access layer does not cause duplicate records. For example, you might ensure that a single insertObject call always results in the correct number of database inserts.

Second, mock out the database in your other unit tests, then add unit tests to ensure that the code under test uses the database access layer in the intended way. For example, you might ensure that an operation that should only call insertObject once does not call insertObject multiple times.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.