基於webdriver的web UI自動化測試框架(系統架構+測試指令碼應用架構)
1.首先是自動化測試系統架構如下圖:
2.測試指令碼的應用架構:
3實際應用後的工程結構:
框架的配置檔案(只是簡單的用properties檔案)
#------------------# # 測試框架配置 #------------------# #啟動目標瀏覽器驅動執行測試 #Browser.Type=ec.qa.autotest.ui.framewrok.webdriverfactory.IEBrowserDriver 暫不支援此瀏覽器 Browser.Type=ec.qa.autotest.ui.framewrok.webdriverfactory.ChromeBrowserDriver #Browser.Type=ec.qa.autotest.ui.framewrok.webdriverfactory.FireFoxBrowserDriver #用例失敗重試次數 testcase.failedcase.retrycount=1 #開啟用例失敗自動截圖功能 testcase.failedcase.screenShotEnabled=true #失敗截圖儲存的目錄 testcase.failedcase.screenShotPath=test-output/screen-shot #是否生成自定義HTML報告 testcase.reporter.htmlreport=true #自定義HTML報告存放路徑 testcase.reporter.htmlreport.path=test-output/html-report #測試資料資料夾地址 testcase.testdata.path=test-data #測試圖片資料夾地址 testcase.testpic.path=\\test-data\\pic\\ #掃描page物件的包將頁面物件自動注入到用力中 init.pageobj.Package = ec.qa.autotest.ui.admin.portal.pageobject,ec.qa.autotest.ui.common.action,ec.qa.autotest.ui.supplier.portal.pageobject,ec.qa.autotest.ui.dao.impl #mybatis配置檔案路徑 init.mybatis.config.path = mybatis-config/mybatis.xml
#測試用例包
init.pageobj.suplier.testcase.Package = ec.qa.autotest.ui.supplier.portal.testcases
init.pageobj.admin.testcase.Package = ec.qa.autotest.ui.admin.portal.testcases
4.jenkins的job啟動自動測試的批處理(因為是基於UI的自動化測試,所以測試代理機是windows系統,使用的是DOS批處理):
@echo off
set workspace=%1%
if not exist %workspace% mkdir %workspace%
cd /d %workspace%
if exist EC_Automation_Test goto cleanENV
goto AutoTest
:cleanENV
echo "project folder exist"
rd /s /q %workspace%\EC_Automation_Test
goto AutoTest
:AutoTest
git clone [email protected]:root/EC_Automation_Test.git
cd EC_Automation_Test
mvn clean test > %workspace%\%date:~5,2%-%date:~8,2%-%time:~0,2%-%time:~3,2%.txt
5.jenkins job 指令碼配置(上述指令碼儲存在 RunAutoTest.bat中):
6.使用jenkins 啟動自動測試:
Started by user qa
Building remotely on AutoMation_Test_Agent (AutoTest) in workspace D:\jenkins\workspace\EC_AutoMation_Test
[EC_AutoMation_Test] $ cmd /c call C:\Users\QA\AppData\Local\Temp\hudson2390304531070066944.bat
The Test Base On Chrome
找不到程序: chromedriver
找不到程序: iedriverserver
"project folder exist"
Cloning into 'EC_Automation_Test'...
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building EC_UI_Auto_Test 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ EC_UI_Auto_Test ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ EC_UI_Auto_Test ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ EC_UI_Auto_Test ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 55 source files to D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ EC_UI_Auto_Test ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ EC_UI_Auto_Test ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ EC_UI_Auto_Test ---
[INFO] No tests to run.
[INFO] Surefire report directory: D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestSuite
...
... TestNG 6.9.4 by Cédric Beust ( [email protected])
...
======測試用例: AddProductDemo 開始執行======
===測試用例執行的瀏覽器型別:Chrome ===
測試網站地址: http://xxx.xxx.com/
Starting ChromeDriver 2.20.353145 (343b531d31eeb933ec778dbcf7081628a1396067) on port 26146
Only local connections are allowed.
上傳圖片中
=====測試用例: AddProductDemo 執行成功=====
killed the useless process
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 104.861 sec - in TestSuite
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:50 min
[INFO] Finished at: 2015-12-09T16:42:52+08:00
[INFO] Final Memory: 21M/222M
[INFO] ------------------------------------------------------------------------
Recording test results
Sending e-mails to: [email protected]
Finished: SUCCESS
7.POM.XML配置:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>EC_Auto_Test</groupId>
<artifactId>EC_UI_Auto_Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>EC_UI_Auto_Test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src\main\java\testng-config\test.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.4</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.47.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>2.47.1</version>
</dependency>
</dependencies>
</project>
用例程式碼編寫文件及例項:
作者:王鑫
日期:Sep.16.2015
最後更新日期:None
****************************************************************************************************************************
程式碼目錄結構:
目前測試程式碼只有一個工程,在該工程中,類檔案(.java)的分組及其存在意義如下:
1.Src/main/java - ec.qa.autotest.ui.constants 用來儲存全域性變數/常量/其他資訊
2.Src/main/java - ec.qa.autotest.ui.pageobject用來儲存頁面的元素資訊或其他從屬資訊,每個類對應一個頁面,每個頁面對應一個類;
3.Src/main/java - ec.qa.autotest.ui.testbase 用來儲存基本測試邏輯,比如每個測試用例的初始化環境步驟;
4.Src/main/java - ec.qa.autotest.ui.utility 用來儲存和業務或被測物件無關的工具,比如操作指定型別的資料、訪問資料庫等;
5.Src/main/java - ec.qa.autotest.ui.testcases 用來儲存實際的測試用例;
如何制定測試用例的執行方案:
例如:現有用例中,以何種順序執行哪些用例的問題
Test.Xml用來制定測試用例的執行方案,根據在此檔案中的不同配置,使用者可以選擇執行制定的用例。
其他目錄分類及其存在意義:
1.BrowserDriver存放瀏覽器驅動等可執行檔案,例如本測試工程可用何種瀏覽器執行測試用例
2.Config 測試全部配置檔案,例如本次測試使用何種瀏覽器
3.Test-Output 預設測試輸出,TestNG的測試報告(Html頁面形式)再次
注:這個不在工程檔案範圍內,需要自行到專案所在資料夾中檢視
程式碼簽入與簽出:
1.試圖新增你更新/新增的程式碼進入master分支之前,請下用如下命令檢查你本地的程式版本是否仍然和當前的master分支一致,如果不一致,請先更新至一致版本再行更新/新增:
$git status 檢視程式碼修改/新增狀態
2.將準備更新/新增的檔案加入準備列表,使用如下命令:
$git add –A注:所有檔案
$git add <檔案名> .注:單個檔案
3.將更新/新增的檔案推送至gitlab伺服器,注意,每次推送都要寫註釋資訊,包含但不限於 將本次更新/新增程式碼的原因及其他需要備註的資訊,。使用如下命令:
$git commit –a –m “備註”注:提交檔案
$git push 注:推送/更新檔案到伺服器
測試程式碼基本資訊說明:
1.測試程式碼從技術角度來說,和開發人員的程式碼(也是測試人員的測試物件)一樣,都是一個Maven Project(工程/專案),使用Java語言開發;
3.測試程式開發基於得的框架是Selenium,你可以在Maven Dependecies路徑下看到它;
4.測試程式執行的容器是WebDriver,你可以在Maven Dependecies路徑下看到它;
5.控制測試程式執行的工具是TestNG,操作的角度來說就是test.xml;
6.標籤的意思是從此標籤起到下一個此標籤間的程式碼段視為一個測試用例,沒有這個標籤的程式碼段將不被視為一個測試用例;
測試用例解析:
package ec.qa.autotest.ui.admin.portal.testcases;
import java.util.HashMap;
import org.testng.annotations.Test;
import ec.qa.autotest.ui.admin.portal.pageobject.AddProductLibraryPage;
import ec.qa.autotest.ui.admin.portal.pageobject.NavigationMenu;
import ec.qa.autotest.ui.admin.portal.pageobject.ProductLibraryPage;
import ec.qa.autotest.ui.common.action.AdminLoadingProgress;
import ec.qa.autotest.ui.common.action.AdminOperationTip;
import ec.qa.autotest.ui.custom.annotation.AutoInject;
import ec.qa.autotest.ui.custom.annotation.DataObject;
import ec.qa.autotest.ui.testbase.impl.AdminPortalTestBase;
public class AddProductLibraryProtal extends AdminPortalTestBase {
@AutoInject
private NavigationMenu menu;
@AutoInject
private ProductLibraryPage porLibrary;
@AutoInject
private AddProductLibraryPage addProLibrary;
@AutoInject
private AdminLoadingProgress adminCommon;
@AutoInject
private AdminOperationTip operationTip;
@DataObject(DataNode="AddProductLibraryPage")
private HashMap<String,String> dataMap;
@Test(invocationCount = 1)
public void addProductLibrary() throws Exception {
menu.goToProdcutLibPage();
porLibrary.addButtonOnclick();
adminCommon.wiatForLoading2Complete();
addProLibrary.AddProduvtLibraryPortal(dataMap.get("ProLibName"),dataMap.get("PLDescription"));
operationTip.waitForTip2appear();
addProLibrary.clickReturnButton();
porLibrary.waitForExpectValue(dataMap.get("ProLibName"));
}
}
如上圖,是一個測試用例的示例,逐行解析如下:
1.@AutoInject
private AdminPortalLoginPage ecHomePage;
獲取測試頁面的物件(自動注入方式 借用spring ioc思想,)詳見:http://blog.csdn.net/wangxin1982314/article/details/50221641
2 @DataObject
自動注入當前用例所需要的資料物件,詳見:http://blog.csdn.net/wangxin1982314/article/details/50319403
3,用例業務程式碼
ecHomePage.loginAdminPortal("admin", "111111");
直接使用宣告頁面物件引用 呼叫相關的action方法 實現頁面操作.
問題1:為什麼就這麼一句程式碼?
如果你的編碼習慣不好,可能會疑惑為什麼沒有像你想象的一樣由如下幾步完成這個操作:
1.FindElementByAttr;
2.InputText;
3.ClickSearchBtn;
問題在於,如果你這樣寫,而且是這樣寫了很多個測試用例,那麼一旦這個Element的Attr發生改變,你就得花費大量的時候Find&Replace,最後結果就是錯誤百出。
為了解決類似這樣的問題,要求每個頁面擁有自己的一個類,例如:
package ec.qa.autotest.ui.admin.portal.pageobject;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
import ec.qa.autotest.ui.custom.annotation.PageObject;
import ec.qa.autotest.ui.testbase.TestBase;
/**
* @author xin.wang
* @see 登入頁面
*/
@PageObject
public class AdminPortalLoginPage {
@FindBy(how = How.ID, using = "loginname")
private WebElement userNameInputBox;
@FindBy(how = How.ID, using = "password")
private WebElement passwordInputBox;
@FindBy(how = How.NAME, using = "loginForm")
private WebElement submitButton;
public void setUserNameContent(String username) {
userNameInputBox.click();
userNameInputBox.sendKeys(username);
}
public void setPwdContent(String pwd) {
passwordInputBox.click();
passwordInputBox.sendKeys(pwd);
}
public void getUserNameContent(String username) {
userNameInputBox.getText();
}
public String getUserNameContent() {
return userNameInputBox.getText();
}
public AdminPortalLoginPage(){
PageFactory.initElements(TestBase.getWebDriver(), this);
}
/**
* @author xin.wang
* @see 登入後臺管理系統
*/
public void loginAdminPortal(String username, String pwd) {
setUserNameContent(username);
setPwdContent(pwd);
submitButton.submit();
}
}
將所有這個頁面內含的元件及其操作邏輯全部放在這個頁面的類中,如此我們可以達成如下目的:
a.每個頁面的耦合度大幅下降,任何一個頁面的改變都不會影響到其他的頁面;
b.將物件/方法的生命集中到一個地方,任何的改變只需要在此處修改一次即可;
c. @PageObject 在測試用例中 頁面物件實測試框架自動注入的(控制反轉) ,不必關注什麼時候去例項它。
@PageObject 見部落格http://blog.csdn.net/wangxin1982314/article/details/50221641
注:
a.以“搜尋”為例,與某些錄製程式的工具不同的是,程式執行時,你在頁面上不會看到按鈕被點選等動畫效果,這是因為我們僅僅是觸發了Form傳送的動作,而不是按鈕點選的動作。但是你不需要擔心這會影響到測試結果,因為以下兩點原因:
1)伺服器並不關心客戶端動作,只關心request資料;
2)動畫效果屬於渲染步驟,是瀏覽器/作業系統的固有特性,和邏輯完全無關;
b.隱藏測試執行過程中重複的過程,寫一個基類,所有用例繼承此基類,那麼自動化測試用例編寫人員只需要關注自己的page類和具體的測試用例類即可:
ItesBase介面:
package ec.qa.autotest.ui.testbase;
import java.lang.reflect.Method;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.xml.XmlTest;
/**
* @author xin.wang
* 測試基類介面
*/
public interface ITestBase {
@BeforeSuite
public void initTest(XmlTest xt, ITestContext tc) throws Exception;
@AfterSuite
public void terminTestSuite(XmlTest xt, ITestContext tc) throws Exception;
@BeforeClass
public void beforeClass(XmlTest xt, ITestContext tc) throws Exception;
@AfterClass
public void afterClass(XmlTest xt, ITestContext tc) throws Exception;
@BeforeTest
public void beforeTest(XmlTest xt, ITestContext tc) throws Exception;
@AfterTest
public void afterTest(XmlTest xt, ITestContext tc) throws Exception;
@BeforeMethod
public void initDriver(ITestContext tc, Method m, XmlTest xt) throws Exception;
@AfterMethod
public void cleanEnv(ITestResult rs, XmlTest xt, Method m, ITestContext tc) throws Exception;
}
TestBase抽象基類:
package ec.qa.autotest.ui.testbase.impl;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.BeforeSuite;
import org.testng.xml.XmlTest;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import ec.qa.autotest.ui.constants.CommonConstants;
import ec.qa.autotest.ui.constants.PropertiesKeys;
import ec.qa.autotest.ui.testbase.ITestBase;
import ec.qa.autotest.ui.testng.listener.RetryToRunCase;
import ec.qa.autotest.ui.utility.CookiesUtil;
import ec.qa.autotest.ui.utility.ExcuteDOSCommand;
import ec.qa.autotest.ui.utility.PageObjectUtil;
import ec.qa.autotest.ui.utility.PictureUtil;
import ec.qa.autotest.ui.utility.PropertiesUtil;
import ec.qa.autotest.ui.utility.InitPageObject;
public abstract class TestBase implements ITestBase {
protected static RemoteWebDriver webDriver;
protected static String browserType;
public static boolean success = true;
protected static int retryMaxCount = RetryToRunCase.getMaxRetryCount();
protected static int reTryCount = 1;
private static String testCaseDeclaringClass = null;
/**
* @author xin.wang
* @see 在測試集執行前確定要執行測試的瀏覽器型別
*/
@BeforeSuite(alwaysRun = true)
public void initTest(XmlTest xt,ITestContext tc) throws Exception {
System.setProperty(CommonConstants.CONFIG_FOLDER_PATH_KEY, CommonConstants.CONFIG_FOLDER_PATH_VALUE);
if (null == PropertiesUtil.getProKVMap()) {
new Root();
}
PictureUtil.setBaseUrl(System.getProperty("user.dir") + PropertiesUtil.getProValue("testcase.testpic.path"));
browserType = PropertiesUtil.getProValue(PropertiesKeys.BROWSER_TYPE).toString();
}
/**
* @author xin.wang
* @see 測試方法執行結束後清理測試環境
*/
@AfterMethod
public void cleanEnv(ITestResult rs,XmlTest xt,Method m,ITestContext tc) throws Exception {
try {
PageObjectUtil.setPageObjMap(null);
if (!rs.isSuccess()) {
if (reTryCount <= retryMaxCount) {
success = false;
}
Throwable throwable = rs.getThrowable();
System.out.println("=====測試用例: " + rs.getMethod().getMethodName() + " 執行失敗,原因: "
+ throwable.getMessage() + "=====");
StackTraceElement[] se = throwable.getStackTrace();
System.out.println("堆疊資訊:");
for (StackTraceElement e : se) {
System.out.println(e.toString());
}
} else {
reTryCount = 1;
System.out.println("=====測試用例: " + rs.getMethod().getMethodName() + " 執行成功=====");
}
webDriver.close();
webDriver.quit();
} catch (Exception e) {
e.printStackTrace();
} finally {
ExcuteDOSCommand.excuteBATFile(CommonConstants.KILL_DRIVER_PROCESS_BAT);
}
}
public void preCondition(ConfigDriverParameters cp) throws Exception {
testCaseDeclaringClass = cp.getTestMethod().getDeclaringClass().getName();
String website = cp.getTargetWebSite();
displayTipInfo(website, cp.getTestMethod());
configDriver(cp);
openTargetWebSit(website);
}
private void configDriver(ConfigDriverParameters cp) throws Exception {
webDriver = Root.wf.getDriver(browserType);
new InitPageObject(this);
webDriver.manage().timeouts().implicitlyWait(cp.getSerachElementTime(), TimeUnit.SECONDS);
webDriver.manage().window().maximize();
webDriver.manage().timeouts().pageLoadTimeout(cp.getPageLoadTime(), TimeUnit.SECONDS);
}
private void displayTipInfo(String website, Method m) {
if (!success) {
System.out.println("\n=======測試用例準備重試=======");
reTryCount++;
success = true;
}
System.out.println("\n======測試用例: " + m.getName() + " 開始執行======" + "\n===測試用例執行的瀏覽器型別:" + browserType + " ==="
+ "\n測試網站地址: " + website);
}
public static String getTestCaseDeclaringClass() {
return testCaseDeclaringClass;
}
private void openTargetWebSit(String website) {
if (CookiesUtil.getCk() != null) {
webDriver.manage().timeouts().pageLoadTimeout(3, TimeUnit.SECONDS);
try {
webDriver.get(website);
} catch (Exception e) {
}
webDriver.manage().addCookie(CookiesUtil.getCk());
}
try {
webDriver.get(website);
} catch (Exception e) {
}
webDriver.manage().timeouts().pageLoadTimeout(-1, TimeUnit.SECONDS);
}
/**
* @author xin.wang
* @see 獲取webdriver物件例項
*/
public static RemoteWebDriver getWebDriver() {
return webDriver;
}
}
如果被測網站為了區分不同的功能集合,提供了不同的域名入口,可以在上面基類基礎上再封裝一層,不同入口的用例繼承各自封裝好的基類:
package ec.qa.autotest.ui.testbase.impl;
import java.lang.reflect.Method;
import org.testng.ITestContext;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.xml.XmlTest;
import ec.qa.autotest.ui.constants.PropertiesKeys;
import ec.qa.autotest.ui.utility.CookiesUtil;
import ec.qa.autotest.ui.utility.PropertiesUtil;
/**
* @author xin.wang 供應商入口網站測試基類
*/
public class SupplierPortalTestBase extends TestBase {
@BeforeMethod(alwaysRun = true)
public void initDriver(ITestContext tc, Method m, XmlTest xt) throws Exception {
ConfigDriverParameters cp = new ConfigDriverParameters();
cp.setPageLoadTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.SUPPLIER_PORTAL_PAGELOAD_TIME)));
cp.setTargetWebSite(PropertiesUtil.getProValue(PropertiesKeys.SUPPLIER_PORTAL_AUTO_TEST_WEBSITE));
cp.setSerachElementTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.IMPLICITLYWAIT_TIME)));
cp.setTestMethod(m);
preCondition(cp);
}
@AfterSuite(alwaysRun = true)
public void terminTestSuite(XmlTest xt, ITestContext tc) {
CookiesUtil.setCk(null);
}
public void beforeClass(XmlTest xt, ITestContext tc) {
// TODO Auto-generated method stub
}
public void afterClass(XmlTest xt, ITestContext tc) {
// TODO Auto-generated method stub
}
public void beforeTest(XmlTest xt, ITestContext tc) {
// TODO Auto-generated method stub
}
public void afterTest(XmlTest xt, ITestContext tc) {
// TODO Auto-generated method stub
}
}
package ec.qa.autotest.ui.testbase.impl;
import java.lang.reflect.Method;
import org.openqa.selenium.support.PageFactory;
import org.testng.ITestContext;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;
import org.testng.xml.XmlTest;
import ec.qa.autotest.ui.admin.portal.pageobject.AdminPortalLoginPage;
import ec.qa.autotest.ui.constants.PropertiesKeys;
import ec.qa.autotest.ui.utility.PropertiesUtil;
/**
* @author xin.wang
* 供應商後臺管理網站測試基類
*/
public class AdminPortalTestBase extends TestBase {
@BeforeMethod(alwaysRun = true)
public void initDriver(ITestContext tc, Method m, XmlTest xt) throws Exception {
ConfigDriverParameters cp = new ConfigDriverParameters();
cp.setPageLoadTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.ADMIN_PORTAL_PAGELOAD_TIME)));
cp.setTargetWebSite(PropertiesUtil.getProValue(PropertiesKeys.ADMIN_PORTAL_AUTO_TEST_WEBSITE));
cp.setSerachElementTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.IMPLICITLYWAIT_TIME)));
cp.setTestMethod(m);
preCondition(cp);
AdminPortalLoginPage ecHomePage = PageFactory.initElements(TestBase.getWebDriver(), AdminPortalLoginPage.class);
ecHomePage.loginAdminPortal("admin", "111111");
}
@AfterSuite
public void terminTestSuite(XmlTest xt, ITestContext tc) throws Exception {
// TODO Auto-generated method stub
}
public void beforeClass(XmlTest xt, ITestContext tc) throws Exception {
// TODO Auto-generated method stub
}
public void afterClass(XmlTest xt, ITestContext tc) throws Exception {
// TODO Auto-generated method stub
}
public void beforeTest(XmlTest xt, ITestContext tc) throws Exception {
// TODO Auto-generated method stub
}
public void afterTest(XmlTest xt, ITestContext tc) throws Exception {
// TODO Auto-generated method stub
}
}
c.@FindBy是個什麼東西?
FindyBy是Selenium框架的維護的一種自定義標籤,用來標示定位頁面元素的方式,一般來說你不需要更新它
@AutoInject @PageObject 參看 http://blog.csdn.net/wangxin1982314/article/details/50221641
c @PageObject (測試框架實現)
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author xin.wang
* @see 標識當前類是否是頁面物件
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PageObject {
boolean lazyLoad() default false;
}
c @AuotInject(測試框架實現)
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author xin.wang
* 自動裝配標籤
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoInject {
boolean enable() default true;
}
目前框架實現的一些功能請檢視一下博文(隨時更新):
使用工廠方法生產不同瀏覽器的webdriver例項:http://blog.csdn.net/wangxin1982314/article/details/50331355
UI自動化測試自動裝配測試用例所需的資料物件:http://blog.csdn.net/wangxin1982314/article/details/50319403
XPTAH除錯工具(chrome外掛):http://blog.csdn.net/wangxin1982314/article/details/50264389
Webdriver+Testng自定義html測試報告:http://blog.csdn.net/wangxin1982314/article/details/50260409
webdriver原始碼分析:http://blog.csdn.net/wangxin1982314/article/details/50239129
關於webdriver上傳檔案功能的一些補充:http://blog.csdn.net/wangxin1982314/article/details/50237567
Webdriver+Testng實現測試用例失敗自動截圖功能:http://blog.csdn.net/wangxin1982314/article/details/50247245
Web
UI 優化自動化測試用例的穩定性:http://blog.csdn.net/wangxin1982314/article/details/50222635
Web
UI自動化測試框架 使用遞迴一次性載入配置檔案資訊(.properties):http://blog.csdn.net/wangxin1982314/article/details/50222457
執行測試用例集過程中在jenkins控制檯列印當前用例測試結果(testng):http://blog.csdn.net/wangxin1982314/article/details/50222073
實現testNg的retry機制:http://blog.csdn.net/wangxin1982314/article/details/50219551
自動化測試使用mybatis更新資料庫資訊例項http://blog.csdn.net/wangxin1982314/article/details/50428452
webdriver UI自動化測試執行JS指令碼:http://blog.csdn.net/wangxin1982314/article/details/50428452
使用JAVA
Robot 擴充套件Webdriver 模擬鍵盤滑鼠操作:http://blog.csdn.net/wangxin1982314/article/details/50344083