2
votes

I'm writing Java based selenium-web-driver tests to run a parallel cross browser test using testng . I have set the tests to run parallel on my xml file.The file looks like this :

 <suite name="TestSuite" thread-count="2" parallel="tests" >    
 <test name="ChromeTest">
  <parameter name="browser" value="Chrome" />               
   <classes>
      <class name="test.login"/>
      <class name="test.main"/>
      <class name="test.logout"/> 
   </classes>  
 </test>

<test name="FirefoxTest">
 <parameter name="browser" value="Firefox" />              
   <classes>
      <class name="test.login"/>
      <class name="test.main"/>
      <class name="test.logout"/> 
   </classes>  
 </test>

But when i run test, both browser instances gets opened (Chrome opens first and starts execution and after a delay Firefox is opened). In that case , the driver object gets overwritten by Firefox driver and chrome stops execution.Tests continue execution on Firefox and gets completed successfully.

The structure of the project is like this :

  • Created a driverbase.class to load driver corresponding to browser which has my @Beforesuite.
  • Crteated individual classes for pages.(Eg: login.class , main.class etc) which has only @Test method and have extended driverbase class to get driver.

Test are run suceessfully when i set parallel to none on xml file

<suite name="TestSuite" thread-count="2" parallel="none" >

How can i overcome this issue? How to run tests in parallel without this issue?

The driverbase class is like this :

public class driverbase {
	
	  private String baseUrl;
	  private String nodeUrl;
	  private boolean acceptNextAlert = true;
	  private StringBuffer verificationErrors = new StringBuffer();
	  
	public static WebDriver driver = null;
		     		  
	  	/**
		 
	   * This function will execute before each Test tag in testng.xml

	   * @param browser

	   * @throws Exception

	   */
	      	  
	@BeforeSuite

	@Parameters("browser")

	  public WebDriver setup(String browser) throws Exception{
		
	      //Check if parameter passed from TestNG is 'firefox'
			
	      if(browser.equalsIgnoreCase("firefox")){
	    	  
	    	  System.out.println("Browser  : "+browser);
	    	      	
	    	  FirefoxProfile profile = new FirefoxProfile();
	 		  profile.setAcceptUntrustedCertificates(true);
	 		
	 		  //create firefox instance
	 		  driver = new FirefoxDriver(profile);
	 			  
	      }
	      
	      //Check if parameter passed as 'chrome'

	      else if(browser.equalsIgnoreCase("chrome")){

	    	  System.out.println("Browser  : "+browser);
	    	      	  
	    //set path to chromedriver.exe You may need to download it from http://code.google.com/p/selenium/wiki/ChromeDriver

	          System.setProperty("webdriver.chrome.driver","C:\\chromedriver.exe");

	          ChromeOptions options = new ChromeOptions();
	          options.addArguments("--test-type");
	        
	 			//create chrome instance
		          
	        	  driver = new ChromeDriver(options);
	        	
	      }
	    
	       else{

	          //If no browser passed throw exception
	    	   
	    	   System.out.println("Browser  is incorrect");

	          throw new Exception("Browser is not correct");

	       }
	  
	      driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
	      driver.manage().window().maximize();
		  return driver;
	  
	}

Thanks for the help :)

2
can you post driverbase.java?Mona
Added driverbase code snippetSijin

2 Answers

1
votes
  1. @BeforeSuite methods are not supposed to return something. => replace by void
  2. Your testng has 2 differents tests, but @BeforeSuite will always be run once by suite what your comment shows you doesn't expect it. => replace by @BeforeTest
  3. When you run in //, 2 threads are settings the driver value (one with firefox, one with chrome) which explains your problem.

You can try something like:

public class driverbase {

  private String baseUrl;
  private String nodeUrl;
  private boolean acceptNextAlert = true;
  private StringBuffer verificationErrors = new StringBuffer();   
  public WebDriver driver;

  @BeforeTest
  @Parameters("browser")
  public void setup(String browser) throws Exception {
      if(browser.equalsIgnoreCase("firefox")) {
          FirefoxProfile profile = new FirefoxProfile();
          profile.setAcceptUntrustedCertificates(true);
          driver = new FirefoxDriver(profile);
      } else if(browser.equalsIgnoreCase("chrome")) {
          System.setProperty("webdriver.chrome.driver","C:\\chromedriver.exe");
          ChromeOptions options = new ChromeOptions();
          options.addArguments("--test-type");
          driver = new ChromeDriver(options);
      } else {
          throw new Exception("Browser is not correct");
      }

      driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
      driver.manage().window().maximize();
}

You should have a look on http://fluentlenium.org/ too.

0
votes

To sure that same instance of webdriver won't be assigned to multiple tests. The method where driver instances are being created should be synchronized. This should solve the issue.

public synchronized void setup(String browser) throws Exception {
      if(browser.equalsIgnoreCase("firefox")) {
          FirefoxProfile profile = new FirefoxProfile();
          profile.setAcceptUntrustedCertificates(true);
          driver = new FirefoxDriver(profile);
      } else if(browser.equalsIgnoreCase("chrome")) {
          System.setProperty("webdriver.chrome.driver","C:\\chromedriver.exe");
          ChromeOptions options = new ChromeOptions();
          options.addArguments("--test-type");
          driver = new ChromeDriver(options);
      } else {
          throw new Exception("Browser is not correct");
      }

      driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
      driver.manage().window().maximize();
}