質問で言及したコード構造を維持すると、遅かれ早かれそれを維持することは悪夢になります。ルールに固執するようにしてください:すべてのブラウザ(環境)に対して同じテストコード(1回記述)。
この状態では、2つの問題を解決する必要があります。
1)選択したすべてのブラウザでテストを実行する方法
2)テストコードを汚染せずに特定のブラウザの回避策を適用する方法
実際、これはあなたの質問のようです。
これが私が最初の問題を解決した方法です。まず、テストするすべての環境を定義しました。テストを実行するすべての条件(ブラウザー名、バージョン番号、OSなど)を「環境」と呼びます。したがって、テストコードとは別に、次のような列挙型を作成しました。
public enum Environments {
FF_18_WIN7("firefox", "18", Platform.WINDOWS),
CHR_24_WIN7("chrome", "24", Platform.WINDOWS),
IE_9_WIN7("internet explorer", "9", Platform.WINDOWS)
;
private final DesiredCapabilities capabilities;
private final String browserName;
private final String version;
private final Platform platform;
Environments(final String browserName, final String version, final Platform platform) {
this.browserName = browserName;
this.version = version;
this.platform = platform;
capabilities = new DesiredCapabilities();
}
public DesiredCapabilities capabilities() {
capabilities.setBrowserName(browserName);
capabilities.setVersion(version);
capabilities.setPlatform(platform);
return this.capabilities;
}
public String browserName() {
return browserName;
}
}
必要なときにいつでも環境を簡単に変更および追加できます。お気づきのとおり、私はこれを使用して、後で特定のWebDriverを作成するために使用されるDesiredCapabilitiesを作成および取得しています。
定義されたすべての環境でテストを実行するために、JUnit(私の場合は4.10)のorg.junit.experimental.theoriesを使用しました。
@RunWith(MyRunnerForSeleniumTests.class)
public class MyWebComponentTestClassIT {
@Rule
public MySeleniumRule selenium = new MySeleniumRule();
@DataPoints
public static Environments[] enviroments = Environments.values();
@Theory
public void sample_test(final Environments environment) {
Page initialPage = LoginPage.login(selenium.driverFor(environment), selenium.getUserName(), selenium.getUserPassword());
// your test code here
}
}
テストには(通常のJUnitテストのようにでは@Theory
なく)という注釈が付けられ、パラメーターが渡されます。@Test
次に、このパラメーターの定義されたすべての値に対して各テストが実行されます。これは、。として注釈が付けられた値の配列である必要があります@DataPoints
。また、から伸びるランナーを使用する必要がありますorg.junit.experimental.theories.Theories
。私はテストの準備に使用org.junit.rules
し、必要なすべての配管をそこに置きます。ご覧のとおり、私もルールを通じて特定の機能ドライバーを取得しています。ただし、テストでは次のコードを使用できます。
RemoteWebDriver driver = new RemoteWebDriver(new URL(some_url_string), environment.capabilities());
重要なのは、ルールにそれを含めると、コードを1回記述して、すべてのテストに使用するということです。Pageクラスは、ドライバーの機能(要素の検索、ナビゲートなど)を使用するすべてのコードを配置するクラスです。このようにして、テストコードはきちんと明確に保たれ、もう一度、一度記述してすべてのテストで使用します。だから、これは最初の問題の解決策です。(TestNGでも同様のことができることは知っていますが、試していません。)
2番目の問題を解決するために、ブラウザー固有の回避策のすべてのコードを保持する特別なパッケージを作成しました。これは、一部のブラウザでたまたま異なる(またはバグがある)共通コードを含む抽象クラス(例:BrowserSpecific)で構成されています。同じパッケージに、テストで使用されるすべてのブラウザーに固有のクラスがあり、それぞれがBrowserSpecificを拡張します。
あなたが言及したChromeドライバーのバグに対してどのように機能するかを次に示します。clickOnButton
影響を受ける動作の共通コードを使用して、BrowserSpecificでメソッドを作成します。
public abstract class BrowserSpecific {
protected final RemoteWebDriver driver;
protected BrowserSpecific(final RemoteWebDriver driver) {
this.driver = driver;
}
public static BrowserSpecific aBrowserSpecificFor(final RemoteWebDriver driver) {
BrowserSpecific browserSpecific = null;
if (Environments.FF_18_WIN7.browserName().contains(driver.getCapabilities().getBrowserName())) {
browserSpecific = new FireFoxSpecific(driver);
}
if (Environments.CHR_24_WIN7.browserName().contains(driver.getCapabilities().getBrowserName())) {
browserSpecific = new ChromeSpecific(driver);
}
if (Environments.IE_9_WIN7.browserName().contains(driver.getCapabilities().getBrowserName())) {
browserSpecific = new InternetExplorerSpecific(driver);
}
return browserSpecific;
}
public void clickOnButton(final WebElement button) {
button.click();
}
}
次に、回避策コードを配置する特定のクラス、たとえばChromeSpecificでこのメソッドをオーバーライドします。
public class ChromeSpecific extends BrowserSpecific {
ChromeSpecific(final RemoteWebDriver driver) {
super(driver);
}
@Override
public void clickOnButton(final WebElement button) {
// This is the Chrome workaround
String script = MessageFormat.format("window.scrollTo(0, {0});", button.getLocation().y);
driver.executeScript(script);
// Followed by common behaviour of all the browsers
super.clickOnButton(button);
}
}
一部のブラウザの特定の動作を考慮に入れる必要がある場合は、次のことを行います。
aBrowserSpecificFor(driver).clickOnButton(logoutButton);
それ以外の:
button.click();
このようにして、私の共通コードでは、回避策が適用された場所を簡単に識別でき、回避策を共通コードから分離したままにします。バグは通常解決されており、回避策は変更または削除される可能性があるため、保守が容易だと思います。
テストの実行について最後に一言。Selenium Gridを使用する場合は、テストを並行して実行する可能性を使用する必要があるため、JUnitテスト(v。4.7以降で使用可能)用にこの機能を構成することを忘れないでください。