selenium:selenium是一个自动化测试工具,支持chrome,firefox,Safari等主流浏览器的。下载对应浏览器的驱动,就能使用selenium对web页面进行测试。
PageObject:其实是一种设计模式,总的来说就是把每一个页面封装成一个对象。对页面的操作写成一个方法。好处在于当前端ui修改后,我们不需要到每一个测试用例上修改,只需要修改页面对应的类即可。
下面针对知乎登陆实现具体的测试用例。
项目的结构如下:
其实pages存放的每个页面对应的对象,tests文件夹是测试用例,utilities是一些辅助类。
测试框架我们使用的testNG框架
整个项目所需要的依赖入下:
<dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.14.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.3</version> </dependency> </dependencies>
package pages; import io.appium.java_client.android.*; import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.By; import org.testng.Assert; public class BasePage { public WebDriver driver; public WebDriverWait wait; public BasePage(WebDriver driver){ this.driver=driver; wait= new WebDriverWait(driver,15); } public void waitVisibility(By elementBy){ wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(elementBy)); } public void click(By elementBy){ waitVisibility(elementBy); driver.findElement(elementBy).click(); } public void writeText(By elementBy,String text){ waitVisibility(elementBy); driver.findElement(elementBy).sendKeys(text); } public String readText(By elementBy){ waitVisibility(elementBy); return driver.findElement(elementBy).getText(); } public void assertEquals(By elementBy,String expectedText){ waitVisibility(elementBy); Assert.assertEquals(readText(elementBy),expectedText); } }
BasePage类是所有page类的基类,包括初始化浏览器驱动和一些页面常见的操作。
BaseTest.java
package tests; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import io.appium.java_client.AppiumDriver; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.remote.MobileCapabilityType; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.net.MalformedURLException; import java.net.URL; public class BaseTest { public WebDriver driver; @BeforeClass public void setup(){ System.setProperty("webdriver.chrome.driver","D:\\chrome-driver\chromedriver.exe"); driver = new ChromeDriver(); driver.manage().window().maximize(); } @AfterClass public void teardown(){ driver.quit(); } }
BaseTest.java实现的测试前准备动作,测试完成的动作。
LoginTest.java
package tests; import pages.HomePage; import pages.LoginPage; import org.testng.annotations.Test; public class LoginTest extends BaseTest { @Test public void invalidLoginTest_InvalidUserNameInvalidPassword() { HomePage homePage = new HomePage(driver); homePage.goToN11() .goToLoginPage() .loginToZhihu("email@qq.com", "password") .verifyLoginPassword("账号或密码错误"); } @Test public void invalidLoginTest_EmptyUsernameAndPassword(){ HomePage homePage = new HomePage(driver); homePage.goToN11() .goToLoginPage() .loginToZhihu("","") .verifyLoginUserName("请输入手机号或邮箱") .verifyLoginPassword("请输入密码"); } }
LoginTest是针对知乎登陆写的具体测试用例,这里包括两个测试用例。一个是使用错误的的账号和密码进行登陆。第二个是使用的空的账号和密码。
然后给出预期的应该出现的结果。
HomePage.java
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; import sun.rmi.runtime.Log; public class HomePage extends BasePage{ public HomePage(WebDriver driver){ super(driver); } String baseURL = "https://www.zhihu.com"; By signInButtonBy = By.xpath("//*[@id="root"]/div/main/div/div/div/div[2]/div[2]/span"); public HomePage goToN11(){ driver.get(baseURL); return this; } public LoginPage goToLoginPage(){ click(signInButtonBy); return new LoginPage(driver); } }
HomePage主要是唤起浏览器,进入到知乎的首页,然后通过找到登录按钮,跳转到登录页面。
知乎的首页如图所示,我们通过xpath找到"登录”按钮所在的位置,然后点击,跳转到登录页面。
登录页面如下
LoginPage.java
package pages; import pages.BasePage; import org.openqa.selenium.WebDriver; import org.openqa.selenium.By; import io.appium.java_client.android.AndroidElement; import io.appium.java_client.android.AndroidDriver; import org.testng.asserts.Assertion; public class LoginPage extends BasePage { By usernameBy = By.name("username"); By passwordBy = By.name("password"); By loginButtonBy = By.className("SignFlow-submitButton"); public LoginPage(WebDriver driver) { super(driver); } public LoginPage loginToZhihu(String username, String password) { writeText(usernameBy, username); writeText(passwordBy, password); click(loginButtonBy); return this; } public LoginPage verifyLoginUserName(String expectedText){ By errorMessageUsernameBy = By.xpath("//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[1]/div[2]/div[2]"); assertEquals(errorMessageUsernameBy,expectedText); return this; } public LoginPage verifyLoginPassword(String expectedText){ By errorMessagePasswordBy = By.xpath("//*[@id="root"]/div/main/div/div/div/div[2]/div[1]/form/div[2]/div/div[2]"); assertEquals(errorMessagePasswordBy,expectedText); return this; } }
LoginPage.java主要实现了找到账号和密码元素所在的位置,然后进行填充。还有一个方法就是使用断言,看看出现的结果和预期的结果是否一致。这里的两个断言的分别的对应是LoginTest.java对应的两个测试用例中的对结果的判断。
errorMessageUsernameBy表示的是实际结果,
expectedText表示的预期结果。
然后我们启动LoginTest类,不出意外的话,Failures:0。但我这个用例中chrome版本太高了,登录知乎出现了missing argument grant_type错误。据说可以通过降低chrome版本结局
其实这个代码还是有问题,要想登录知乎,有些输入验证码。验证码的问题后面再讲。