考虑如下属性文件prop.properties,为上述代码例子中的UI元素指定了 “别名”:
admin.username = loginForm:tbUsername |
其中定位信息还是指向页面的HTML对象,但我们在测试脚本和UI元素之间引入一层抽象层。测试类从属性文件中读取定位信息,从而实现UI映射。
页面对象设计模式
页面对象设计模式,可以提高自动化测试脚本的维护性、减少代码重复,越发流行。页面对象是一个面向对象的类,作为待测应用对外提供的接口。测试代码在需要和UI页面交互时,使用此页面对象类的方法。这样做的好处是,如果UI页面发生变化,测试代码本身并不需要改变,只需要改变相应的页面对象的代码。为适应新UI页面的所有更改,都位于一个地方。
页面对象设计模式具有以下优点:
1、测试代码和页面相关的代码,比如页面元素定位信息(若使用UI映射,也包括定位信息的应用),页面布局等,完全分离;
2、可以维护单一的储存库来存储页面提供的服务或操作,而不是把他们分散在测试代码中。
在这两种情况下,这使得任何由于UI界面变化导致的修改,都可以在一个地方进行修改。关于该技术的更多有用信息,可以在众多的博客上找到。我们也鼓励读者去阅读更多。 许多人写这样的设计模式和超出本用户指南的范围,可以提供有用的提示。不过,为了让你开始,我们将举例说明页面对象的一个简单的例子。
首先,考虑一个例子,典型的自动化测试,不使用页面对象。
/*** * Tests login feature */ public class Login { public void testLogin() { selenium.type("inputBox", "testUser"); selenium.type("password", "my supersecret password"); selenium.click("sign-in"); selenium.waitForPageToLoad("PageWaitPeriod"); Assert.assertTrue(selenium.isElementPresent("compose button"), "Login was unsuccessful"); } } |
这种方法有两个问题。
1、没有分离测试代码和待测应用的定位器(在这个例子中是ID);两者都交织在一个单一方法中。如果待测应用UI改变了它的标识,布局,或登录输入和处理的方式变化,测试代码本身必须改变。
2、ID定位信息分散在多个测试代码中,所有的测试不得不使用此登录页面。
使用页面对象技术,上述测试代码可以按如下方式重写,为登录页面的页面对象例子:
/** * Page Object encapsulates the Sign-in page. */ public class SignInPage { private Selenium selenium; public SignInPage(Selenium selenium) { this.selenium = selenium; if(!selenium.getTitle().equals("Sign in page")) { throw new IllegalStateException("This is not sign in page, current page is: " +selenium.getLocation()); } } /** * Login as valid user * * @param userName * @param password * @return HomePage object */ public HomePage loginValidUser(String userName, String password) { selenium.type("usernamefield", userName); selenium.type("passwordfield", password); selenium.click("sign-in"); selenium.waitForPageToLoad("waitPeriod"); return new HomePage(selenium); } } |