@SuppressWarnings("unchecked")
public T get() {
try {
isLoaded();
return (T) this;
} catch (Error e) {
load();
}
isLoaded();
return (T) this;
}
即违反了设计原则“ “仅将异常用于特殊用途”,这里,异常是规则,并且
isLoaded
至少在第一次调用该方法时,预计会引发异常。此外,此
LoadableComponent
是抽象类,这意味着我不能拥有从父组件继承的子组件。这一切对我来说都是错误的。我只是为每个页面对象实现一个
get()
方法,该方法将根据需要根据Selenium驱动程序的状态加载页面,而无需捕获异常。我把所有这些弄错了吗?#1 楼
当您问“我把所有这些弄错了吗?”时,我不知道您指的是哪个“这个”。根据Wiki页面,isLoaded方法应使用JUnit断言来检查是否实际加载了页面。 JUnit断言抛出错误而不是异常,以表示出现问题。LoadableComponent可以将isLoaded重构为两种方法:一种(称为isLoadedBoolean)返回指示页面是否已加载的布尔值,另一种(称为assertLoaded)使用JUnit断言。当然,如果检查页面是否已加载需要评估多个条件,则assertLoaded指示哪个条件失败可能很有价值。懒惰的人可能会这样做:
protected void assertLoaded() {
assertTrue(condition1,"condition 1 failed");
assertTrue(condition2,"condition 2 failed");
}
protected boolean isLoadedBoolean() {
try {
assertLoaded();
return true;
}
catch (Error e) {
return false;
}
其他人会认为设计太怪异了,而是这样做:
protected void assertLoaded() {
assertTrue(condition1,"condition 1 failed");
assertTrue(condition2,"condition 2 failed");
}
protected boolean isLoadedBoolean() {
return condition1 && condition2;
}
当然,如果检查页面是否加载的标准发生了变化(当然,因为这是对Web界面的测试,所以它也会发生变化),这两种方法都需要更新。因此,以这种方式编写代码的开发人员将以怪异的方式换取维护错误。
我想另一种选择是这样的:
public class PageLoadCheckFailure {
public String reason;
... other interesting data ...
public PageLoadCheckFailure(reason, ... other interesting data ...) {
this.reason = reason;
etc.
}
public String getReason() {
return reason;
}
... getters for other interesting data ...
}
protected PageLoadCheckFailure checkWhetherLoaded() {
if (!condition1) {
return new PageLoadCheckFailure("condition 1 failed", ... other interesting data...);
}
if (!condition2) {
return new PageLoadCheckFailure("condition 1 failed", ... other interesting data...);
}
return nil;
}
protected void assertLoaded() {
PageLoadCheckFailure result = checkWhetherLoaded();
if (result != nil) {
Assert.fail(result.toString());
}
}
protected boolean isLoadedBoolean() {
return checkWhetherLoaded() == nil;
}
但是与Selenium设计相比,这肯定是很多工作,特别是因为毕竟这只是测试代码。
评论
非常感谢您的回答。恐怕我没有对此考虑足够长的时间,而您的推理正是我所缺少的。我不了解的两件事是:1-为什么使用错误来控制流程? (我写了“ exceptions”,意思是必须捕获的Throwables);和2-为什么LoadableComponent是必须扩展的类,而不是接口?
–阿尔贝托
2011年11月28日在13:31
您已经回答了我的第一个问题,因为在阅读您的回答后,我注意到我从他们的文档中遗漏的重要部分:“通过使用这些断言,可以为类的用户提供清晰的信息,这些信息可以用于调试测试。”就是说,与提供大量信息的assertTrues列表相比,您的checkWheterLoaded方法过于繁琐。我应该已经阅读了stackoverflow中的“真的是异常错误的例外吗”问题!
–阿尔贝托
2011年11月28日在13:31
我还是不太喜欢第二期。我正在使用PageObjects层次结构来建模UI的嵌套组件。以他们的例子为例。对我来说,EditIssue组件还在其API中提供了signOut()方法是有意义的(它与SecuredPage组件有关)。但是,LoadableComponent实现非常简单,可以直接包含在我的根组件中,因此现在也适合我。
–阿尔贝托
2011-11-28 13:31