[JAVA] Accelerate Selenium execution time with JUnit ClassRule annotation

Introduction

When testing with Selenium, it is common (I think) to start / stop the browser for each test method. However, I wanted to shorten it because the execution time would increase considerably if the browser was restarted every time.

I think there are various methods, but this time I tried using the ClassRule annotation of JUnit4. If you declare it in ClassRule, new / quit of WebDriver can be done for each test class, so it will be shortened accordingly.

↓ Regarding Rule / Class Rule, this one is easier to understand. http://qiita.com/Chayata/items/dd31e22bca6df6c91793

Implementation

To use Rule annotation, it is necessary to implement a dedicated class and make it a field of test method. For details, refer to this repository (https://github.com/knakamatsu/SeleniumJUnitRuleSample)

Rule side

Implement the class by inheriting ExternalResouce and generate WebDriver as the field of the class. Since the overrided after method becomes the post-processing of junit, implement quit of WebDriver in after.

WebDriverRule.java


public class WebDriverRule extends ExternalResource {

	private WebDriver driver;
	public WebDriver getDriver() {
		return getInstance();
	}

	@Override
	protected void after() {
		this.driver.quit();
	}

	private WebDriver getInstance(){
		if(this.driver == null){
			this.driver = new ChromeDriver();
		}
		return this.driver;
	}
}

Test execution side

The implemented Rule class can be used in both @Rule and @ClassRule, and they are as follows. When declared with @ClassRule, before / after corresponds to pre-processing and post-processing for each class (@BeforeClass and @AfterClass) When declared with @Rule, before / after corresponds to pre-processing and post-processing for each method (@setUp and @tearDown)

Test.java


public class classSample {
	@ClassRule
	public static WebDriverRule dr = new WebDriverRule();

	@Test
	public void test(){
		WebDriver d = dr.getDriver();
		d.get("https://www.google.co.jp/");
		WebElement el = d.findElement(By.cssSelector("input[aria-label='Search']"));
		el.sendKeys("chrome test.");
	}
}

Comparison

QS_20170513-195323.png Implementation with @ClassRule on the upper side and @Rule on the lower side. Both tests are the same. In the test class made with the sample, there is a difference of about 10 seconds. In the case of ClassRule, the browser is started only for the first test method, so the more test methods there are, the more effective it is. In the test environment, it took about 5 seconds to start the browser.

Summary

It depends on the test target, but restarting the browser for each test method is often excessive, so I prefer to do this. However, even if there is a dependency between the test methods, it is difficult to notice (such as information remaining in the cookie and moving accidentally), so be careful.

Recommended Posts

Accelerate Selenium execution time with JUnit ClassRule annotation
JUnit 5 gradle test fails with lombok annotation