使用Java我正在为selenium测试实现一个Page Factory对象,该对象获取页面对象的名称并通过反射实例化它以供Cucumber步骤定义使用。我遇到的问题是下面的代码找不到声明的类。包含此代码的对象PageFactory
和页面对象LoginPage
都位于名为pages
的包中。
/**
* This method take a string containing a Page Object class name (case-sensitive) and returns an instance of the Page Object.
* This allows us to operate on pages without knowing they exist when we write step definitions.
* @param choice String
* @return Page Object cast as a Page
*/
public static Page getPage(String choice) {
Page entity = null;
try {
entity = (Page) Class.forName(choice).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return entity;
}
我收到一个堆栈跟踪,其中java.lang.ClassNotFoundException: LoginPage
作为错误的开头。如果我将实体创建更改为以下代码,那么它可以正常工作。
private static String packageName = "pages";
entity = (Page) Class.forName(packageName + "." + choice).newInstance();
问题在于我想组织我的页面。当我创建pages.mywebsite
并在其中放置LoginPage
时,PageFactory
无法知道在哪里找到该文件。
撇开我可能有两个名称空间pages.mywebsite
和pages.myotherwebsite
并且都有LoginPage
对象的问题,如何在不声明确切包的情况下找到我想要的文件,以及只是说"看看这个包和下面的课程"?
答案 0 :(得分:3)
您可以使用System.getProperty("java.class.path")
获取类路径,将其拆分为File.pathSeparator
,然后使用FileVisitor扫描结果。
答案 1 :(得分:0)
这就是我解决问题的方式。我将反射移至findPageInPackage
方法中,并递归调用该方法以搜索目录。
/**
* Returns a page object if it exists in the package searched.
* @param pageName String the name of the page object class to instantiate
* @param packageName String the name of the package to search
* @return Page the page object if it exists, otherwise null
*/
private static Page findPageInPackage(String pageName, String packageName) {
Page page = null;
try {
page = (Page) Class.forName(packageName + "." + pageName).newInstance();
} catch (InstantiationException e) {
log.trace("{}.{} Page Object creation failed.", packageName, pageName);
log.trace("java.lang.InstantiationException: {}", e.getMessage());
} catch (IllegalAccessException e) {
log.trace("{}.{} Page Object creation failed.", packageName, pageName);
log.trace("java.lang.IllegalAccessException: {}", e.getMessage());
} catch (ClassNotFoundException e) {
log.trace("{}.{} Page Object creation failed.", packageName, pageName);
log.trace("java.lang.ClassNotFoundException: {}", e.getMessage());
}
return page;
}
/**
* Returns the Page Object for the page name. This allows us to operate on pages
* without knowing they exist when we write step definitions.
* <p>
* Searches any optional page object packages set with the pageObjectPackages system property, and
* then searches the defaultPackageName value.
* <p>
* <b>Example:</b>
* <p>
* <code>System.setProperty("pageObjectPackages", "pages.SharedComponent,pages.UserAdminTool");</code>
*
* @param pageName String the name of the page in
* <a href="https://en.wikipedia.org/wiki/Camel_case">Pascal
* case</a>
* @return Page the specific page object cast as a generic page object
* @throws PageNotFoundException if page could not be built or retrieved.
* @throws ConfigurationNotFoundException if the value is not found in the configuration file
*/
public static Page buildOrRetrievePage(String pageName) throws PageNotFoundException, ConfigurationNotFoundException {
Page page = pages.get(pageName);
final String errorMessage = "The page you want to test could not be built. At least one Page object package is required to run a test. Please add a pageObjectPackages property to your conf/sentinel.yml configuration file and try again.";
if (page != null) {
return page;
} else {
if (pageObjectPackagesList == null) {
pageObjectPackagesList = ConfigurationManager.getPageObjectPackageList();
if(pageObjectPackagesList == null) {
throw new PageNotFoundException(errorMessage);
}
}
for (String pageObjectPackage : pageObjectPackagesList) {
log.trace("pageObjectPackage: " + pageObjectPackage);
page = findPageInPackage(pageName, pageObjectPackage);
if (page != null) {
break; // If we have a page object, stop searching.
}
}
}
if(page == null) {
throw new PageNotFoundException(errorMessage);
}
pages.put(pageName, page);
return page;
}