简体   繁体   中英

Constructor not taking value passed during object creation in Selenium using Java

I am writing a code wherein I am operating with an excel file having three sheets. I am using Apache POI and Data provider annotation for data driven approach. I wanted to pass Sheet index number or Sheet name at run time but I was not able to do it setting a parameter to data provider method. So what I did is I wrote a constructor and a static variable as integer. In parameterized constructor, I initialized that static variable and then in my test case, by creating object of the class which had data provider method, I passed an integer that is, sheet index from which I wanted the data to be taken to run the test. But every time, the constructor is taking value as 0. I don't know why. Below is the data driven code and constructor I have written.

public class Excel_Util {
    static int fileinitial;
    public Excel_Util(int filename) {
        fileinitial=filename;
    }
    @DataProvider(name="testdata")
    public static Object[][] readexcelretobj() throws Exception {
        
FileInputStream f= new FileInputStream("F:\\Eclipse Java new Programs\\shdtestpeopleinteractive\\src\\test\\resources\\Test_data.xls");
        
HSSFWorkbook workbook = new HSSFWorkbook(f);
HSSFSheet s = workbook.getSheetAt(fileinitial);
HSSFRow row = s.getRow(0);
int rownum=s.getPhysicalNumberOfRows();
int colnum=row.getLastCellNum();

//System.out.println(rownum);
//System.out.println(colnum);
Object data[][] = new Object[rownum][colnum];
List<Object> l = new ArrayList<Object>();
for(int i=0;i<rownum-1;i++) {
    row = s.getRow(i+1);
    for(int j=0;j<colnum;j++) {
        HSSFCell c  = row.getCell(j);
        //l.add(c.getStringCellValue());
        data[i][j]=c.getStringCellValue();
    }
}

return data;
        }
    

The test case which I wrote is as follows.

@Test(dataProvider="testdata",dataProviderClass=Excel_Util.class)
    public void testsignupdatafields(String email, String password) {
        Syncutil.Implicitwait();
        try {
            Excel_Util ex = new Excel_Util(2);
            getdriver().get("https://www."+csvreaderutil.csvread().get(0).toString()+"/");
            Marathishd marathishdpage = PageFactory.initElements(getdriver(), Marathishd.class);
            Signuppagemarathishd signup = marathishdpage.letsbeginclick();
            signup.emailid.sendKeys(email);
            signup.password.sendKeys(password);


        }catch(Exception e) {System.out.println("Exception");}
    }
}

Here, I have passed 2 at the time of object creation but every time, the values are taken from the first sheet. That is, sheet index 0 is considered every time. I don't want to hard code any value in excelutil class code as I wanted to behave it as generic code. So in test case itself I decided to pass sheet number. I am confused what to do and wanted a reason why this is happening and what is the mistake I am doing. Can anyone please guide me with this ?

I simplified the code to replicate the issue.

Existing code :

@Test method :

@Test(dataProvider = "testdata", dataProviderClass = Excel_Util.class)
public void testsignupdatafields(String email, String password) {
    System.out.println("Test started");
    new Excel_Util(2);
    System.out.println("Email: " + email + " & Passowrd: " + password);

}

Excel_Util :

public class Excel_Util {
static int fileinitial;

public Excel_Util(int filename) {
    fileinitial = filename;
    System.out.println("Constructor called...");
    System.out.println("Sheet number: " + fileinitial);
}

@DataProvider(name = "testdata")
public static Object[][] readexcelretobj() throws Exception {
    Object[][] object = new Object[1][2];
    object[0][0] = "Nandan";
    object[0][1] = "123456";
    System.out.println("Data provider called...");
    System.out.println("Sheet number: " + fileinitial);
    return object;
 }
}

Output :

Data provider called...
Sheet number: 0
Test started
Constructor called...
Sheet number: 2
Email: Nandan & Passowrd: 123456

If you see the above output the DataProvider code is being called first so your value is passing as 0 . To fix this call the new Excel_Util(2); object into DataProvider

Updated code :

@Test method :

@Test(dataProvider = "testdata", dataProviderClass = Excel_Util.class)
public void testsignupdatafields(String email, String password) {
    System.out.println("Test started");
    System.out.println("Email: " + email + " & Passowrd: " + password);

}

Excel_Util :

public class Excel_Util {
static int fileinitial;

public Excel_Util(int filename) {
    fileinitial = filename;
    System.out.println("Constructor called...");
    System.out.println("Sheet number: " + fileinitial);
}

@DataProvider(name = "testdata")
public static Object[][] readexcelretobj() throws Exception {
    new Excel_Util(2);
    Object[][] object = new Object[1][2];
    object[0][0] = "Nandan";
    object[0][1] = "123456";
    System.out.println("Data provider called...");
    System.out.println("Sheet number: " + fileinitial);
    return object;
 }
}

Output :

Constructor called...
Sheet number: 2
Data provider called...
Sheet number: 2
Test started
Email: Nandan & Passowrd: 123456

If you see the above output now the constructor is being called first.

As we discussed if you want to pass the value from Test class then you can do something like this. Instead of a constructor use static block.

Test class :

public class ClassTestNG {

static int sheetNumber = 2;

@Test(dataProvider = "testdata", dataProviderClass = Excel_Util.class)
public void testsignupdatafields(String email, String password) {
    System.out.println("Test started");
    System.out.println("Email: " + email + " & Passowrd: " + password);
}

Excel_Util :

public class Excel_Util {
static int fileinitial;
static {
    fileinitial = ClassTestNG.sheetNumber;
    System.out.println("Static called...");
    System.out.println("Sheet number: " + fileinitial);
}

@DataProvider(name = "testdata")
public static Object[][] readexcelretobj() throws Exception {
    Object[][] object = new Object[1][2];
    object[0][0] = "Nandan";
    object[0][1] = "123456";

    System.out.println("Data provider called...");
    System.out.println("Sheet number: " + fileinitial);
    return object;
 }
}

Output :

Static called...
Sheet number: 2
Data provider called...
Sheet number: 2
Test started
Email: Nandan & Passowrd: 123456

fileinitial=filename; It's a wonder you did not get an error message about a static int cannot be assigned from a non static context! Why not simply take static off your global fileinitial. *NB the class with the int problem were the main class and if you were calling from public static void main(String args[]) that would be different and not require assigning by the constructor, so if it is not the main class remove static keyword from variable "fileinitial".

Or build a static class (always nested subclass) to send the "non static filename argument" into (through) a static method and return it as static assignment from that method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM