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版本結局

其實這個代碼還是有問題,要想登錄知乎,有些輸入驗證碼。驗證碼的問題后面再講。