想动态使用 Enum 文件名来获取常量
Want to use Enum file name dynamically to fetch constants
我有一个包含键值对的配置文件
language = "IN"
我有多个页面对象枚举文件,名称为
PageObject_US,PageObject_UK,PageObject_IN
每个页面对象枚举文件都有可以访问的常量,例如
PageObjects_US.String.lable
但我想要实现的是一种创建如下内容的方法
- 从配置文件中获取参数并将其存储在字符串中
像 String language = "IN"
- 然后使用“PageObjects_”+语言连接得到(PageObjects_IN)
- 以便返回值可用于从 PageObjects_IN.String.label.
中获取常量
代码块如下:
if(!ENV.equalsIgnoreCase("development") && VALIDATION.equalsIgnoreCase("yes")) {
Elements.ByTitle(webDriver,PageObjects_IN.GREAT.label);
Elements.ByID(webDriver, PageObjects_IN.COUNTER.label);
}
在上面我想在 运行 时使用枚举文件 PageObjects_IN 因为我有很多枚举文件
下面是枚举
public enum PageObjects_IN {
// Text
GREAT("great"),
COUNTER("counter");
public final String lable;
PageObjects_IN(final String lable) {
this.lable = lable;
}
}
这是可能的(使用反射)但强烈不推荐,因为它会降低 Java 语言构造的效率。
不推荐的方式
假设您有一个包裹click.webelement.cucumber.po
,您将其存放在
public enum PO_EN {
GREAT("great_en"),
COUNTER("counter_en");
public final String label;
PO_EN(String label){
this.label = label;
}
}
和
public enum PO_IN {
GREAT("great_in"),
COUNTER("counter_in");
public final String label;
PO_IN(String label){
this.label = label;
}
}
然后要获取一个值,您可以这样做:
String lang = "EN";
// Take class
Class clazz = Class.forName("click.webelement.cucumber.po.PO_" + lang);
// Find an object that represent enum constant
Object val = Arrays
.stream(clazz.getEnumConstants()).filter(o -> "GREAT".equals(o.toString()))
.findAny()
.get();
// Take field value for that object
Field f = clazz.getField("label");
System.out.println(f.get(val));
这是 error-prone 方法,您不会从编译阶段受益。
推荐方法 - 1
而不是 enum
使用 类.
public abstract class PO {
public abstract String great();
public abstract String counter();
}
和
public class PO_EN extends PO{
@Override
public String great() {
return "great_en";
}
@Override
public String counter() {
return "counter_en";
}
}
和
public class PO_IN extends PO{
@Override
public String great() {
return "great_in";
}
@Override
public String counter() {
return "counter_in";
}
}
所以你的测试会简单得多
String lang = "EN";
Class clazz = Class.forName("click.webelement.cucumber.po.PO_" + lang);
PO val = (PO) clazz.getDeclaredConstructor().newInstance();
System.out.println(val.great());
推荐方法 - 2
您可以将 PageFactory 工具用于您的页面对象,并使用 this lib 来参数化您的定位器,例如(如果您使用 test ng):
@DataProvider(name = "languages")
Object[][] dataProvider(){
return new Object[][]{
{"en", "great_en", "counter_en"},
{"in", "great_in", "counter_in"}
};
}
@Test(dataProvider = "languages")
public void testPage(String language, String great, String counter){
DefaultParameterProvider
.properties
.set(Map.of("p.great", great, "p.counter", counter));
MyPage myPage = new MyPage(driver);
...
}
你的页面应该是这样的:
public class MyPage extends PageObjectParameterized {
@FindByParameterized(xpath = "//button[@name='{wec:p.great}']")
WebElement great;
@FindByParameterized(xpath = "//label[text()='{wec:p.counter}']")
WebElement counter;
@FindBy(xpath = "//input")
WebElement input;
public MyPage(SearchContext searchContext) {
super(searchContext);
}
}
我有一个包含键值对的配置文件
language = "IN"
我有多个页面对象枚举文件,名称为
PageObject_US,PageObject_UK,PageObject_IN
每个页面对象枚举文件都有可以访问的常量,例如
PageObjects_US.String.lable
但我想要实现的是一种创建如下内容的方法
- 从配置文件中获取参数并将其存储在字符串中 像 String language = "IN"
- 然后使用“PageObjects_”+语言连接得到(PageObjects_IN)
- 以便返回值可用于从 PageObjects_IN.String.label. 中获取常量
代码块如下:
if(!ENV.equalsIgnoreCase("development") && VALIDATION.equalsIgnoreCase("yes")) {
Elements.ByTitle(webDriver,PageObjects_IN.GREAT.label);
Elements.ByID(webDriver, PageObjects_IN.COUNTER.label);
}
在上面我想在 运行 时使用枚举文件 PageObjects_IN 因为我有很多枚举文件
下面是枚举
public enum PageObjects_IN {
// Text
GREAT("great"),
COUNTER("counter");
public final String lable;
PageObjects_IN(final String lable) {
this.lable = lable;
}
}
这是可能的(使用反射)但强烈不推荐,因为它会降低 Java 语言构造的效率。
不推荐的方式
假设您有一个包裹click.webelement.cucumber.po
,您将其存放在
public enum PO_EN {
GREAT("great_en"),
COUNTER("counter_en");
public final String label;
PO_EN(String label){
this.label = label;
}
}
和
public enum PO_IN {
GREAT("great_in"),
COUNTER("counter_in");
public final String label;
PO_IN(String label){
this.label = label;
}
}
然后要获取一个值,您可以这样做:
String lang = "EN";
// Take class
Class clazz = Class.forName("click.webelement.cucumber.po.PO_" + lang);
// Find an object that represent enum constant
Object val = Arrays
.stream(clazz.getEnumConstants()).filter(o -> "GREAT".equals(o.toString()))
.findAny()
.get();
// Take field value for that object
Field f = clazz.getField("label");
System.out.println(f.get(val));
这是 error-prone 方法,您不会从编译阶段受益。
推荐方法 - 1
而不是 enum
使用 类.
public abstract class PO {
public abstract String great();
public abstract String counter();
}
和
public class PO_EN extends PO{
@Override
public String great() {
return "great_en";
}
@Override
public String counter() {
return "counter_en";
}
}
和
public class PO_IN extends PO{
@Override
public String great() {
return "great_in";
}
@Override
public String counter() {
return "counter_in";
}
}
所以你的测试会简单得多
String lang = "EN";
Class clazz = Class.forName("click.webelement.cucumber.po.PO_" + lang);
PO val = (PO) clazz.getDeclaredConstructor().newInstance();
System.out.println(val.great());
推荐方法 - 2
您可以将 PageFactory 工具用于您的页面对象,并使用 this lib 来参数化您的定位器,例如(如果您使用 test ng):
@DataProvider(name = "languages")
Object[][] dataProvider(){
return new Object[][]{
{"en", "great_en", "counter_en"},
{"in", "great_in", "counter_in"}
};
}
@Test(dataProvider = "languages")
public void testPage(String language, String great, String counter){
DefaultParameterProvider
.properties
.set(Map.of("p.great", great, "p.counter", counter));
MyPage myPage = new MyPage(driver);
...
}
你的页面应该是这样的:
public class MyPage extends PageObjectParameterized {
@FindByParameterized(xpath = "//button[@name='{wec:p.great}']")
WebElement great;
@FindByParameterized(xpath = "//label[text()='{wec:p.counter}']")
WebElement counter;
@FindBy(xpath = "//input")
WebElement input;
public MyPage(SearchContext searchContext) {
super(searchContext);
}
}