如何为使用SpringBootTest和Junit-Jupiter并行执行的每个测试初始化@Autowired对象的单独



我使用SpringBootTest 3.0.5, Java 17, Selenium 4.8, Junit-Jupiter 5.9.2,并尝试并行运行测试。

我的Config类是:

@Component 
public class WebDriverLibrary {
@Bean
@ConditionalOnProperty(name = "default.browser", havingValue = "chrome")
public WebDriver getDriver() {
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
return new ChromeDriver(options);
} }

My TestCase is:

@SpringBootTest
@SpringJUnitConfig(WebDriverLibrary.class)
public class AppTestCase {
@Autowired
public WebDriver driver;

@Test
public void testYoutube() {
driver.get("https://www.youtube.com");
}
@Test
public void testGoogle() {
driver.get("https://www.google.com");
}
}

这里的问题是,WebDriver的同一个@Autowired实例由两个并行测试共享。因此,只启动一个浏览器会话,并依次加载YouTube.com和google.com的url。谁能让我知道如何确保一个单独的@Autowired WebDriver而不是创建每个测试(基本上每个线程),并确保两个单独的WebDriver驱动程序会话并行启动?

我建议您阅读更多关于Spring启动SimpletThreadscope的内容,但是您可以这样做SimeplThreadScope

创建一个WebdriverScope类,它的作用就像一个threadlocal,你用它来存储并行执行期间的Webdriver实例,即每个线程一个驱动程序,这样你只能访问为创建test的线程创建的驱动程序

public class WebdriverScope extends SimpleThreadScope {
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Object o = super.get(name, objectFactory);
SessionId sessionId = ((RemoteWebDriver)o).getSessionId();
if(Objects.isNull(sessionId)){
super.remove(name);
o = super.get(name, objectFactory);
}
return o;
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
}
}

创建一个配置类,它会创建WebdriverScopePostProcessor bean

@Configuration
public class WebdriverScopeConfig {
@Bean
public static BeanFactoryPostProcessor beanFactoryPostProcessor(){
return new WebdriverScopePostProcessor();
}
}

创建WebdriverScopePostProcessor

public class WebdriverScopePostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.registerScope("webdriverscope", new WebdriverScope());
}
}`

然后为你的webdriver实例创建一个Configuration类,如下所示

@Configuration
public class DriverConfig {
@WebdriverScopeBean
public WebDriver chromeDriver() {
System.setProperty("webdriver.chrome.driver", "path");
return new ChromeDriver();
}
}

现在当你做

@Autowired
WebDriver driver;

你应该得到每个线程一个唯一的实例

最新更新