下面的工厂类用于获取执行驱动程序
public class DriverFactory {
//holds the device config
public static Map<String, String> devConfig = new ConcurrentHashMap<>();
//other lines of code follow
}
此配置从外部数据源加载到junit类中,如下所示:
@RunWith(ConcurrentTestRunner.class)
public class MyTestRunner{
static final int THREAD_COUNT = 1;
@ThreadCount(THREAD_COUNT) @Override @Test
public void run(){
// Devices class returns config for the device
DriverFactory.devConfig = Devices.getConfig()
//other lines of code to perform execution
}
}
如果在执行过程中其他类中需要设备配置,则可以通过以下方式访问它:
public class MobileActions{
public void swipe(){
String pf = DriverFactory.devConfig.get("Platform");
//other lines of code
}
}
这种方法(具有devConfig为静态)工作正常,只有一个线程。现在,为了支持跨设备并行执行,如果将线程数更改为2,则devConfig将始终具有由第二个线程设置的值。
为了避免此问题,如果将devConfig设为非静态,则必须在所有其他类中(例如,在上述MobileActions类中)注入此变量。 有没有一种方法可以使该变量保持静态,但在多线程执行期间仍然可以工作(每个线程应处理自己的devConfig副本)。我们还尝试将此变量设置为ThreadLocal <>,但这也无济于事。
非常感谢您的帮助! 谢谢
答案 0 :(得分:1)
将DriverFactory中的devConfig设为私有。提供它的获取器和设置器。 如果您需要特定于线程,请将其设为本地线程。
public class DriverFactory {
// holds the device config
private static final ThreadLocal<Map<String, String>> devConfig = ThreadLocal
.withInitial(ConcurrentHashMap::new);
public static String getDevConfig(String key) {
return this.devConfig.get().get(key);
}
public static void setDevConfig(Map<String, String> config) {
this.devConfig.get().putAll(config);
}
}
答案 1 :(得分:0)
您可以将devConfig包装到ConcurrentHashMap中:
public class DriverFactory {
//holds the device config
private static final String CONFIG_KEY = "config_key";
private static final ConcurrentHashMap<String, Map<String, String>> devConfig = new ConcurrentHashMap<>();
public static Map<String, String> setDevConfig(Map<String, String> devConfig) {
return DriverFactory.devConfig.putIfAbsent(CONFIG_KEY, devConfig);
}
public static Map<String, String> getDevConfig() {
return DriverFactory.devConfig.get(CONFIG_KEY);
}
//other lines of code follow
}
@RunWith(ConcurrentTestRunner.class)
public class MyTestRunner{
static final int THREAD_COUNT = 1;
@ThreadCount(THREAD_COUNT) @Override @Test
public void run(){
// Devices class returns config for the device
DriverFactory.setDevConfig(Devices.getConfig())
//other lines of code to perform execution
}
}
public class MobileActions{
public void swipe(){
String pf = DriverFactory.getDevConfig().get("Platform");
//other lines of code
}
}
但是,如果您想一次执行Devices.getConfig()
,则应该尝试java.util.concurrent.ConcurrentHashMap#computeIfAbsent
或自定义锁定。像这样:
public static Map<String, String> getDevConfig() {
return DriverFactory.devConfig
.computeIfAbsent(CONFIG_KEY, s -> Devices.getConfig());
}
答案 2 :(得分:0)
最后找到了使用此链接的方法:
https://dmitrykrivenko.blogspot.com/2016/07/threadlocal-and-inheritablethreadlocal.html
使用InheritableThreadLocal而不是ThreadLocal。这样,我现在也可以访问子线程中的数据。
public class DriverFactory {
private static final ThreadLocal<Map<String, String>> driverData = new InheritableThreadLocal<>();
public static String getDriverData(String key){
return driverData.get().get(key);
}
public static void setDriverData(Map<String, String> driver){
driverData.set(driver);
}
}