Reputation: 14711
3 weeks of experience with Java here. I have these two classes - AppTest and AppTest2 and I have the same code in both of them:
Here is my code:
public class Apptest/AppTest2 {
public WebDriver driver;
public WebDriverWait wait;
@DataProvider(name = "dataProvider")
public Object[][] setUp() throws Exception {
File firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"));
FirefoxBinary ffox = new FirefoxBinary(firefoxPath);
ffox.setEnvironmentProperty("DISPLAY", ":20");
driver = new FirefoxDriver(ffox, null);
wait = new WebDriverWait(driver, timeoutInSeconds );
Object[][] data = new Object[1][2];
data[0][0] = driver;
data[0][1] = wait;
return data;
}
@Parameters({ "driver", "wait" })
@Test(dataProvider = "dataProvider")
public void twoUsersSignUp(WebDriver driver, WebDriverWait wait) throws InterruptedException{
//test here
}
}
How can I take this code out (setUp()), make it a class and then pass those variables to the next void "twoUsersSignUp"
EDIT: Im not looking for automatic solution, I just want to refactor this, so I dont have the same code in both classes
EDIT2: After I implemented the accepted answer's solution, I now have a problem with passing the variable "driver" to the next method in the first class:
@AfterClass
public void quit () {
driver.quit();
}
How do I do that?
EDIT3: This is the @AfterClass solution:
@SuppressWarnings("deprecation")
@Configuration
@AfterClass
public static void quit (@Optional WebDriver driver) {
driver.quit();
}
EDIT4: actually EDIT3 doesnt work, it just hides the errors from Eclipse. I still can't access "driver" :(
EDIT5: I decided that I dont need to have it in an AfterClass TestNG annotation, so I removed all the unnecessary stuff and it now looks like this:
public static void quit (WebDriver driver) {
driver.quit();
}
and the variable has been declared this way:
public static WebDriver driver;
but still it doesnt work
EDIT6: fixed this by actually calling the method in the test code. Beforehand I didnt have to call it, because testng.xml had it called, but after I removed the @AfterTest annotation, it had been excluded from there!
Upvotes: 1
Views: 254
Reputation: 4511
Initialize your testData class like this
public class ApptestData{
public WebDriver driver;
public WebDriverWait wait;
public ApptestData() throws Exception {
File firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"));
FirefoxBinary ffox = new FirefoxBinary(firefoxPath);
ffox.setEnvironmentProperty("DISPLAY", ":20");
driver = new FirefoxDriver(ffox, null);
wait = new WebDriverWait(driver, timeoutInSeconds );
Object[][] data = new Object[1][2];
data[0][0] = driver;
data[0][1] = wait;
twoUsersSignUp(data);
return data;
}
}
And then use that object in your test classes
public class Apptest/AppTest2 {
@Test
public void twoUsersSignUp() throws InterruptedException{
AppTestData data = new AppTestData();
//test here
}
}
Upvotes: 1
Reputation: 726489
You cannot convert a method to a class, but you can move a method to a place from which it would be shared by both Apptest
and AppTest2
: create a base class, and make the Apptest
and AppTest2
classes extend it.
public abstract class AbstractAppTest {
public WebDriver driver;
public WebDriverWait wait;
@DataProvider(name = "dataProvider")
public Object[][] setUp() throws Exception {
File firefoxPath = new File(System.getProperty("lmportal.deploy.firefox.path", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"));
FirefoxBinary ffox = new FirefoxBinary(firefoxPath);
ffox.setEnvironmentProperty("DISPLAY", ":20");
driver = new FirefoxDriver(ffox, null);
wait = new WebDriverWait(driver, timeoutInSeconds );
Object[][] data = new Object[1][2];
data[0][0] = driver;
data[0][1] = wait;
twoUsersSignUp(data);
return data;
}
public abstract void twoUsersSignUp(@Optional Object[][] data) throws InterruptedException;
}
public class Apptest extends AbstractAppTest {
public void twoUsersSignUp(@Optional Object[][] data) throws InterruptedException {
...
}
}
public class AppTest2 extends AbstractAppTest {
public void twoUsersSignUp(@Optional Object[][] data) throws InterruptedException {
...
}
}
Now the code of the setUp
method does not need to be repeated, and it uses the implementation of the twoUsersSignUp
method provided in each of the two subclasses of AbstractAppTest
.
Upvotes: 2
Reputation: 50203
The kind of refactoring you are looking for does not exists yet, at least on Eclipse.
A workaround to do it manually is explained here
By the way, in Eclipse by pressing ALT SHIFT T you will find all the current available possibilities to refactor your existent code, by extracting methods, classes etc.
Upvotes: 0
Reputation: 482
You can't just convert a method to a class.
However, you can create new objects or modify existing objects.
Upvotes: 1