0

I am working on a project I am closing to being done with. I know my methods with and the code overall works, but I am stuck on how to read in a specific row or column from a CSV file.

Example - My CVS looks something like this...

  1. Title One, URL 1, Login1, Password1 |
  2. Title Two, URL 2, Login2, Password2 |
  3. Title Three, URL 3, Login3, Password3 |
  4. ...and so on

This is my @DataProvider that reads in the CSV file

//opens and reads in CVS file from resource folder
@DataProvider
    public Iterator<Object[]> expectedTitles() throws IOException {
        List<Object []>testData = new ArrayList<>();
        String[] data = null;
        BufferedReader br = new BufferedReader(new FileReader("src/main/resources/expectedTitles.csv"));
        String line;
        while ((line = br.readLine()) != null){
            data = line.split(",");
            testData.add(data);
        }
        return testData.iterator();
    }

I also have a @Test method for every line of data in the CSV that looks something like this.

//executes sideNavAboutLink test 
    @Test(dataProvider = "expectedTitles")
    public void sideNavAboutLink(String pageTitle){

        driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
        AboutLink page = new AboutLink(driver);
        page.loadPage();
        page.clickSideAbout(); //clicks on link
        page.validateURLSideNav(); //Validates URL
        page.validateTitleSideNav(pageTitle); //Validates Page Title
    }

Current this this all works more or less because I don't have my CSV filled out all the way yet it just has the pageTitle, but like I stated above I would like to be able to call any given row or column to get rid of redundant code. I have looks at some other examples but I haven't figured out how to adapt it to my code above.

Please any help would be great thank you.

2 Answers 2

1

Here is step by step example.

I have a CSV file with 3 Test data set. I have created one function will return a specific Data set based on provided Title. We have 3 separate data provider to serve each test case. Now we can run one test case for one test data.

I will Hope it will help you.

CSV File Data:

enter image description here

Function to read a specific row based provide title (can be customized based on requiredment)

private  String[][] expectedTitles(String titleName) throws IOException {
    String[][] testData = null;
    String[] data = null;
    String line = null;

    BufferedReader br = new BufferedReader(new FileReader("...\\yourfilepath\\data.csv"));


    while ((line = br.readLine()) != null){

        data = line.split(",");
       testData= new String[1][data.length];

        if(data[0].equalsIgnoreCase(titleName))
        {
            for(int i =0; i<data.length; i++)

            {

            testData[0][i] = data[i];

            }

        break;
        }
    }
    return testData;        
}

DataProviders specific for Test data

@DataProvider(name = "GoogleDataprovider")
    public Object[][] googleDataprovider() throws IOException {
         Object[][] arrayObject = expectedTitles("Google");
         return arrayObject;
    }


    @DataProvider(name = "MicrosoftDataprovider")
    public Object[][] microsoftDataprovider() throws IOException {
         Object[][] arrayObject = expectedTitles("Microsoft");
         return arrayObject;
    }

    @DataProvider(name = "WallmartDataprovider")
    public Object[][] wallmartDataprovider() throws IOException {
         Object[][] arrayObject = expectedTitles("Wallmart");
         return arrayObject;
    }

Test cases using specific test data from Data providers (1 test cases for 1 data set)

@Test(dataProvider="GoogleDataprovider")
    public void testGoogleData(String title, String url, String domain) {
        Assert.assertEquals("Google", title);
        Assert.assertEquals("www.google.com", url);
        Assert.assertEquals("Search engine", domain);
    }

    @Test(dataProvider="MicrosoftDataprovider")
    public void testMicrosoftData(String title, String url, String domain) {
        Assert.assertEquals("Microsoft", title);
        Assert.assertEquals("www.microsoft.com", url);
        Assert.assertEquals("Operating System", domain);
    }


    @Test(dataProvider="WallmartDataprovider")
    public void testWallmartData(String title, String url, String domain) {
        Assert.assertEquals("Wallmart", title);
        Assert.assertEquals("www.wallmart.com", url);
        Assert.assertEquals("Retail", domain);

    }

Output:

PASSED: testGoogleData("Google", "www.google.com", "Search engine") PASSED: testMicrosoftData("Microsoft", "www.microsoft.com", "Operating System") PASSED: testWallmartData("Wallmart", "www.wallmart.com", "Retail")

Sign up to request clarification or add additional context in comments.

13 Comments

I am sorry can you clarify this a little more with the code example I gave for my @Test method? I am not sure how this is going to work you only referring to the url and not all my data in the CSV so I don't total understand.
What you did not understand. I have used url to get specific row. You can debug this code separately
more or less the whole thing. I don't need a print statement, which is what you are doing. I am feeding data into a selenium framework test using TestNG. I have an several @Test method that I need to call specific pieces of data (row & column) from the CSV at specific times and I don't see how what you have will do that. What you have and what I have doesn't match up.
My answer is as per your question. It will return specific row. Instead url you can use other column to filter specific raw and it will return as object array so you can use it in dataprovider
Thank you so much for your help. I showed this to one of my co-worker to see if he could help me understand what you are saying and he was able to explain it to me so I understood. This worked perfectly for what I wanted to do. Thank you so much, I greatly appreciate it. Now that I understand it I can rework several spot in my code to make it more efficient. Thanks again.
|
0

I think your test method can have the array itself instead of the first string, so that you can use the array values inside your test method with indices and get any row / column value.

public void sideNavAboutLink(String args[]){

will bring the whole array, and then we can have :

String pageTitle = args[0];
String url = args[1];
String userName = args[2];
String password = args[3];

in your test method and use these variables in your function calls.

2 Comments

This helped but for each line in my CSV it needs to have its own test and instead each test is running through every line in my CSV. I only want test one to read row one and the corresponding columns for that row. Then test two to read row two and the corresponding columns and so on. So right now when I click play test one instead of running once it runs 4 times for each line in my CVS. I only want it to run once. I hope that helps explain my issues. Any ideas how to fix that?
OK, in that case, may be you can try having a column in your file with test names to compare. public void testGoogleData(String testName, String title, String url, String domain) { String currentTestName = new Object() { }.getClass().getEnclosingMethod().getName(); if(currentTestName.equals(testName)) { //your test lines.... } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.