Implementing test cases in a test scenario of JGiven

234 Views Asked by At

A file is provided containing a number of lines, which is loaded by an (under acceptance) system in a database. A simple test scenario, based on JGiven, would check that the number of lines of the file matches the corresponding table rows. The maven test execution of a mockup implementation in Java 1.8, provided the following (first output):

Test Class: com.testcomp.LoadingTest
 Check Loading Process
   Given that the parameters provided are for an input file ( BRANCH )for a specific date ( 20190105 )was provided
    When the number of file records is calculated
     And the loading is complete
     And the number of table rows loaded is calculated
    Then the no of file records (200) must match the no of table rows (200)

It is a valid option however to provide no file for loading. So, we have two test cases and the maven test should provide something like (second output):

Test Class: com.testcomp.LoadingTest1
 Check Loading Process
   Given that the parameters provided are for an input file ( BRANCH )for a specific date ( 20190105 )
     And the file exists
    When the number of file records is calculated
     And the loading is complete
     And the number of table rows loaded is calculated
    Then the no of file records (200) must match the no of table rows (200)

Test Class: com.testcomp.LoadingTest2
 Check Loading Process
   Given that the parameters provided are for an input file ( BRANCH )for a specific date ( 20190105 )
     And the file does NOT exist
    Then we check nothing

How do we combine the two test cases so that depending of the file's existence we have a "pass" test in either case, knowing if the file was provided or not? OR is there a way to create something similar to the HTML report of JGiven itself (third output):

Test Class: com.testcomp.LoadingTest3
 Check Loading Process
   Given that the parameters provided are for an input file ( BRANCH )for a specific date ( 20190105 )
     And the scenario has 2 cases from which only one may be true
    When checking the file's existence is done
     And for case 1 file existence is TRUE
     And for case 1 the number of file records is calculated
     And for case 1 the loading is complete
     And for case 1 the number of table rows loaded is calculated
     And for case 2 file existence is FALSE
    Then for case 1 the no of file records (200) must match the no of table rows (200)
     And for case 2 we check nothing

The implementation for the first output is as follows:

LoadingTest Class

public class LoadingTest
    extends ScenarioTest<GivenWeHaveFile2Load, WhenFileAndDatabaseAreChecked, ThenCheckIfNoOfFileLinesMatchesNoOfTableRows> {

    @ScenarioStage
    WhenFileAndDatabaseAreChecked loadingFinishedState;

    @ScenarioStage
    WhenFileAndDatabaseAreChecked databaseState;

    @Test
    public void Check_Loading_Process() {
        given().that_an_input_file_for_a_specific_date_was_provided("BRANCH", "20190105");
        when().the_number_of_file_records_is_calculated();
        loadingFinishedState
                .and().the_loading_is_complete();
        databaseState
                .and().the_number_of_table_rows_loaded_is_calculated();
        then().the_no_of_file_records_must_match_the_no_of_table_rows();
    }
}

GivenWeHaveFile2Load Class

public class GivenWeHaveFile2Load extends Stage<GivenWeHaveFile2Load> {

    @ProvidedScenarioState
    String properFileName;

    @As( "that the parameters provided are for an input file ($) for a specific date ($) was provided" )
    public GivenWeHaveFile2Load that_an_input_file_for_a_specific_date_was_provided(String filenamePrefix, String dateStringYYYYMMDD) {
        properFileName = filenamePrefix + "_" + dateStringYYYYMMDD + ".txt";
        return self();
    }
}

WhenFileAndDatabaseAreChecked Class

public class WhenFileAndDatabaseAreChecked extends Stage<WhenFileAndDatabaseAreChecked> {

    @ExpectedScenarioState
    String properFileName;

    @ProvidedScenarioState
    int noOfFileRecords;

    @ProvidedScenarioState
    int noOfTableRows;

    // @ExtendedDescription("after we check the number of file lines") // does NOT seem to work..
    public WhenFileAndDatabaseAreChecked the_number_of_file_records_is_calculated() {
        // we'll use properFileName to get noOfFileRecords in the actual implementation
        noOfFileRecords = 200;
        return self();
    }

    public WhenFileAndDatabaseAreChecked the_loading_is_complete() {
        return self();
    }

    public WhenFileAndDatabaseAreChecked the_number_of_table_rows_loaded_is_calculated() {
        noOfTableRows = 200;
        return self();
    }
}

ThenCheckIfNoOfFileLinesMatchesNoOfTableRows Class

public class ThenCheckIfNoOfFileLinesMatchesNoOfTableRows extends Stage<ThenCheckIfNoOfFileLinesMatchesNoOfTableRows> {

    @ExpectedScenarioState
    int noOfFileRecords;

    @ExpectedScenarioState
    int noOfTableRows;

    @ScenarioState
    CurrentStep currentStep;

