15.4. Data-driven testing using CSV files

Thucydides lets you perform data-driven testing using test data in a CSV file. You store your test data in a CSV file (by default with columns separated by commas), with the first column acting as a header:

        NAME,AGE,PLACE OF BIRTH
        Jack Smith, 30, Smithville
        Joe Brown, 40, Brownville
        Mary Williams, 20, Williamsville

Next, create a test class containing properties that match the columns in the test data. Each property should be a property by the JavaBeans definition, with a matching getter and setter. The test class will typically contain one or more tests that use these properties as parameters to the test step or Page Object methods.

The class will also contain the @UseTestDataFrom annotation to indicate where to find the CSV file (this can either be a file on the classpath or a relative or absolute file path - putting the data set on the class path (e.g. in src/test/resources) makes the tests more portable). You also use the @RunWith annotation as well as the other usual Thucydides annotations (@Managed, @ManagedPages and @Steps).

An example of such a class is shown here:

        @RunWith(ThucydidesParameterizedRunner.class)
        @UseTestDataFrom("test-data/simple-data.csv")
        public class SampleCSVDataDrivenScenario {

            private String name;
            private String age;
            private String placeOfBirth;

            public SampleCSVDataDrivenScenario() {
            }

            @Qualifier
            public String getQualifier() {
                return name;
            }

            @Managed
            public WebDriver webdriver;

            @ManagedPages(defaultUrl = "http://www.google.com")
            public Pages pages;

            @Steps
            public SampleScenarioSteps steps;

            @Test
            public void data_driven_test() {
                System.out.println(getName() + "/" + getAge() + "/" + getCity());
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getAge() {
                return age;
            }

            public void setAge(String age) {
                this.age = age;
            }

            public String getPlaceOfBirth() {
                return placeOfBirth;
            }

            public void setPlaceOfBirth(String placeOfBirth) {
                this.placeOfBirth = placeOfBirth;
            }
        }

Each row of test data needs to be distinguished in the generated reports. By default, Thucydides will call the toString() method. If you provide a public method returning a String that is annotated by the @Qualifier annotation, then this method will be used to distinguish data sets. It should return a value that is unique to each data set.

The test runner will create a new instance of this class for each row of data in the CSV file, assigning the properties with corresponding values in the test data. SoWhen we run this test, we will get an output like this:

        Jack Smith/30/Smithville
        Joe Brown/40/Brownville
        Mary Williams/20/Williamsville

There are a few points to note. The columns in the CSV files are converted to camel-case property names (so "NAME" becomes name and "PLACE OF BIRTH" becomes placeOfBirth). Since we are testing web applications, all of the fields should be strings.

If some of the field values contain commas, you will need to use a different separator. You can use the separator attribute of the @UseTestDataFrom annotation to specify an alternative separator. For example, the following data uses a semi-colon separator:

    NAME;AGE;ADDRESS
    Joe Smith; 30; 10 Main Street, Smithville
    Jack Black; 40; 1 Main Street, Smithville
    Mary Williams, 20, 2 Main Street, Williamsville

To run our tests against this data, we would use a test class like the following:

        @RunWith(ThucydidesParameterizedRunner.class)
        @UseTestDataFrom(value="test-data/simple-semicolon-data.csv", separator=';')
        public class SampleCSVDataDrivenScenario {

            private String name;
            private String age;
            private String address;

            public SampleCSVDataDrivenScenario() {
            }

            @Qualifier
            public String getQualifier() {
                return name;
            }

            @Managed
            public WebDriver webdriver;

            @ManagedPages(defaultUrl = "http://www.google.com")
            public Pages pages;

            @Steps
            public SampleScenarioSteps steps;

            @Test
            public void data_driven_test() {
                System.out.println(getName() + "/" + getAge() + "/" + getAddress());
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getAge() {
                return age;
            }

            public void setAge(String age) {
                this.age = age;
            }

            public String getAddress() {
                return address;
            }

            public void setAddress(String address) {
                this.address = address;
            }
        }

This will generate an output like this:

        Joe Smith/30/10 Main Street, Smithville
        Jack Black/40/1 Main Street, Smithville
        Mary Williams/20/2 Main Street, Williamsville

Excel support will be added in a future version. However if you store your test data in CSV form, it becomes easier to keep track of changes to test data in your version control system.