深圳网站制作哪家好薇,专业做网站平台,大学毕业网站设计代做,东风多利卡道路清障车做网站PO的思想最早是2013年由IT大佬Martin Flower提出的#xff1a;https://martinfowler.com/bliki/PageObject.html 没错#xff0c;就是他 — 没错#xff0c;就是他 —
在他的文章里有这样一张经典样图,图片中展示了测试代码中直接操作HTML元素和使用PO模式将page对象封装成…PO的思想最早是2013年由IT大佬Martin Flower提出的https://martinfowler.com/bliki/PageObject.html 没错就是他 — 没错就是他 —
在他的文章里有这样一张经典样图,图片中展示了测试代码中直接操作HTML元素和使用PO模式将page对象封装成一个HTML页面通过特定方法来操作元素的对比如下图
我们知道PO主要就是应用在UI自动化测试上(Web端和App端均适用)因此2015年Selenium官方给出了PO的设计原则说明https://github.com/SeleniumHQ/selenium/wiki/PageObjects
对官方的原则进行解读我们可以得到如下的信息 用公共方法代表UI所提供的功能 如企业微信的通讯录页面其中有“添加成员”、“批量导入导出”、“设置所在部门”、“删除”等功能这些功能都可以封装成通讯录这个UI界面所提供的方法当然部分数据较多或者较为复杂复用性也比较高的话例如添加成员也可以单独抽离出来做一个page。 方法应该返回其他的PageObject或者返回用于断言的数据 我们既然以页面为对象进行业务操作那么一个方法结束后必然要有返回值 要么返回一个页面这个页面可以是当前页(因为可能还要在这个页面进行其他操作)可以是其他页面(我们操作某个方法后很可能会跳转到另一个页面进行下一步操作) 要么返回需要断言的值测试用例总归有预期结果的对吧那么最后肯定要有方法返回一个值用来给我们做断言来判断用例执行是否符合预期结果。
不要返回null或者写一个void没有返回值的方法这样的方法没有意义既不能为下一步操作创造条件也不能为用例的断言提供结果。 同样的行为不同的结果可以建模为不同的方法 这个就比较好理解了拿最简答的登录场景来说 同样的行为 无论输入的账号密码正确与否都是按照输入账号密码点击登录这样的行为去操作 不同的结果账号密码错误和正确得到的登录响应一定是不同的。 建模为不同的方法对于登录页来说就可以根据登录信息正确与否建模出正确登录、账号错误登录、密码错误登录等方法了 不要在方法内加断言 对一个测试用例的执行结果进行判断一定是在测试用例里的方法只是提供给我们业务上需要的操作因此断言不要加在方法里而是应该写在用例里 不要暴露页面内部的元素给外部 我们使用PO的目的就是为了提高测试用例的可读性和可维护性只要我们人能操作的事通过page对象封装好的客户端都可以做到就类似于一个接口我们只关心请求操作后接口的返回值是什么而不需要关心接口内部到底是如何工作的 不需要建模UI内的所有元素 一个UI页面可能会包含很多的元素但是我们只要根据实际业务需求将我们用的上的元素进行建模即可 以页面为单位独立建模 隐藏实现细节 本质是面向接口编程 page 完成对页面的封装 driver 完成对Web、Android、Ios、接口的驱动 testcase 调用各类page完成业务流程并进行断言 data 配置文件和数据驱动 utils 其他便捷的功能封装(可选)
1.3.3 PO的优点
减少例如find click这类样板代码的重复测试用例的可读性提高只关心业务流程测试用例可维护性提高UI页面频繁被修改了我们只需要去修改对应PO即可用例无需修改
说的再多不如动手下面以QQ邮箱登录为例演示PO模式在UI自动化中的应用
2.1 登录场景预设 登录页面提供login功能——LoginPage类login方法 登录页面内有多少元素并不关心隐藏内部细节 登录成功和失败会返回不同的页面 loginSuccess——MainPage(进入主页面) loginFail——LoginPage(停留在登录页) 通过方法返回值判断登录是否符合预期
1创建基础类BasePage初始化driver并封装常用的元素操作方法如click、sendKeys等
package poshow.page;import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;import java.util.List;public class BasePage {public static WebDriver driver;public WebElement findElement(By by){return driver.findElement(by);}public ListWebElement finElements(By by){return driver.findElements(by);}public void click(By by){findElement(by).click();}public void sendKeys(By by,String context){findElement(by).sendKeys(context);}public String getText(By by){return findElement(by).getText();}
}
2创建MainPage类用于登录成功后的返回页面由于这里并未演示登录后的操作所以类中无具体方法实现仅作为loginSuccess后的返回对象
package poshow.page;public class MainPage extends BasePage{
}
3创建LoginPage类继承BasePage类。定义所需元素定位方式并根据操作动作输入账号、输入密码、点击登录将其封装成具体的业务操作方法例如登录成功用户名错误登录、密码错误登录等输入的测试数据作为方法的入参传入(username,password)
package poshow.page;import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;public class LoginPage extends BasePage{//定位器By usernameInput By.name(u); //获取用户名输入框By passwordInput By.id(p); //获取密码输入框By submitLogin By.cssSelector(#login_button); //获取登录按钮By ErrM By.id(err_m); //获取错误提示信息public void openUrl(){String url https://mail.qq.com/;driver new ChromeDriver();driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);driver.get(url);driver.manage().window().maximize();driver.switchTo().frame(login_frame);}private void sleepWait(){try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}//业务方法/*登录方法*/private void login(String username,String password){findElement(usernameInput).clear();findElement(passwordInput).clear();sendKeys(usernameInput,username);sendKeys(passwordInput,password);click(submitLogin);}/*成功登录*/public MainPage loginSuccess(String username,String password){login(username,password);return new MainPage();}/*密码错误登录message:你输入的帐号或密码不正确请重新输入。*/public String loginWithErrPassword(String username,String password ){login(username,password);sleepWait();return getText(ErrM);}/*账号为空登录你还没有输入帐号*/public String loginWithErrUsername(String username,String password){login(username,password);sleepWait();return getText(ErrM);}/*密码为空登录*/public String loginWithoutPassword(String username,String password){login(username,password);sleepWait();return getText(ErrM);}
}
4最后创建LoginTest测试类编写测试用例用例的编写更接近于人的行为人想要登录邮箱只需要依靠用户名和密码完成登录的行为即可无需关注具体的输入框和登录按钮是如何定位如何进行输入点击的。并在用例中加入断言进行判断。
package poshow.testcase;import org.junit.jupiter.api.*;
import poshow.page.LoginPage;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LoginTest {LoginPage loginPage new LoginPage();BeforeAllstatic void openUrl(){new LoginPage().openUrl();}TestDisplayName(密码错误登录)Order(1)void loginWithErrPassword(){String username 376057520;String password 123456;String expectedErrM 你输入的帐号或密码不正确请重新输入。;String errM loginPage.loginWithErrPassword(username, password);assertThat(errM,equalTo(expectedErrM));}TestDisplayName(账号错误登录)Order(2)void loginWithErrUsername(){String username 111;String password 123456;String expectedErrM 请输入正确的帐号;String errM loginPage.loginWithErrUsername(username, password);assertThat(errM,equalTo(expectedErrM));}TestDisplayName(空密码登录)Order(3)void loginWithoutPassword(){String username 376057520;String password ;String expectedErrM 你还没有输入密码;String errM loginPage.loginWithoutPassword(username, password);assertThat(errM,equalTo(expectedErrM));}TestDisplayName(正确登录)Order(4)void logSuccess(){String username 376057520;String password xxx;loginPage.loginSuccess(username,password);}}5整体结构展示
case尽量保持独立suite体系管理用例的顺序不要把大量的业务校验逻辑放到UI自动化测试里 UI主要校验的是用户交付操作流程样式、数据、兼容性。与接口测试合理的分工 #### 3.2 补充说明 以上仅仅是为了演示PO而举的一个简单的demo实际上还有很大的优化空间常用元素操作方法可以进一步封装的更完善可封装常用的操作util类例如滑动特定元素的等待采用显示等待登录用例可以利用参数化来以数据驱动的方式完成使用例代码更简洁易懂PO代码和testcase代码可以分开test下只放case代码
最后感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走 这些资料对于【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴上万个测试工程师们走过最艰难的路程希望也能帮助到你
文章转载自: http://www.morning.fpryg.cn.gov.cn.fpryg.cn http://www.morning.mbmh.cn.gov.cn.mbmh.cn http://www.morning.stcds.cn.gov.cn.stcds.cn http://www.morning.frzdt.cn.gov.cn.frzdt.cn http://www.morning.ctfwl.cn.gov.cn.ctfwl.cn http://www.morning.zqcsj.cn.gov.cn.zqcsj.cn http://www.morning.kfsfm.cn.gov.cn.kfsfm.cn http://www.morning.qjldz.cn.gov.cn.qjldz.cn http://www.morning.whpsl.cn.gov.cn.whpsl.cn http://www.morning.hnrls.cn.gov.cn.hnrls.cn http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn http://www.morning.mqldj.cn.gov.cn.mqldj.cn http://www.morning.qbjrf.cn.gov.cn.qbjrf.cn http://www.morning.lbgsh.cn.gov.cn.lbgsh.cn http://www.morning.kbyp.cn.gov.cn.kbyp.cn http://www.morning.crqbt.cn.gov.cn.crqbt.cn http://www.morning.drspc.cn.gov.cn.drspc.cn http://www.morning.pphgl.cn.gov.cn.pphgl.cn http://www.morning.shsh1688.com.gov.cn.shsh1688.com http://www.morning.jmmz.cn.gov.cn.jmmz.cn http://www.morning.cpkcq.cn.gov.cn.cpkcq.cn http://www.morning.dwrjj.cn.gov.cn.dwrjj.cn http://www.morning.trqsm.cn.gov.cn.trqsm.cn http://www.morning.rnhh.cn.gov.cn.rnhh.cn http://www.morning.pqsys.cn.gov.cn.pqsys.cn http://www.morning.kxwsn.cn.gov.cn.kxwsn.cn http://www.morning.njftk.cn.gov.cn.njftk.cn http://www.morning.fxjnn.cn.gov.cn.fxjnn.cn http://www.morning.crsnb.cn.gov.cn.crsnb.cn http://www.morning.wdwfm.cn.gov.cn.wdwfm.cn http://www.morning.ypqwm.cn.gov.cn.ypqwm.cn http://www.morning.rfgkf.cn.gov.cn.rfgkf.cn http://www.morning.kqglp.cn.gov.cn.kqglp.cn http://www.morning.xkhxl.cn.gov.cn.xkhxl.cn http://www.morning.mbfj.cn.gov.cn.mbfj.cn http://www.morning.wgrl.cn.gov.cn.wgrl.cn http://www.morning.smj78.cn.gov.cn.smj78.cn http://www.morning.qlkzl.cn.gov.cn.qlkzl.cn http://www.morning.qsfys.cn.gov.cn.qsfys.cn http://www.morning.msbpb.cn.gov.cn.msbpb.cn http://www.morning.jnzfs.cn.gov.cn.jnzfs.cn http://www.morning.dcdhj.cn.gov.cn.dcdhj.cn http://www.morning.smdiaosu.com.gov.cn.smdiaosu.com http://www.morning.tqrxm.cn.gov.cn.tqrxm.cn http://www.morning.pbtrx.cn.gov.cn.pbtrx.cn http://www.morning.pcgmw.cn.gov.cn.pcgmw.cn http://www.morning.wlgpz.cn.gov.cn.wlgpz.cn http://www.morning.brlcj.cn.gov.cn.brlcj.cn http://www.morning.flzqq.cn.gov.cn.flzqq.cn http://www.morning.npmx.cn.gov.cn.npmx.cn http://www.morning.tkflb.cn.gov.cn.tkflb.cn http://www.morning.rmtmk.cn.gov.cn.rmtmk.cn http://www.morning.nrxsl.cn.gov.cn.nrxsl.cn http://www.morning.zkgpg.cn.gov.cn.zkgpg.cn http://www.morning.lqgtx.cn.gov.cn.lqgtx.cn http://www.morning.wxckm.cn.gov.cn.wxckm.cn http://www.morning.lpqgq.cn.gov.cn.lpqgq.cn http://www.morning.qzdxy.cn.gov.cn.qzdxy.cn http://www.morning.gqksd.cn.gov.cn.gqksd.cn http://www.morning.zgdnd.cn.gov.cn.zgdnd.cn http://www.morning.llyqm.cn.gov.cn.llyqm.cn http://www.morning.nckzt.cn.gov.cn.nckzt.cn http://www.morning.yrdt.cn.gov.cn.yrdt.cn http://www.morning.rjmg.cn.gov.cn.rjmg.cn http://www.morning.krtcjc.cn.gov.cn.krtcjc.cn http://www.morning.xdpjf.cn.gov.cn.xdpjf.cn http://www.morning.ptwqf.cn.gov.cn.ptwqf.cn http://www.morning.dhbyj.cn.gov.cn.dhbyj.cn http://www.morning.fllfc.cn.gov.cn.fllfc.cn http://www.morning.xhkgl.cn.gov.cn.xhkgl.cn http://www.morning.bgqr.cn.gov.cn.bgqr.cn http://www.morning.ypzsk.cn.gov.cn.ypzsk.cn http://www.morning.fgsct.cn.gov.cn.fgsct.cn http://www.morning.rkxk.cn.gov.cn.rkxk.cn http://www.morning.eronghe.com.gov.cn.eronghe.com http://www.morning.mtsgx.cn.gov.cn.mtsgx.cn http://www.morning.tmtrl.cn.gov.cn.tmtrl.cn http://www.morning.xflwq.cn.gov.cn.xflwq.cn http://www.morning.tnwwl.cn.gov.cn.tnwwl.cn http://www.morning.lwlnw.cn.gov.cn.lwlnw.cn