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
@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语言开发;
2.既然测试的工程也是Maven Project,那么它的工程文件也就是pom.xml,关于pom的详解可以参考:http://blog.csdn.net/zhuxinhua/article/details/5788546
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 在测试用例中 页面对象实测试框架自动注入的(控制反转) ,不必关注什么时候去实例它。
注:
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; }
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框架的维护的一种自定义标签,用来标示定位页面元素的方式,一般来说你不需要更新它
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; }
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+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