Ich habe viele Fragen zu diesem Thema gesehen, aber keine scheint zu dem zu gehören, wonach ich suche. Ich versuche, parallel Methoden unter einer einzigen Klasse mit dem @BeforeMethod
zu starten, den Browser zu starten, und @AfterMethod
, um den Browser abzureißen. In diesem Beispiel wollen wir sagen, dass es sich um eine einzelne Klassendatei handelt, in der mehrere Testmethoden enthalten sind. Ich möchte 4 von ihnen gleichzeitig in verschiedenen Browsern ausführen. Wir verwenden Groovy, aber eine Java-Antwort würde ausreichen.TestNG Selen mit parallelen Gewinden
XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="sampleSuite" thread-count="4" preserve-order="true" parallel="methods">
<test name="sample">
<classes>
<class name="tests.some.class.MyClassFile"/>
</classes>
</test>
</suite>
DriverFactory Klasse, die verantwortlich für einfach das Erstellen und Zurückgeben eines Browsers ist:
private static WebDriver createWebDriver() {
String property = System.getProperty("driver", "chrome")
def capabilities
if (property == "chrome") {
capabilities = DesiredCapabilities.chrome()
} else if (property == "firefox") {
System.setProperty("webdriver.gecko.driver", "/usr/local/Cellar/geckodriver/0.16.1/bin/geckodriver")
capabilities = DesiredCapabilities.firefox()
}
def url = System.getProperty("seleniumServerUrl", "http://localhost:4444/wd/hub")
if (!url) {
throw new IllegalStateException("No 'seleniumServerUrl' system property set")
}
def webDriver = new RemoteWebDriver(new URL(url), capabilities)
webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS)
webDriver.manage().window().setSize(new Dimension(1920,1080))
Runtime.addShutdownHook {
try {
webDriver.quit()
} catch (ignore) {}
}
webDriver
}
Zum Gewindeschneiden, auch in DriverFactory Klasse:
static final WebDriver createStackWebDriver(){
ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>(){
protected WebDriver initialValue(){
createWebDriver()
}
}
webDriver.get()
}
Jetzt Ich habe eine TestPlatform-Klasse, die das zentrale "Aufbau- und Abbau-Stück" der Architektur ist. Alle meine Klassendateien, die die @Test
Methoden enthalten erweitert diese TestPlatform Klasse:
class TestPlatform {
WebDriver webDriver
@BeforeMethod
void startUpWebBrowser(){
webDriver = DriverFactory.createStackWebDriver()
}
@AfterMethod
void quitWebDriver(){
webDriver.quit()
}
}
Wenn wir die XML-Datei ausführen, was wir 4 Fälle von startUpWebBrowser()
sehen, der 4 würde „pass“ ein und auch weiterhin die Test, und es wird sofort 4 Methoden aus einer Instanz von startUpWebBrowser()
öffnen, während die anderen 3 einfach "hängen" bleiben. Wir benötigen es, um einen Browser in jeder Instanz zu öffnen, anstatt 4 Browser in einer Instanz.
Unsere aktuelle Problemumgehung ist EACH @Test
Methode innerhalb der eigenen Klasse wickeln, und die @BeforeMethod
in @BeforeClass
sowie den after ändern. Das funktioniert irgendwie, ist aber auf der Berichtsseite sehr hässlich, und es gibt andere wenige Nachteile auf diese Weise.
Gibt es eine Lösung für dieses Problem ohne eine Überarbeitung der aktuellen Architektur? Fehle ich gerade etwas sehr einfaches?
Die Webdriver-Variable in der TestPlatform ist nicht threadsicher. Wäre es nicht einfacher, die ThreadLocal-Variable als statische final in die TestPlatform-Klasse zu verschieben und die DriverFactory.createWebDriver() in der initialValue-Methode aufzurufen. Keine Notwendigkeit für die Vorher-Methode, da Sie den threadspezifischen Treiber mit get() für die threadlokale Variable in den Testmethoden erhalten können. Außerdem haben Sie einen Shutdown-Hook für die Treiber-Quit-Methode und auch einen Quit-Aufruf im Aftermethod. Das Aftermethod kann auch entfernt werden. – Grasshopper