    public ThenCheckIfNoOfFileLinesMatchesNoOfTableRows the_no_of_file_records_must_match_the_no_of_table_rows () {
        currentStep.setName("the no of file records (" + noOfFileRecords + ") must match the no of table rows (" + noOfTableRows + ")");
        assert(noOfFileRecords == noOfTableRows);
        return self();
    }
}
1

There are 1 best solutions below

0
GrandPaTim On

A somehow different approach was devised that covers the needs:

  • to know whether the file was supplied or not
  • to differentiate the resulting output depending on the file's existence

In case the file does exist, we may have this (first output):

Test Class: com.testcomp.LoadingTest
 Check Loading Process
   Given that the parameters provided are for an input file ( BRANCH )for a specific date ( 20190105 )was provided
     And after checking for file existence ( result: true )
    When the number of file records is calculated
     And the loading is complete
     And the number of table rows loaded is calculated
    Then the no of file records (200) must match the no of table rows (200)

In case the file does not exist, we may have this (second output):

Test Class: com.testcomp.LoadingTest
 Check Loading Process
   Given that the parameters provided are for an input file ( BRANCH )for a specific date ( 20190105 )was provided
     And after checking for file existence ( result: false )
    Then since we have no file it is OK

To achieve the above, the key change was to define in the GivenWeHaveFile2Load class the after_checking_if_file_exists method returning a Boolean for file existence. The result then could be checked in the LoadingTest class and differentiate the "script" displayed for the test result. From the initial four (4) classes, only WhenFileAndDatabaseAreChecked remains as is. The code for the remaining three (3) is provided below.

LoadingTest Class


public class LoadingTest
    extends ScenarioTest<GivenWeHaveFile2Load, WhenFileAndDatabaseAreChecked, ThenCheckIfNoOfFileLinesMatchesNoOfTableRows> {

    private Boolean fileExists;

    @ScenarioStage
    GivenWeHaveFile2Load CheckingFileExistenceState;

    @ScenarioStage
    WhenFileAndDatabaseAreChecked loadingFinishedState;

    @ScenarioStage
    WhenFileAndDatabaseAreChecked databaseState;

    @ScenarioStage
    ThenCheckIfNoOfFileLinesMatchesNoOfTableRows NoFileProvidedState;

    @Test
    public void Check_Loading_Process() {
        given().that_an_input_file_for_a_specific_date_was_provided("BRANCH", "20190105");
        fileExists = CheckingFileExistenceState
                .and().after_checking_if_file_exists();
        if (fileExists) {
            when().the_number_of_file_records_is_calculated();
            loadingFinishedState
                    .and().the_loading_is_complete();
            databaseState
                    .and().the_number_of_table_rows_loaded_is_calculated();
            then().the_no_of_file_records_must_match_the_no_of_table_rows();
        } else {
            NoFileProvidedState
                    .then().since_we_have_no_file_it_is_OK();
        }
        ;
    }
}

GivenWeHaveFile2Load Class

public class GivenWeHaveFile2Load extends Stage<GivenWeHaveFile2Load> {

    private Boolean fileExists;

    @ProvidedScenarioState
    String properFileName;

    @ScenarioState
    CurrentStep currentStep;

    public Boolean after_checking_if_file_exists() {
        currentStep.setName("after checking for file existence ( result: " + fileExists + " )");
        return fileExists;
    }

    public void setFileExists(Boolean fileExists) {
        this.fileExists = fileExists;
    }

    @As( "that the parameters provided are for an input file ($) for a specific date ($) was provided" )
    public GivenWeHaveFile2Load that_an_input_file_for_a_specific_date_was_provided(String filenamePrefix, String dateStringYYYYMMDD) {
        properFileName = filenamePrefix + "_" + dateStringYYYYMMDD + ".txt";
        this.setFileExists(Boolean.FALSE); // actual file check goes here
        return self();
    }
}

ThenCheckIfNoOfFileLinesMatchesNoOfTableRows Class

public class ThenCheckIfNoOfFileLinesMatchesNoOfTableRows extends Stage<ThenCheckIfNoOfFileLinesMatchesNoOfTableRows> {

    @ExpectedScenarioState
    int noOfFileRecords;

    @ExpectedScenarioState
    int noOfTableRows;

    @ScenarioState
    CurrentStep currentStep;

    public ThenCheckIfNoOfFileLinesMatchesNoOfTableRows the_no_of_file_records_must_match_the_no_of_table_rows () {
        currentStep.setName("the no of file records (" + noOfFileRecords + ") must match the no of table rows (" + noOfTableRows + ")");
        assert(noOfFileRecords == noOfTableRows);
        return self();
    }
    public ThenCheckIfNoOfFileLinesMatchesNoOfTableRows since_we_have_no_file_it_is_OK () {
        assert(Boolean.TRUE);
        return self();
    }
}