Java 如何在SeleniumJupiter的基类中以编程方式配置WebDriver?

Java 如何在SeleniumJupiter的基类中以编程方式配置WebDriver?,java,selenium-webdriver,junit,selenium-jupiter,Java,Selenium Webdriver,Junit,Selenium Jupiter,我想将现有的基于JUnit4的Selenium测试迁移到JUnit5。为此,我想利用 测试必须满足的一个要求是,能够在运行时基于执行环境切换WebDriver实现,为所有测试使用一个公共基类: 在开发人员机器(Windows 10)上执行时,应使用FirefoxDriver,启动本地安装的Firefox 在CI环境(CentOS 7)中,应使用RemoteWebDriver,将测试执行委托给Selenium网格 我已经尝试配置“通用WebDriver”,但我不知道如何为RemoteWebDr

我想将现有的基于JUnit4的Selenium测试迁移到JUnit5。为此,我想利用

测试必须满足的一个要求是,能够在运行时基于执行环境切换WebDriver实现,为所有测试使用一个公共基类:

  • 在开发人员机器(Windows 10)上执行时,应使用FirefoxDriver,启动本地安装的Firefox
  • 在CI环境(CentOS 7)中,应使用RemoteWebDriver,将测试执行委托给Selenium网格
我已经尝试配置“通用WebDriver”,但我不知道如何为RemoteWebDriver实现这一点(“示例2”应该让事情更清楚)

关于内容,但没有给出令人满意的答案

更新:我自己解决了这个问题。参见“示例3”


嘿,也许你想更新一下Selenium Jupiter文档。至少我有一些问题,弄明白了。。。哦,非常感谢您在Selenium Jupiter(以及底层WebDriverManager)上所做的出色工作


示例1:什么有效但不优雅

@ExtendWith(SeleniumExtension.class)
class MyTest {

  @EnabledIfSystemProperty(named = "os.name", matches = "Windows 10")
  @Test
  void test_executed_with_local_firefox(FirefoxDriver ffDriver) {
     executeTestCaseWith(ffDriver);
  }

  @EnabledIfSystemProperty(named = "os.name", matches = "Linux")
  @Test
  void test_executed_with_firefox_from_selenium_grid(@DriverUrl("http://...") RemoteWebDriver remoteDriver) {
     executeTestCaseWith(remoteDriver);
  }

  void executeTestCaseWith(WebDriver webDriver) {
     webDriver.get(...)
     Assert(...)
  }
}
我看到的问题是:

  • 非常详细(虽然这可能需要通过自定义注释来处理)
  • 对于一个逻辑/语义测试用例,每个测试类需要两个测试方法
  • 具体的WebDriver实现是公开的,因此,允许测试作者依赖WebDriver实现细节(例如,Firefox配置文件)
  • 示例2:我想做但不起作用的事情

    @ExtendWith(SeleniumExtension.class)
    class MyTest {
    
      @EnabledIfSystemProperty(named = "os.name", matches = "Windows 10")
      @Test
      void test_executed_with_local_firefox(FirefoxDriver ffDriver) {
         executeTestCaseWith(ffDriver);
      }
    
      @EnabledIfSystemProperty(named = "os.name", matches = "Linux")
      @Test
      void test_executed_with_firefox_from_selenium_grid(@DriverUrl("http://...") RemoteWebDriver remoteDriver) {
         executeTestCaseWith(remoteDriver);
      }
    
      void executeTestCaseWith(WebDriver webDriver) {
         webDriver.get(...)
         Assert(...)
      }
    }
    
    基类,用于WebDriver配置:

    abstract class UiTest {
    
       @RegisterExtension
       static SeleniumExtension seleniumExtension = new SeleniumExtension();     
    
       @BeforeAll
       static void setUpOnce() {
    
         // This check is not the problem discussed here
         boolean isRunningInCiEnvironment = ...
         Browser firefox;
    
          if( ! isRunningInCiEnvironment ) {
            // This works
            firefox = BrowserBuilder.firefox().build();
          } else {
            // this does not exist yet!
            //firefox = BrowserBuilder.remoteWebDriver().url("http://...").build();
    
            // This executes, but does not behave as expected
            // The URL is pretty much ignored.
            firefox = BrowserBuilder.firefox().url("http://...").build();
          }
    
         seleniumExtension.addBrowsers(firefox);
       }       
    }
    
    在测试中,我只需要做这样的事情

    class MyTest extends UiTest {
    
      @Test
      void my_one_logic_test_case(WebDriver webDriver) {
    
         webDriver.get(...)
         Assert(...)        
      }
    }
    
    请注意,参数的类型如何仅限于WebDriver

    示例3:我当前的解决方案

    abstract class UiTest {
    
       @RegisterExtension
       static SeleniumExtension seleniumExtension = new SeleniumExtension();     
    
       @BeforeAll
       static void setUpOnce() {
    
         // This check is not the problem discussed here
         boolean isRunningInCiEnvironment = ...
    
          if( isRunningInCiEnvironment ) {
            // This is doing the trick!
            seleniumExtension.getConfig().setSeleniumServerUrl("http://...");
          }
    
         seleniumExtension.addBrowsers( BrowserBuilder.firefox().build() );
       }       
    }
    

    具体测试现在可以按照“示例2”中的描述实施了。

    对于遇到相同问题的任何人,这是我丑陋的解决方法:1。在基类(这里:
    UiTest
    )中,我声明了一个字符串成员,其中包含Selenium网格的URL,并用
    @DriverUrl
    对其进行注释(这使测试在CI环境中通过)2。在本地执行测试时,我会对该注释进行注释,这会导致在本地机器上启动Firefox。不再需要“丑陋的解决方法”(请参见“示例3”)。您是否解决了问题2?是否每个测试类仍然需要有2个方法才能在2个浏览器中执行一个测试?是的,情况仍然如此……但请注意,这也有好处:比如有显式的测试结果。