Mr Balanikas
Mr Balanikas

Reputation: 1681

how to organize test data in integration tests

I am working on a large test project consisting of thousands of integration tests. It is a bit messy with lots of code duplication. Most tests are composed of several steps, and a lot of "dummy" objects are created. With dummy I mean something like this:

new Address {
    Name = "fake address",
    Email = "[email protected]",
    ... and so on
}

where it often really doesn't matter what the data is. This kind of code is spread out and duplicated in tests, test base classes, and helpers.

What I want is to have a single "test data builder", having a single responsibility, generate test data which is consumed by the tests.

One approach is to have a class with a bunch of static methods like following:

Something CreateSomething(){
    return new Something {
    // set default dummy values
}

and an overload:

Something CreateSomething(params){
    return new Something {
    // create the Something from the params
}

Another approach is to have xml files containing the data but i am afraid then it would be too far away from the tests.

The goal is to move this kind of code out of the tests because right now the tests are big and not readable. In a typical case, of 50 lines of test code, 20-30 is of this kind of code.

Are there any patterns for accomplishing this? Or any example of big open source codebase with something similar that I can have a look at?

Upvotes: 1

Views: 1558

Answers (2)

Scott Nimrod
Scott Nimrod

Reputation: 11570

I would shy away from xml files that specify test dependencies.

My thought process stems from a lack of refactoring tools that these xml files cannot take advantage of within the Visual Studio ecosystem.

Instead, I would create a TestAPI. This API will be responsible for serving dependency data to test clients.

Note that the dependency data that is being requested will already be initialized with general data and ready to go for the clients that are requesting the dependencies.

Any values that serve as required test inputs for a particular test would be assigned within the test itself. This is because I want the test to self document its intent or objective and abstract away the dependencies that are not being tested.

XUnit Test Patterns provided me a lot of insight for writing tests.

Upvotes: 1

James Simpson
James Simpson

Reputation: 1150

For code, use a simple method chaining builder pattern:

public class TestOrderBuilder
{
    private order = new Order();

    //  These methods represent sentances / grammar that describe the sort   
    //  of test data you are building
    public AnObjectBuilder AddHighQuantityOrderLine()
    {
         //... code to add a high quantity order line

         return this; // for method chaining
    }

    //  These methods represent sentances / grammar that describe the sort   
    //  of test data you are building
    public AnObjectBuilder MakeDescriptionInvalid()
    {
         //... code to set descriptions etc...

         return this; // for method chaining
    }

    public Order Order
    {
         get { return this.order; }
    }
}

// then using it:
var order = new TestOrderBuilder()
                 .AddHighQuantityOrderLine()
                 .MakeDescriptionInvalid()
                 .Order

Upvotes: 1

Related Questions