Java: how can I put two String[] objects into one

2019-08-28 20:41发布

问题:

EDIT: I did a very heavy refactoring of the code and I fixed this issue. Fixed code is below the wrong code.

I have these two:

public String[] firstname = new String[2];
public String[] lastname = new String[2];

and I want to pass them to this method (which already accepts some data from elsewhere):

    @Parameters({ "driver", "wait", "firstname[]", "lastname[]" })
    @Test(dataProvider = "dataProvider")
public void oneUserTwoUser(WebDriver driver, WebDriverWait wait, String[] firstname, String[] lastname) {

        //code
    }

and this is the data provider from another class:

public class AppData extends CSVReader { //was public abstrac class before
    public static WebDriver driver;
    public WebDriverWait wait;
    public String[] firstname = new String[2];
    public String[] lastname = new String[2];
    public String firstname1;
    public String firstname2;
    public String lastname1;
    public String lastname2;

    @DataProvider(name = "dataProvider")
    public Object[][] setUp(ArrayList<ArrayList<String>> array) throws Exception {

        driver = new EventFiringWebDriver(new FirefoxDriver(ffox, profile, dc))
                .register(eventListener);
        wait = new WebDriverWait(driver, timeoutInSeconds);

        int randomUser1 = randomizer (1, 250);
        int randomUser2 = randomizer (1, 250);
        firstname1 = array.get(randomUser1).get(0);
        firstname2 = array.get(randomUser2).get(0);
        lastname1 = array.get(randomUser1).get(1);
        lastname2 = array.get(randomUser2).get(1);

        firstname[0] = firstname1.replace(" ", "");
        firstname[1] = firstname2.replace(" ", "");
        lastname[0] = lastname1.replace(" ", "");
        lastname[1] = lastname2.replace(" ", "");


    Object[][] setUp = new Object[1][4];
    setUp[0][0] = driver;
    setUp[0][1] = wait;
    setUp[0][2] = firstname;
    setUp[0][3] = lastname;
    return setUp;
    }

Can you tell me what Im doing wrong here? Im new to Java - 4 weeks.

Im getting this error:

SKIPPED: oneUserTwoUser
java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)

EDIT Here is the refactored code that works

    @Parameters({ "driver", "wait", "array" })
    @Test(dataProvider = "dataProvider")
    public void oneUserTwoUser(WebDriver driver, WebDriverWait wait, ArrayList<ArrayList<String>> array) throws Exception {
        String[] firstname = new String[2];
        String[] lastname = new String[2];
        String firstname1;
        String firstname2;
        String lastname1;
        String lastname2;
        //parametrize tests by reading the array passed from CSV reader class
                int randomUser1 = randomizer(1, 250);
                int randomUser2 = randomizer(1, 250);
                firstname1 = array.get(randomUser1).get(0);
                firstname2 = array.get(randomUser2).get(0);
                lastname1 = array.get(randomUser1).get(1);
                lastname2 = array.get(randomUser2).get(1);
                firstname[0] = firstname1.replace(" ", "");
                firstname[1] = firstname2.replace(" ", "");
                lastname[0] = lastname1.replace(" ", "");
                lastname[1] = lastname2.replace(" ", "");
                System.out.println(firstname[0]);
                System.out.println(lastname[0]);
                System.out.println(firstname[1]);
                System.out.println(lastname[1]);

}

public abstract class AppData extends Mailer {
    public static WebDriver driver;
    public static WebDriverWait wait;
    static AppTest3 instance;

    @DataProvider(name = "dataProvider")
    public Object[][] setUp() throws Exception {


        // change to false if testing on local machine, so selenium will pick up the correct firefox binary.
        Boolean testingOnServer1 = false; //
        File firefoxPath;
        if (testingOnServer1 == true) {
            firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "/opt/firefox/firefox")); // usr/bin/firefox - another firefox isntallation
        } else {
            firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"));
            // "c:\\Program Files\\Mozilla Firefox\\firefox.exe")); //for testing at home
        }

        //prepare Firefox and run it on Xvfb
        long timeoutInSeconds = 30;
        FirefoxProfile profile = new FirefoxProfile();
        profile.setPreference("dom.max_chrome_script_run_time", "120");
        profile.setPreference("dom.max_script_run_time", "120");
        FirefoxBinary ffox = new FirefoxBinary(firefoxPath);
        ffox.setEnvironmentProperty("DISPLAY", ":21");
        DesiredCapabilities dc = new DesiredCapabilities();
        dc.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT);
        WebDriverEventListener eventListener = new MyEventListener();
        driver = new EventFiringWebDriver(new FirefoxDriver(ffox, profile, dc)).register(eventListener);
        wait = new WebDriverWait(driver, timeoutInSeconds);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);


        final String FILE_PATH = "C:\\250.csv";

            CSVReader reader = new CSVReader(new FileReader(FILE_PATH));
            ArrayList<ArrayList<String>> array = new ArrayList<ArrayList<String>>();
            String[] nextLine;
            while ((nextLine = reader.readNext()) != null) {
                ArrayList<String> list = new ArrayList<String>();
                for (int i = 0; i < 5; i++) { // 5 is the number of sheets
                    list.add(nextLine[i]);
                }
                array.add(list);

            }
            instance = new AppTest3(); 
            instance.oneUserTwoUser(driver, wait, array);
            reader.close();


        Object[][] setUp = new Object[1][3];
        setUp[0][0] = driver;
        setUp[0][1] = wait;
        setUp[0][2] = array;
        return setUp;
}

回答1:

@DataProvider is from TestNG, and yes it needs to be a 2D array (so a test can be run multiple times from different sets of data)

What you are doing wrong is your @Parameters(...) line. The Parameters annotation and the DataProvider annotation are for the same purpose but they do it in different ways.

However, I am also confused at your setUp function...as a DataProvider function shouldn't accept parameters (except for Method). Consider a different way of giving it that ArrayList<ArrayList<String>> such as the way explained in this post.

Finally, you comment said that that class was public abstract...is your test in the same class as your @DataProvider? If not, the class with the @Test must extend the class with the @DataProvider. (And I would recommmend making it abstract, but that's up to you)



回答2:

I don't know the Selenium API, but based on your stacktrace you might want to try this if you're automatically injecting parameters and it's throwing that error.

    Objec[] data = new Object[4];
    data[0] = driver;
    data[1] = wait;
    data[2] = firstname;
    data[3] = lastname;

It would make no logical sense for it to be a multidimensional array because arrays themselves are objects in Java and an injection method for passing in parameters as an Object array would probably take that into account. Therefore the firstname and lastname arrays can just as easily be treated like any Object descendant in that one dimensional array.



标签: java testng