Общие настройки веб-драйвера Selenium-Jupiter не применяются
Я хочу использовать Selenium-Jupiter в моем проекте Spring Boot Project, но мое требование - переключить реализацию WebDriver во время выполнения - в зависимости от среды выполнения - с использованием одного общего базового класса для всех тестов.
Я уже проверил этот пост и этот, но я не мог заставить его работать.
Трассировки стека:
2020-09-17 23:17:47.196 INFO 14092 --- [ Test worker] d[....path....].SignupPageTest : Started SignupPageTest in 26.133 seconds (JVM running for 29.179)
2020-09-17 23:17:47.498 WARN 14092 --- [ Test worker] i.g.bonigarcia.seljup.SeleniumExtension : Driver handler for context id [engine:junit-jupiter]/[class:de,[....path....].SignupPageTest]/[method:verifyLogInPage(org.openqa.selenium.WebDriver)] not found
Failed to resolve parameter [org.openqa.selenium.WebDriver genDriver] in method [public void de.[....path....].SignupPageTest.verifyLogInPage(org.openqa.selenium.WebDriver) throws java.lang.Exception]: org/glassfish/hk2/api/MultiException
org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [org.openqa.selenium.WebDriver genDriver] in method [public void de.[....path....].SignupPageTest.verifyLogInPage(org.openqa.selenium.WebDriver) throws java.lang.Exception]: org/glassfish/hk2/api/MultiException
at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:239)
at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:183)
at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:144)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:96)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy5.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:133)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.NoClassDefFoundError: org/glassfish/hk2/api/MultiException
at io.github.bonigarcia.seljup.DockerService.<init>(DockerService.java:79)
at io.github.bonigarcia.seljup.SeleniumExtension.initHandlerForDocker(SeleniumExtension.java:381)
at io.github.bonigarcia.seljup.SeleniumExtension.getDriverHandler(SeleniumExtension.java:242)
at io.github.bonigarcia.seljup.SeleniumExtension.resolveParameter(SeleniumExtension.java:220)
at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:216)
... 73 more
Caused by: java.lang.ClassNotFoundException: org.glassfish.hk2.api.MultiException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 78 more
de.[....path....].SignupPageTest > verifyLogInPage(WebDriver) FAILED
org.junit.jupiter.api.extension.ParameterResolutionException at ExecutableInvoker.java:239
Caused by: java.lang.NoClassDefFoundError at DockerService.java:79
Caused by: java.lang.ClassNotFoundException at BuiltinClassLoader.java:602
Просто заранее с хром-драйвером все работает нормально, но не с обычным веб-драйвером.
Я использую Java14 и создал дополнительный исходный набор для тестов на селен под названием "endToEndTest"
Вот все, что связано с gradle.build:
sourceCompatibility = 14
sourceSets {
endToEndTest {
java.srcDir('src/end-to-end-test/java')
resources.srcDir file('src/end-to-end-tests/resources')
compileClasspath += sourceSets.main.output + configurations.testRuntime
runtimeClasspath += output + compileClasspath
}
}
configurations {
endToEndTestImplementation.extendsFrom testImplementation
endToEndTestRuntimeOnly.extendsFrom testRuntimeOnly
}
task endToEndTest(type: Test) {
testClassesDirs = sourceSets.endToEndTest.output.classesDirs
classpath = sourceSets.endToEndTest.runtimeClasspath
useJUnitPlatform ()
}
endToEndTestImplementation('io.github.bonigarcia:selenium-jupiter:3.3.5')
У меня есть базовый класс, от которого должен расширяться любой другой тестовый класс. Он заботится о запуске веб-среды и т. Д.
Базовый класс
@ExtendWith({SpringExtension.class})
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SeleniumBaseTestEnvironment {
@RegisterExtension
static SeleniumExtension seleniumJupiter = new SeleniumExtension();
@LocalServerPort
protected int serverPort;
@BeforeAll
public static void beforeAll() {
//both seems to have no impact
seleniumJupiter.getConfig().setDefaultBrowser("chrome");
seleniumJupiter.addBrowsers(BrowserBuilder.chrome().build());
}
protected String getUrl(String address) {
return "http://localhost:" + serverPort + address;
}
}
Testclass Он отлично работает, если я заменю WebDriver на ChromeDriver. Но мне нужен универсальный драйвер.
public class SignupPageTest extends SeleniumBaseTestEnvironment {
@Test
public void verifyLogInPage(WebDriver genDriver) throws Exception {
genDriver.get(getUrl("/"));
List<WebElement> cardTitleList = genDriver.findElements(By.className("card-title"));
List<WebElement> navbar = genDriver.findElements(By.className("navbar-toggler collapsed"));
assertEquals(cardTitleList.get(0).getText(), "Login");
assertTrue(navbar.isEmpty());
}
}
Похоже, мои настройки браузера по умолчанию не применяются. Другие настройки, такие как для снимков экрана, работают нормально.
1 ответ
Согласно моим исследованиям, добавление браузеров в Selenium Extension работает только для функции тестовых шаблонов в Selenium Jupiter.
Таким образом, при использовании тестовых шаблонов следующий код должен работать:
@ExtendWith({SpringExtension.class})
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SeleniumBaseTestEnvironment {
@RegisterExtension
static SeleniumExtension seleniumJupiter = new SeleniumExtension();
@LocalServerPort
protected int serverPort;
@BeforeAll
public static void beforeAll() {
String browsersList = System.getProperty("prop.browsers.list");
List<String> browsers = Arrays.asList(browsersList.split(","));
if (browsers.contains("chrome")) {
seleniumJupiter.addBrowsers(BrowserBuilder.chrome().build());
}
if (browsers.contains("firefox")) {
seleniumJupiter.addBrowsers(BrowserBuilder.firefox().build());
}
//----// All browsers you need
}
protected String getUrl(String address) {
return "http://localhost:" + serverPort + address;
}
public class SignupPageTest extends SeleniumBaseTestEnvironment {
@TestTemplate
public void verifyLogInPage(WebDriver genDriver) throws Exception {
genDriver.get(getUrl("/"));
List<WebElement> cardTitleList = genDriver.findElements(By.className("card-title"));
List<WebElement> navbar = genDriver.findElements(By.className("navbar-toggler collapsed"));
assertEquals(cardTitleList.get(0).getText(), "Login");
assertTrue(navbar.isEmpty());
}
}
Пожалуйста, обратите внимание:
- В моем примере я использую вариант виртуальной машины
-Dprop.browsers.list=chrome,firefox
чтобы включить в тест несколько браузеров. - Аннотации
@TestTemplate
следует размещать для каждого метода всех подклассов SeleniumBaseTestEnvironment (вы можете создать свою собственную аннотацию уровня класса, чтобы обойти это). - Чтобы переключить
Webdriver
реализации, вы можете настроить конфигурацию Spring для каждой среды, которая предоставит соответствующий список драйверов.