I have just started using selenium grid with Testing tool for a web testing.
I have a class with this method #Test, I have hardcoded the URL here and wrote multiple methods with different URLs. but i want to pass those URL values from a txt file and the class should launch the
methods parallely for each URL from the txt file. please let me know how I can do it
#Test(description = "Showing bing")
#Parameters({"seleniumHost", "seleniumPort", "browser", "webSite"})
public void bing(String seleniumHost, int seleniumPort, String rowser, String webSite) throws Throwable {
try {
startSeleniumSession(seleniumHost, seleniumPort, browser, webSite);
Base b = new Base();
b.setInitialUrl("http://www.bing.com");
b.setMaxCount(30);
AssertJUnit.assertTrue(b.InitiateTest());
} finally {
closeSeleniumSession(); }
}
Can I use #Factory annotation here? Can you help me how I do write that class and place it where? I'am not using testng.xml here.
Please help.
To pass multiple data to your test, you can use testNG dataprovider. Details are clearly mentioned here
Related
I want to pass a dynamic parameter to a test case from testng xml, my parameter is something like:
String dynamicParameter=generateRandomStringForMail();
Here is my testcase:
#Test()
public void customerCreatorAllProducts () throws Exception {
setup();
Functions.pages.LoginPage login = PageFactory.initElements(driver, Functions.pages.LoginPage.class);
login.navigateRegisterPage().createFixedPasswordCustomerRequiredFields(dynamicParameter);
}
I will be using this parameter in other cases as well, how can i do this from testng.xml or with something else?
I am not familiar with testing.xml, but Mockito immediately comes to mind for this: http://mockito.org.
add Mockito to your project (e.g. through the build.gradle page)
add the import to your test file:
import static org.mockito.Mockito.*;
within your test class, create a mock of the class which has the generateRandomStringForMail() method. In my current project, I have
DefaultFileService mockFileService = mock(DefaultFileService.class);
define what you want the method to return under these test conditions, e.g.
when(mockFileService.generateRandomFileName()).thenReturn("fileName");
Whenever your tests need to use the result of the method in question, you can use "fileName", because you have told the test environment to give this response. My project has a method to update the image file associated with an inventory item, which process includes using the DefaultFileService to generate a random file name, then passing the image file and the new file name to the DefaultFileService to save the file in the system. My test code can't see or guess what file name would actually be produced, but my 'when' line above has resolved that problem for the purposes of testing my QuiltController class:
quiltController.update(data, mockFile);
verify(mockFileService).save(mockFile, "fileName"); // confirms the save() method was called with the expected parameters
It feels pretty similar to what you are trying to do, so hopefully that helps you proceed if you do want to explore Mockito. Don't be surprised if you need to refactor some of your work to make it more testable. I did, and have better code as a result. Give it a go :)
This is more of a question on test automation framework design. Very hard indeed to summarize whole question in one line :)
I am creating a test automation framework using Selenium. Mostly I am accessing the data (methods name) from an excel file.
In my main Runner class I am getting a list of test cases. Each test case has a set of methods (can be same or different) which I have defined in a java class and executing each method using java reflection api. Everything is fine till this point.
Now I want to incorporate TestNG and reporting/logging in my automation suite. Problem is I cant use #Test for each method as TestNG considers #Test = 1 Test Case - but my 1 Test case might have more than 1 methods. My methods are more like a test steps for a test case, reason is I dont want repeat the code. I want to create a #Test dynamically calling different sets of methods and executing them in Java Or defining each teststeps for a #Test. I was going through the TestNG documentation, but could not able to locate any feature to handle this situation.
Any help is really appreciated and if you have any other thoughts to handle this situaton I am here to listen.
Did you try the following?
#Test(priority = 1)
public void step1() {
//code
}
#Test(priority = 2)
public void step2() {
//code
}
You need to use "priority" for each method, otherwise it won't work.
I'm trying to set up a web app test suite using Selenium and Java. I am going to create 3 packages under src
Objects - used for my page objects
Tasks - used for testing methods
Tests - used for the tests
Under Tasks I created a class called CommonTasks, which is used to store methods created for testing. Here are some examples.
protected void verifyNumberOfElements(By selector, int expectedsize){
int size = driver.findElements(selector).size();
log.info("INFO: Verifying the number of elements is "+expectedsize+"");
Assert.assertEquals(size, expectedsize);
log.info("PASS: The number of elements returned was "+expectedsize+" ");
}
public static void verifyText(By selector, String expectedtext){
//verify that the expected text is present
String actualtext = driver.findElement(selector).getText();
Assert.assertEquals(actualtext, expectedtext);
log.info("PASS: "+expectedtext+" was present and verified");
}
protected void verifyElement(By selector){
//Verify that a certain selector is present in the page
smartSleep(selector);
boolean isPresent = driver.findElements(selector).size() > 0;
Assert.assertEquals(isPresent, true);
log.info("PASS: Element was found");
boolean notPresent = driver.findElements(selector).size() > 0;
Assert.assertEquals(notPresent, false);
log.info("FAIL: Element was NOT found");
}
Under the Tests package, I create a class called ABC for testing feature ABC. I have some basic steps like below
verifyText(PageObjects.ItemText, "Multiple Choice - Single Answer Radio - Vertical");
verifyText(PageObjects.Progress_PercentComplete, "0%");
The issue I am having is I don't know where to create the webdriver. I want to be able to create many test classes and call any method created in the Tasks package. I know that I need to import the class from Tasks, but can't figure out the webdriver creation part. Both the Tasks and Test packages will reference driver, so how to I make this work? Does it need to be created in Tasks.CommonTasks, or Tests.ABC?
I will also need the test to connect to SauceLabs instead of my local machine.
From the code above, all your methods in the Tasks packages are utility methods and are common to your test suite so these methods are invoked from the Test methods only where your driver was initialized already so create your webdriver in your test class and pass it on to utility methods in the tasks package.
Hope it helps
I am fairly new to Java so forgive me if this is a silly question, but believe me when I say I really cannot find a solid answer.
This is what I'm working with:
So I'm testing a program, and the easiest way to keep it maintained and updated is to create my own library of "buttons". Everything in the library are small functions like "enterValidCredentials" and "clickLoginButton".
So let's take a look at my test cases. In a perfect world I'd be able to just:
public class progressCheck {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("http://mail.google.com/");
enterValidCredentials;
clickLoginButton;
}
}
enterValidCredentials and clickLoginButton exist in my library of classes. I know very well that that's not going to work as written above. What, literally, is the correct way to do this?
If it helps at all, my enterValidCredentials class looks like this:
public class loginPageButtons {
private WebDriver driver;
Actions actions = new Actions(driver);
public class enterValidCredentials { // This class enters in a valid username and valid password on the login page.
public void enterValidCredentials2() {
driver.findElement(By.cssSelector("input[type=\"text\"]")).clear();
driver.findElement(By.cssSelector("input[type=\"text\"]")).sendKeys("XXXXXXXX");
driver.findElement(By.cssSelector("input[type=\"password\"]")).clear();
driver.findElement(By.cssSelector("input[type=\"password\"]")).sendKeys("XXXXXXXX");
}
}
All my other functions follow a relatively similar structure (depending on their function, of course).
You can use a unit test to check single functionalities of your classes.
The most used library to create unit tests is JUnit.
If you use an ide (like IntelliJ or Eclipse) running the test can be done with a simple command exactly as running a main method.
If you need to create mocks of your objects you can use a library like Mockito (but there are many other valid alternatives).
Note: A mock is an object that has the same interface as a complex object that is difficult to use in a test environment (for example a db connection, a file handler, a network handler).
Here is an example, I tried to imagine your code and a possible test. I assumed that clickLoginButton returns an integer just to show a possible assert statement.
Example:
#Test
public static void testCredentials() {
WebDriver driver = new FirefoxDriver();
driver.get("http://mail.google.com/");
EnterValidCredentials enterValidCredentials = new EnterValidCredentials(); // Or create a mock if necessary
// Set values if necessary
int returnValue = enterValidCredentials.clickLoginButton();
assertEquals(returnValue, 1);
}
I am learning selenium grid and testng.
I am trying to create customized html result using testng interfaces. my understanding on how to create html results is fine in a single machine execution.
But when i factor remote machines, i am not able to understand like how results are consolidated if tests are executed in parallel in remote machines?
Any factors should i consider before implementing my own interfaces?
Any help is appreciated..
Thanks in advance
It works fine, from multi-threaded tests to the HTML report because the ITestResult is always the same in the end, no matter what you do. You can simple create a "CustomReport" class that extends IReporter. Then, override the generateReport method and just let TestNG create and pass these 2 arguments into it:
#Override
public void generateReport( List<XmlSuite> xml, List<ISuite> suites, String outdir )
{
for ( ISuite thisSuite: suites ) {
thisSuite.getResults(). ...
...
}
....
Then, inside that method, do what you will, to customize the report and generate HTML tables or whatever.
Also, one thing I do (to reduce confusion in the console output while multithreaded tests run) is log the thread name to messages on the TestNG report by using something like:
public void logIt( String message ) {
Reporter.log( "Thread-" + Thread.currentThread().getId() + ": " + message, true );
}
TestNG is awesome, especially when you understand what I said above as well as the fact that you implicitly allow TestNG to pass a XMLTest or ITestContext or ITestResult to some of the #Configuration methods. For example:
#BeforeClass
public void setUp( ITestContext context ) {
logger.info("BeforeClass setUp...");
suiteParams = context.getSuite().getXmlSuite().getAllParameters();
...