测试数据
测试地址
http://120.78.128.25:8765/
投资人
13323234545
lemon123456
借款人
13323234444
lemonbest
后台地址
http://120.78.128.25:8765/Admin/Index/login.html
lemon7
lemonbest
Page Object
PO简介
https://www.selenium.dev/documentation/en/guidelines_and_recommendations/page_object_models/
Page Object 是 Selenium 自动化测试项目开发实践的最佳设计模式之一,Page Object 的主要体现于对界面交互细节的封装,这样可以使测试案例更关注与业务而非界面细节,提高测试案例的可读性。
Page Object 设计模式的优点如下:
- 减少代码的重复;
- 提高测试用例的可读性;
- 提高测试用例的可维护性,特别是针对 UI 频繁变化的项目;
Paget Object 使用注意:
- public方法代表Page提供的功能
- 尽量不要暴露Page的内部细节
- 不要assertion
- 方法可以返回其他Page Objects
- Page Objects不用代表整个页面,可以是任意一个部分
- 一样的操作,不同的结果应该分开(正确登录,错误登录)
使用po是对页面进行抽象或者说建模的过程,需要把页面当作一个对象。
面向对象编程语言中,进行面向对象编程需要考虑以下两点:
- 对象的属性「全局变量」 == web页面的元素「定位方法,定位值」
- 对象的行为「方法」 == web页面的元素的操作
编写页面操作基类
package com.zhongxin.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class BasePage {
private WebDriver driver;
public BasePage(WebDriver driver) {
this.driver = driver;
}
/**
* 封装显式等待
*
* @param by 元素定位信息
* @return 元素对象
*/
public WebElement waitElementBisibility(By by) {
WebElement element = null;
try {
//5秒元素可见显式等待
WebDriverWait wait = new WebDriverWait(driver, 5);
element = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
return element;
} catch (Exception e) {
System.out.println("元素定位异常" + e.getMessage());
}
return null;
}
}
登陆页面封装
package com.zhongxin.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class LoginPage extends BasePage {
private WebDriver driver;
// phone元素定位信息
private By phoneBy = By.name("phone");
//password元素定位信息
private By passwordBy = By.name("password");
//登陆按钮元素定位信息
private By loginBtnBy = By.xpath("//button[@class='btn btn-special']");
//页面中央错误提示
private By centerErrorBy = By.className("layui-layer-content");
//页面手机红色错误提示
private By phoneformErrorBy = By.xpath("//input[@name='phone']//following-sibling::div");
//页面密码红色错误提示
private By passwordformErrorBy = By.xpath("//input[@name='password']//following-sibling::div");
public LoginPage(WebDriver driver) {
super(driver);
}
//对手机框进行输入
public void inputPhone(String phone) {
WebElement element = waitElementBisibility(phoneBy);
if (element != null) {
element.clear();
element.sendKeys(phone);
}
}
//对密码框进行输入
public void inputPassword(String password) {
WebElement element = waitElementBisibility(passwordBy);
if (element != null) {
element.clear();
element.sendKeys(password);
}
}
//点击登陆按钮
public void clickLoginBtn() {
WebElement element = waitElementBisibility(loginBtnBy);
if (element != null) {
element.click();
}
}
//获取页面中央错误提示文本
public String getCenterErrorText() {
WebElement element = waitElementBisibility(centerErrorBy);
if (element != null) {
return element.getText();
}
return "";
}
//获取页面手机红色错误提示
public String getPhoneFormErrorText() {
WebElement element = waitElementBisibility(phoneformErrorBy);
if (element != null) {
return element.getText();
}
return "";
}
//获取页面手机红色错误提示
public String getPasswordFormErrorText() {
WebElement element = waitElementBisibility(passwordformErrorBy);
if (element != null) {
return element.getText();
}
return "";
}
}
首页封装
package com.zhongxin.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
public class IndexPage extends BasePage {
private WebDriver driver;
//昵称
private By nicknameBy = By.xpath("//a[contains(text(),'我的帐户[自动化测试帐号1]')]");
public IndexPage(WebDriver driver) {
super(driver);
}
// 昵称是否可见
public boolean nicknameIsVisibility() {
WebElement element = waitElementBisibility(nicknameBy);
if (element != null) {
return element.isDisplayed();
}
return false;
}
}
测试代码
package com.zhongxin.cases;
import com.zhongxin.pages.IndexPage;
import com.zhongxin.pages.LoginPage;
import okio.Timeout;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LoginCase {
public WebDriver driver;
@BeforeClass
public void setUp() {
//打开浏览器
driver = open("chrome");
//访问登陆页面
driver.get("http://120.78.128.25:8765/Index/login.html");
}
@Test
public void testFailed01() throws InterruptedException {
LoginPage loginpage = new LoginPage(driver);
loginpage.inputPhone("13212312312");
loginpage.inputPassword("123123123");
loginpage.clickLoginBtn();
String actual = loginpage.getCenterErrorText();
String expected = "此账号没有经过授权,请联系管理员!";
Assert.assertEquals(actual, expected);
}
@Test
public void testFailed02() throws InterruptedException {
LoginPage loginpage = new LoginPage(driver);
loginpage.inputPhone("");
loginpage.inputPassword("123123123");
loginpage.clickLoginBtn();
String actual = loginpage.getPhoneFormErrorText();
String expected = "请输入手机号";
Assert.assertEquals(actual, expected);
}
@Test(dataProvider = "datas")
public void testFailed03(String phone, String password, String expected) throws InterruptedException {
LoginPage loginpage = new LoginPage(driver);
loginpage.inputPhone(phone);
loginpage.inputPassword(password);
loginpage.clickLoginBtn();
String actual = loginpage.getPhoneFormErrorText();
Assert.assertEquals(actual, expected);
}
@Test
public void testFailed04() throws InterruptedException {
LoginPage loginpage = new LoginPage(driver);
loginpage.inputPhone("15859019251");
loginpage.inputPassword("");
loginpage.clickLoginBtn();
String actual = loginpage.getPasswordFormErrorText();
Assert.assertEquals(actual, "请输入密码");
}
@Test
public void testFailed05() throws InterruptedException {
LoginPage loginpage = new LoginPage(driver);
loginpage.inputPhone("13323234545");
loginpage.inputPassword("123123123");
loginpage.clickLoginBtn();
String actual = loginpage.getCenterErrorText();
Assert.assertEquals(actual, "帐号或密码错误!");
}
@Test
public void testSuccess() throws InterruptedException {
LoginPage loginpage = new LoginPage(driver);
loginpage.inputPhone("13323234545");
loginpage.inputPassword("lemon123456");
loginpage.clickLoginBtn();
Thread.sleep(2000);
IndexPage indexPage = new IndexPage(driver);
boolean flag = indexPage.nicknameIsVisibility();
Assert.assertTrue(flag);
}
@DataProvider
public Object[][] datas() {
Object[][] datas = {
{"", "123123123", "请输入手机号"},
{"1585901925", "123123123", "请输入正确的手机号"},
{"158590192534", "123123123", "请输入正确的手机号"},
{"1585901925%", "123123123", "请输入正确的手机号"},
};
return datas;
}
@AfterClass
public void tearDown() throws InterruptedException {
Thread.sleep(2000);
//关闭浏览器
close(driver);
}
public static void close(WebDriver driver) throws InterruptedException {
Thread.sleep(3000);
driver.quit();
}
public static WebDriver open(String type) {
WebDriver driver = null;
if ("chrome".equalsIgnoreCase(type)) {
System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver");
driver = new ChromeDriver();
} else if ("ie".equalsIgnoreCase(type)) {
// 设置ie启动项
DesiredCapabilities capabilities = new DesiredCapabilities();
// 忽略缩放
capabilities.setCapability(InternetExplorerDriver.IGNORE_ZOOM_SETTING, true);
// 忽略保护模式
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
// 设置初始化浏览器地址
capabilities.setCapability(InternetExplorerDriver.INITIAL_BROWSER_URL, "https://www.baidu.com");
// 配置ie驱动位置
System.setProperty("webdriver.ie.driver", "src/test/resources/IEDriverServer.exe");
// 创建ie驱动对象
driver = new InternetExplorerDriver();
} else if ("firefox".equalsIgnoreCase(type)) {
System.setProperty("webdriver.firefox.bin", "D:\\Mozilla Firefox\\firefox.exe");
System.setProperty("webdriver.firefox.driver", "src/test/resources/geckodriver.exe");
driver = new FirefoxDriver();
}
return driver;
}
}
最后,绵薄之力
感谢每一个认真阅读我文章的人,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!