I have a Selenium test case that I need to write, but before it executes I need to get some information from the user for the Test to run.
Currently, my code is structured like this:
public class myTest {
private WebDriver driver;
#Before
System.setProperty("webdriver.ie.driver",
"C:\\Users\\ktuck\\Documents\\Selenium\\Selenium Server\\IEDriverServer.exe");
driver = new InternetExplorerDriver(); // I guess I don't need to fire this up as i'm only collecting information from the user?
#Test
// Code to collect user inputted data to use later in my test
#After
public void tearDown() throws Exception {
driver.quit(); // Do I need this?
}
}
My initial thoughts were to put the collection code inside of a main function and then call the rest of my test script which would be in a different file, passing the information collected into it. But I'm not quite sure how to do that as I'm quite new to Selenium/Java :p
Can anyone help?
If you are not using any testing framework , you can choose TestNG. TestNG supports Data driven and parameterized test.
you can pass param via testng.xml.
since you are using maven you can configure maven to pass parameters without using testng.xml.
you can also pass params to TestNG via maven through command line like below
mvn -Dtest=<testName> -D<paramName>=<paramValue> test
if you dont want to use any of the testing framework then you can pass the param via JVM arg
and retrive it using System.getProperty("paramName")
Consider using a test framework like JUnit or TestNG. This would enable you to use methods that are run before and after the actual test (as indicated by the pseudo-code given above).
Using this approach, you can do all the lookup stuff in the #BeforeClass method and quit the webdriver in the #AfterTest method. To keep the test class clean, I recommend to move the #BeforeClass and #AfterTest to an abstract super class which you inherit from.
Abstract Superclass
public abstract class AbstractSeleniumTest {
private WebDriver webDriver;
#BeforeClass
public void setup() {
// do all the initalization stuff, e.g. system property lookup
}
#AfterTest(alwaysRun = true)
public void tearDown() {
// do all the clean-up stuff, e.g. webdriver.quit();
}
}
Test Class
#Test
public class MySeleniumTest extends AbstractSeleniumTest {
public void testSomething() {
// do the actual test logic
}
}
I hope this covers most of your question. For further assistance, please give more information.
Related
I'm trying to construct a suite of Cucumber tests using Selenium. The first step in each test logs in to a web application.
I'm using the Selenium ChromeDriver, and I can see that Cucumber is using dependency injection to initialise the driver. After each test completes I would like to start fresh with a new web browser, but Cucumber insists on using the same driver used in the previous test. I've tried a number of things to start from a clean point. I'm not sure what the recommended way of doing this is, I presume you have to use the 'Hooks' class, as that contains methods which run before and after each test scenario. Here's what I currently have:
public class Hooks {
private final WebDriver driver;
#Inject
public Hooks(final WebDriver driver) {
this.driver = driver;
}
#Before
public void openWebSite() {
}
#After
public void closeSession() {
driver.close();
}
}
As you can see, I put a driver.close() statement into the #After method, but I don't see a method to reopen, or recreate a new session, and I'm getting the following exception when the next test tries to log in:
Message: org.openqa.selenium.NoSuchSessionException: no such session
Presumably because it didn't like the fact that I just called close().
But really, I want to tell Cucumber that I'd like a completely fresh driver to be used for each test scenario.
I've searched around for Cucumber examples, but all the example code I've found just involves one single test. I didn't turn up anything which was using a suite of tests, aiming to do something similar to what I've described above.
What's the recommended pattern for this?
I am using TestNG with Selenium WebDriver, the framework that I use has one base class which has BeforeClass method and all the Suite classes extend from this base class and have overriden BeforeClass methods as shown.
public BaseClass{
#BeforeClass
public void preConditions{
//primary actions like opening browser and setting preferences
}
}
public TestSuiteClass extends BaseClass{
#BeforeClass
#Override
public void preConditions(){
super.preCnditions();
//specific preconditions required by test suite
}
}
The problem I am have is, if an overridden method is failing for any reason, all the test suits/cases gets skipped and entire test execution stops.
How to stop this from happening?
If something fails in #Before... annotated procedure the tests will be skipped instead of failing, because the problem is not with your test cases, but with the process before them. So it looks like your car cannot cross the river on a broken bridge, but it's not your car's fault.
If you really want to do some hacking about it, you can find ideas here!
You can find a way around this, but you need to consider if you realy want to do it. The idea of the method with #BeforeClass annotation is to set relevant data for the test (you even called it preConditions). If it fails, the test won't pass anyway.
One way to do it is to remove the #BeforeClass annotation and call the method from the test itself
public TestSuiteClass etends BaseClass {
public void customPreConditions() {
super.preCnditions();
}
#Test
publuc void someTest() {
customPreConditions();
// do the test
}
}
The test will continue even if customPreConditions() is not successful.
I am running a test over and over. Each time I run I see that another firefox appears as seen here:
Where can I add the driver.quit() (or similar) function so it properly cleans itself up on program close?
I am only calling driver with this:
me.Drivers.Test = new FirefoxDriver();
me.Drivers.Test.get(websiteLink);
Any assistance greatly appreciated.
You can use the test annotation and call me.Drivers.Test.quit() in #After (In JUnit its #After, every testing environment has its own naming convention).
Example:
#Before
public void before() {
me.Drivers.Test = new FirefoxDriver();
}
#Test
public void test() {
me.Drivers.Test.get(websiteLink);
}
#After
public void after() {
me.Drivers.Test.quit();
}
The #Before annotation will run before the test starts, some kind of test setup.
In #Test you are doing the actual testing.
And #After will run after the test is finished, and there you are doing all the cleaning.
For more details you can look here.
Like you initialize the driver you have to quit it.
Use:
me.Drivers.Test.quit()
I assume that me.Drivers.Test is an instance of WebDriver. So you can use me.Drivers.Test.quit() at the end of your script to quit the webdriver.
NEW USER ALERT
Using Java, webdriver and TestNG
I have 2 separate methods
1. For initiating driver
2. Login
I have called driver initiating method in #BeforeTest and this will also launch the application login page.
I also want to call the 'login' method in #BeforeTest (since this is needed by almost all of the tests) but problem is that I also have 4-5 tests for this login page (like testing version, copyright, forgot password link). So for these tests logging in is not required (or rather login should not happen).
Is there a way I can execute a set of method calls before tests pertaining to login page AND a different set of method calls before all other tests.
Please let me know if there's an alternate way this can be achieved.
Let me know if more information is required here.
I would create a base-class where I put the #BeforeTest method with login and let only the testclasses inherit it that will need a login:
public abstract class TestBaseForLogin{
#BeforeTest
public void loginBeforeEachTest() {
// do the login
}
}
Now if you wanna pool tests that need the login before each test, then just inherit from the baseclass.
public class TestThatNeedLogin extends TestBaseForLogin{
#BeforeTest
public void beforeEachTest() {
// do whatever you need before the test
}
}
Otherwise just go without the baseclass (or another baseclass)
public class TestLogin {
#BeforeTest
public void beforeEachTest() {
// do whatever you need before the test
}
}
Your inherited classes will FIRST execute the #BeforeTest of the base class and only after that their own #BeforeTest tagged methods.
The selenium tests I'm gonna be doing are basically based on three main steps, with different parameters. These parameters are passed in from a text file to the test. this allows easy completion of a test such as create three of "X" without writing the code to do the create three times in one test.
Imagine i have a test involving creating two of "X" and one of "Y". CreateX and CreateY are already defined in separate tests. Is there a nice way of calling the code contained in createX and createY from say, Test1?
I tried creating a class with the creates as seperate methods, but got errors on all the selenium.-anything-, ie every damn line. it goes away if i extend seleneseTestCase, but it seems that my other test classes wont import from a class that extends seleneseTestCase. I'm probably doing something idiotic but i might as well ask!
EDIT:
well for example, its gonna be the same setUp method for every test, so id like to only write that once... instead of a few hundred times...
public void ready() throws Exception
{
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "https://localhost:9443/");
selenium.start();
selenium.setSpeed("1000");
selenium.setTimeout("999999");
selenium.windowMaximize();
}
thats gonna be used EVERYWHERE.
its in a class called reuseable. Id like to just call reuseable.ready(); from the tests SetUp... but it wont let me....
public class ExampleTest {
#Before
public void setup() {
System.out.println("setup");
}
public void someSharedFunction() {
System.out.println("shared function");
}
#Test
public void test1() {
System.out.println("test1");
someSharedFunction();
}
#Test
public void test2() {
System.out.println("test2");
someSharedFunction();
}
}
The contents of the function after the #Before annotation is what will be executed before every test. someSharedFunction() is an example of a 'reusable' function. The code above will output the following:
setup
test1
shared function
setup
test2
shared function
I would recommend using JUnit and trying out some of the tutorials on junit.org. The problem you have described can be fixed using the #Before annotation on a method that performs this setup in a super class of your tests