基于webdriver的web UI自动化测试框架(系统架构+测试脚本应用架构)

来源:互联网 发布:知乎web前端必读书籍 编辑:程序博客网 时间:2024/05/17 07:44

1、自动化测试系统架构图


2、测试脚本应用架构



3实际应用后的工程结构:



框架的配置文件(只是简单的用properties文件)

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #------------------#  
  2. #  测试框架配置  
  3. #------------------#  
  4.   
  5.   
  6. #启动目标浏览器驱动运行测试  
  7. #Browser.Type=ec.qa.autotest.ui.framewrok.webdriverfactory.IEBrowserDriver  暂不支持此浏览器  
  8. Browser.Type=ec.qa.autotest.ui.framewrok.webdriverfactory.ChromeBrowserDriver  
  9. #Browser.Type=ec.qa.autotest.ui.framewrok.webdriverfactory.FireFoxBrowserDriver  
  10.   
  11.   
  12. #用例失败重试次数  
  13. testcase.failedcase.retrycount=1  
  14.   
  15.   
  16. #开启用例失败自动截图功能  
  17. testcase.failedcase.screenShotEnabled=true  
  18.   
  19.   
  20. #失败截图保存的目录  
  21. testcase.failedcase.screenShotPath=test-output/screen-shot  
  22.   
  23.   
  24. #是否生成自定义HTML报告  
  25. testcase.reporter.htmlreport=true  
  26.   
  27.   
  28. #自定义HTML报告存放路径  
  29. testcase.reporter.htmlreport.path=test-output/html-report  
  30.   
  31.   
  32. #测试数据文件夹地址  
  33. testcase.testdata.path=test-data  
  34.   
  35.   
  36. #测试图片文件夹地址  
  37. testcase.testpic.path=\\test-data\\pic\\  
  38.   
  39.   
  40. #扫描page对象的包将页面对象自动注入到用力中  
  41. 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  
  42.   
  43.   
  44. #mybatis配置文件路径  
  45. init.mybatis.config.path = mybatis-config/mybatis.xml  
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #测试用例包  
  2. init.pageobj.suplier.testcase.Package = ec.qa.autotest.ui.supplier.portal.testcases  
  3. init.pageobj.admin.testcase.Package = ec.qa.autotest.ui.admin.portal.testcases  


4.jenkins的job启动自动测试的批处理(因为是基于UI的自动化测试,所以测试代理机是windows系统,使用的是DOS批处理)

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. @echo off  
  2. set workspace=%1%  
  3. if not exist %workspace% mkdir %workspace%  
  4. cd /d %workspace%  
  5. if exist EC_Automation_Test goto cleanENV  
  6. goto AutoTest  
  7. :cleanENV  
  8. echo "project folder exist"  
  9. rd /s /q %workspace%\EC_Automation_Test  
  10. goto AutoTest  
  11. :AutoTest  
  12. git clone git@192.168.0.156:root/EC_Automation_Test.git  
  13. cd EC_Automation_Test  
  14. mvn clean test > %workspace%\%date:~5,2%-%date:~8,2%-%time:~0,2%-%time:~3,2%.txt   



5.jenkins job 脚本配置(上述脚本保存在 RunAutoTest.bat中):


6.使用jenkins 启动自动测试:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. Started by user qa  
  2. Building remotely on AutoMation_Test_Agent (AutoTest) in workspace D:\jenkins\workspace\EC_AutoMation_Test  
  3. [EC_AutoMation_Test] $ cmd /c call C:\Users\QA\AppData\Local\Temp\hudson2390304531070066944.bat  
  4.  The Test Base On Chrome  
  5. 找不到进程: chromedriver  
  6. 找不到进程: iedriverserver  
  7. "project folder exist"  
  8. Cloning into 'EC_Automation_Test'...  
  9. [INFO] Scanning for projects...  
  10. [INFO]                                                                           
  11. [INFO] ------------------------------------------------------------------------  
  12. [INFO] Building EC_UI_Auto_Test 0.0.1-SNAPSHOT  
  13. [INFO] ------------------------------------------------------------------------  
  14. [INFO]   
  15. [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ EC_UI_Auto_Test ---  
  16. [INFO]   
  17. [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ EC_UI_Auto_Test ---  
  18. [INFO] Using 'UTF-8' encoding to copy filtered resources.  
  19. [INFO] skip non existing resourceDirectory D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\src\main\resources  
  20. [INFO]   
  21. [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ EC_UI_Auto_Test ---  
  22. [INFO] Changes detected - recompiling the module!  
  23. [INFO] Compiling 55 source files to D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\target\classes  
  24. [INFO]   
  25. [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ EC_UI_Auto_Test ---  
  26. [INFO] Using 'UTF-8' encoding to copy filtered resources.  
  27. [INFO] skip non existing resourceDirectory D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\src\test\resources  
  28. [INFO]   
  29. [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ EC_UI_Auto_Test ---  
  30. [INFO] No sources to compile  
  31. [INFO]   
  32. [INFO] --- maven-surefire-plugin:2.18.1:test (default-test) @ EC_UI_Auto_Test ---  
  33. [INFO] No tests to run.  
  34. [INFO] Surefire report directory: D:\jenkins\workspace\EC_AutoMation_Test\EC_Automation_Test\target\surefire-reports  
  35.   
  36. -------------------------------------------------------  
  37.  T E S T S  
  38. -------------------------------------------------------  
  39. Running TestSuite  
  40. ...  
  41. ... TestNG 6.9.4 by Cédric Beust (cedric@beust.com)  
  42. ...  
  43.   
  44.   
  45. ======测试用例: AddProductDemo 开始执行======  
  46. ===测试用例运行的浏览器类型:Chrome ===  
  47. 测试网站地址: http://xxx.xxx.com/  
  48. Starting ChromeDriver 2.20.353145 (343b531d31eeb933ec778dbcf7081628a1396067) on port 26146  
  49. Only local connections are allowed.  
  50. 上传图片中  
  51. =====测试用例: AddProductDemo 运行成功=====  
  52. killed the useless process  
  53. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 104.861 sec - in TestSuite  
  54.   
  55. Results :  
  56.   
  57. Tests run: 1, Failures: 0, Errors: 0, Skipped: 0  
  58.   
  59. [INFO] ------------------------------------------------------------------------  
  60. [INFO] BUILD SUCCESS  
  61. [INFO] ------------------------------------------------------------------------  
  62. [INFO] Total time: 01:50 min  
  63. [INFO] Finished at: 2015-12-09T16:42:52+08:00  
  64. [INFO] Final Memory: 21M/222M  
  65. [INFO] ------------------------------------------------------------------------  
  66. Recording test results  
  67. Sending e-mails to: qa.group@xxxxx.com  
  68. Finished: SUCCESS  

7.POM.XML配置:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.   
  5.     <groupId>EC_Auto_Test</groupId>  
  6.     <artifactId>EC_UI_Auto_Test</artifactId>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <packaging>jar</packaging>  
  9.   
  10.     <name>EC_UI_Auto_Test</name>  
  11.     <url>http://maven.apache.org</url>  
  12.   
  13.     <properties>  
  14.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  15.     </properties>  
  16.   
  17.     <build>  
  18.         <pluginManagement>  
  19.             <plugins>  
  20.                 <plugin>  
  21.                     <groupId>org.apache.maven.plugins</groupId>  
  22.                     <artifactId>maven-surefire-plugin</artifactId>  
  23.                     <version>2.18.1</version>  
  24.                     <configuration>  
  25.                         <suiteXmlFiles>  
  26.                             <suiteXmlFile>src\main\java\testng-config\test.xml</suiteXmlFile>  
  27.                         </suiteXmlFiles>  
  28.                     </configuration>  
  29.                 </plugin>  
  30.             </plugins>  
  31.         </pluginManagement>  
  32.     </build>  
  33.   
  34.     <dependencies>  
  35.         <dependency>  
  36.             <groupId>org.testng</groupId>  
  37.             <artifactId>testng</artifactId>  
  38.             <version>6.9.4</version>  
  39.         </dependency>  
  40.   
  41.         <dependency>  
  42.             <groupId>org.seleniumhq.selenium</groupId>  
  43.             <artifactId>selenium-java</artifactId>  
  44.             <version>2.47.1</version>  
  45.         </dependency>  
  46.   
  47.         <dependency>  
  48.             <groupId>org.seleniumhq.selenium</groupId>  
  49.             <artifactId>selenium-server</artifactId>  
  50.             <version>2.47.1</version>  
  51.         </dependency>  
  52.     </dependencies>  
  53. </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.标签的意思是从此标签起到下一个此标签间的代码段视为一个测试用例,没有这个标签的代码段将不被视为一个测试用例;

 

 

测试用例解析:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package ec.qa.autotest.ui.admin.portal.testcases;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import org.testng.annotations.Test;  
  6. import ec.qa.autotest.ui.admin.portal.pageobject.AddProductLibraryPage;  
  7. import ec.qa.autotest.ui.admin.portal.pageobject.NavigationMenu;  
  8. import ec.qa.autotest.ui.admin.portal.pageobject.ProductLibraryPage;  
  9. import ec.qa.autotest.ui.common.action.AdminLoadingProgress;  
  10. import ec.qa.autotest.ui.common.action.AdminOperationTip;  
  11. import ec.qa.autotest.ui.custom.annotation.AutoInject;  
  12. import ec.qa.autotest.ui.custom.annotation.DataObject;  
  13. import ec.qa.autotest.ui.testbase.impl.AdminPortalTestBase;  
  14.   
  15.   
  16. public class AddProductLibraryProtal extends AdminPortalTestBase {  
  17.       
  18.     @AutoInject  
  19.     private  NavigationMenu menu;  
  20.       
  21.     @AutoInject  
  22.     private  ProductLibraryPage porLibrary;  
  23.       
  24.     @AutoInject  
  25.     private  AddProductLibraryPage addProLibrary;  
  26.       
  27.     @AutoInject  
  28.     private  AdminLoadingProgress adminCommon;  
  29.       
  30.     @AutoInject  
  31.     private  AdminOperationTip operationTip;  
  32.       
  33.     @DataObject(DataNode="AddProductLibraryPage")  
  34.     private  HashMap<String,String> dataMap;  
  35.       
  36.     @Test(invocationCount = 1)  
  37.     public void addProductLibrary() throws Exception {  
  38.         menu.goToProdcutLibPage();  
  39.         porLibrary.addButtonOnclick();  
  40.         adminCommon.wiatForLoading2Complete();  
  41.         addProLibrary.AddProduvtLibraryPortal(dataMap.get("ProLibName"),dataMap.get("PLDescription"));  
  42.         operationTip.waitForTip2appear();  
  43.         addProLibrary.clickReturnButton();  
  44.         porLibrary.waitForExpectValue(dataMap.get("ProLibName"));  
  45.     }  
  46. }  


 如上图,是一个测试用例的示例,逐行解析如下:

1.@AutoInject

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. 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;

 

问题在于,如果你这样写,而且是这样写了很多个测试用例,那么一旦这个ElementAttr发生改变,你就得花费大量的时候Find&Replace,最后结果就是错误百出。

 

为了解决类似这样的问题,要求每个页面拥有自己的一个类,例如:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package ec.qa.autotest.ui.admin.portal.pageobject;  
  2.   
  3.   
  4. import org.openqa.selenium.WebElement;  
  5. import org.openqa.selenium.support.FindBy;  
  6. import org.openqa.selenium.support.How;  
  7. import org.openqa.selenium.support.PageFactory;  
  8. import ec.qa.autotest.ui.custom.annotation.PageObject;  
  9. import ec.qa.autotest.ui.testbase.TestBase;  
  10.   
  11.   
  12. /** 
  13.  * @author xin.wang 
  14.  * @see 登录页面 
  15.  */  
  16. @PageObject  
  17. public class AdminPortalLoginPage {  
  18.       
  19.     @FindBy(how = How.ID, using = "loginname")  
  20.     private WebElement userNameInputBox;  
  21.   
  22.   
  23.     @FindBy(how = How.ID, using = "password")  
  24.     private WebElement passwordInputBox;  
  25.   
  26.   
  27.     @FindBy(how = How.NAME, using = "loginForm")  
  28.     private WebElement submitButton;  
  29.   
  30.   
  31.     public void setUserNameContent(String username) {  
  32.         userNameInputBox.click();  
  33.         userNameInputBox.sendKeys(username);  
  34.     }  
  35.       
  36.     public void setPwdContent(String pwd) {  
  37.         passwordInputBox.click();  
  38.         passwordInputBox.sendKeys(pwd);  
  39.     }  
  40.       
  41.     public void getUserNameContent(String username) {  
  42.         userNameInputBox.getText();  
  43.     }  
  44.   
  45.   
  46.     public String getUserNameContent() {  
  47.         return userNameInputBox.getText();  
  48.     }  
  49.   
  50.   
  51.     public AdminPortalLoginPage(){  
  52.         PageFactory.initElements(TestBase.getWebDriver(), this);  
  53.     }  
  54.       
  55.     /** 
  56.      * @author xin.wang 
  57.      * @see 登录后台管理系统 
  58.      */  
  59.   
  60.   
  61.     public void loginAdminPortal(String username, String pwd) {  
  62.         setUserNameContent(username);  
  63.         setPwdContent(pwd);  
  64.         submitButton.submit();  
  65.     }  
  66. }  

将所有这个页面内含的组件及其操作逻辑全部放在这个页面的类中,如此我们可以达成如下目的:

a.每个页面的耦合度大幅下降,任何一个页面的改变都不会影响到其他的页面;

b.将对象/方法的生命集中到一个地方,任何的改变只需要在此处修改一次即可;

       c. @PageObject 在测试用例中 页面对象实测试框架自动注入的(控制反转) ,不必关注什么时候去实例它。

    @PageObject 见博客http://blog.csdn.net/wangxin1982314/article/details/50221641

注:

a.以“搜索”为例,与某些录制程序的工具不同的是,程序运行时,你在页面上不会看到按钮被点击等动画效果,这是因为我们仅仅是触发了Form发送的动作,而不是按钮点击的动作。但是你不需要担心这会影响到测试结果,因为以下两点原因:

1)服务器并不关心客户端动作,只关心request数据;

2)动画效果属于渲染步骤,是浏览器/操作系统的固有特性,和逻辑完全无关;

b.隐藏测试运行过程中重复的过程,写一个基类,所有用例继承此基类,那么自动化测试用例编写人员只需要关注自己的page类和具体的测试用例类即可:

ItesBase接口:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package ec.qa.autotest.ui.testbase;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.testng.ITestContext;  
  6. import org.testng.ITestResult;  
  7. import org.testng.annotations.AfterClass;  
  8. import org.testng.annotations.AfterMethod;  
  9. import org.testng.annotations.AfterSuite;  
  10. import org.testng.annotations.AfterTest;  
  11. import org.testng.annotations.BeforeClass;  
  12. import org.testng.annotations.BeforeMethod;  
  13. import org.testng.annotations.BeforeSuite;  
  14. import org.testng.annotations.BeforeTest;  
  15. import org.testng.xml.XmlTest;  
  16.   
  17. /**  
  18.  * @author xin.wang  
  19.  * 测试基类接口  
  20.  */  
  21. public interface ITestBase {  
  22.   
  23.     @BeforeSuite  
  24.     public void initTest(XmlTest xt, ITestContext tc) throws Exception;  
  25.   
  26.     @AfterSuite  
  27.     public void terminTestSuite(XmlTest xt, ITestContext tc) throws Exception;  
  28.   
  29.     @BeforeClass  
  30.     public void beforeClass(XmlTest xt, ITestContext tc) throws Exception;  
  31.   
  32.     @AfterClass  
  33.     public void afterClass(XmlTest xt, ITestContext tc) throws Exception;  
  34.   
  35.     @BeforeTest  
  36.     public void beforeTest(XmlTest xt, ITestContext tc) throws Exception;  
  37.   
  38.     @AfterTest  
  39.     public void afterTest(XmlTest xt, ITestContext tc) throws Exception;  
  40.   
  41.     @BeforeMethod  
  42.     public void initDriver(ITestContext tc, Method m, XmlTest xt) throws Exception;  
  43.   
  44.     @AfterMethod  
  45.     public void cleanEnv(ITestResult rs, XmlTest xt, Method m, ITestContext tc) throws Exception;  
  46. }  


TestBase抽象基类:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package ec.qa.autotest.ui.testbase.impl;  
  2.   
  3. import java.lang.reflect.Method;  
  4. import java.util.concurrent.TimeUnit;  
  5.   
  6. import org.openqa.selenium.remote.RemoteWebDriver;  
  7. import org.testng.annotations.BeforeSuite;  
  8. import org.testng.xml.XmlTest;  
  9. import org.testng.ITestContext;  
  10. import org.testng.ITestResult;  
  11. import org.testng.annotations.AfterMethod;  
  12.   
  13. import ec.qa.autotest.ui.constants.CommonConstants;  
  14. import ec.qa.autotest.ui.constants.PropertiesKeys;  
  15. import ec.qa.autotest.ui.testbase.ITestBase;  
  16. import ec.qa.autotest.ui.testng.listener.RetryToRunCase;  
  17. import ec.qa.autotest.ui.utility.CookiesUtil;  
  18. import ec.qa.autotest.ui.utility.ExcuteDOSCommand;  
  19. import ec.qa.autotest.ui.utility.PageObjectUtil;  
  20. import ec.qa.autotest.ui.utility.PictureUtil;  
  21. import ec.qa.autotest.ui.utility.PropertiesUtil;  
  22. import ec.qa.autotest.ui.utility.InitPageObject;  
  23.   
  24. public abstract class TestBase implements ITestBase {  
  25.     protected static RemoteWebDriver webDriver;  
  26.     protected static String browserType;  
  27.     public static boolean success = true;  
  28.     protected static int retryMaxCount = RetryToRunCase.getMaxRetryCount();  
  29.     protected static int reTryCount = 1;  
  30.     private static String testCaseDeclaringClass = null;  
  31.   
  32.     /**  
  33.      * @author xin.wang  
  34.      * @see 在测试集运行前确定要运行测试的浏览器类型  
  35.      */  
  36.     @BeforeSuite(alwaysRun = true)  
  37.     public void initTest(XmlTest xt,ITestContext tc) throws Exception {  
  38.         System.setProperty(CommonConstants.CONFIG_FOLDER_PATH_KEY, CommonConstants.CONFIG_FOLDER_PATH_VALUE);  
  39.         if (null == PropertiesUtil.getProKVMap()) {  
  40.             new Root();  
  41.         }  
  42.         PictureUtil.setBaseUrl(System.getProperty("user.dir") + PropertiesUtil.getProValue("testcase.testpic.path"));  
  43.         browserType = PropertiesUtil.getProValue(PropertiesKeys.BROWSER_TYPE).toString();  
  44.     }  
  45.   
  46.     /**  
  47.      * @author xin.wang  
  48.      * @see 测试方法执行结束后清理测试环境  
  49.      */  
  50.     @AfterMethod  
  51.     public void cleanEnv(ITestResult rs,XmlTest xt,Method m,ITestContext tc) throws Exception {  
  52.         try {  
  53.             PageObjectUtil.setPageObjMap(null);  
  54.             if (!rs.isSuccess()) {  
  55.                 if (reTryCount <= retryMaxCount) {  
  56.                     success = false;  
  57.                 }  
  58.                 Throwable throwable = rs.getThrowable();  
  59.                 System.out.println("=====测试用例: " + rs.getMethod().getMethodName() + " 运行失败,原因: "  
  60.                         + throwable.getMessage() + "=====");  
  61.                 StackTraceElement[] se = throwable.getStackTrace();  
  62.                 System.out.println("堆栈信息:");  
  63.                 for (StackTraceElement e : se) {  
  64.                     System.out.println(e.toString());  
  65.                 }  
  66.             } else {  
  67.                 reTryCount = 1;  
  68.                 System.out.println("=====测试用例: " + rs.getMethod().getMethodName() + " 运行成功=====");  
  69.             }  
  70.             webDriver.close();  
  71.             webDriver.quit();  
  72.         } catch (Exception e) {  
  73.             e.printStackTrace();  
  74.         } finally {  
  75.             ExcuteDOSCommand.excuteBATFile(CommonConstants.KILL_DRIVER_PROCESS_BAT);  
  76.         }  
  77.     }  
  78.   
  79.     public void preCondition(ConfigDriverParameters cp) throws Exception {  
  80.         testCaseDeclaringClass = cp.getTestMethod().getDeclaringClass().getName();  
  81.         String website = cp.getTargetWebSite();  
  82.         displayTipInfo(website, cp.getTestMethod());  
  83.         configDriver(cp);  
  84.         openTargetWebSit(website);  
  85.     }  
  86.   
  87.     private void configDriver(ConfigDriverParameters cp) throws Exception {  
  88.         webDriver = Root.wf.getDriver(browserType);  
  89.         new InitPageObject(this);  
  90.         webDriver.manage().timeouts().implicitlyWait(cp.getSerachElementTime(), TimeUnit.SECONDS);  
  91.         webDriver.manage().window().maximize();  
  92.         webDriver.manage().timeouts().pageLoadTimeout(cp.getPageLoadTime(), TimeUnit.SECONDS);  
  93.     }  
  94.   
  95.     private void displayTipInfo(String website, Method m) {  
  96.         if (!success) {  
  97.             System.out.println("\n=======测试用例准备重试=======");  
  98.             reTryCount++;  
  99.             success = true;  
  100.         }  
  101.         System.out.println("\n======测试用例: " + m.getName() + " 开始执行======" + "\n===测试用例运行的浏览器类型:" + browserType + " ==="  
  102.                 + "\n测试网站地址: " + website);  
  103.   
  104.     }  
  105.   
  106.     public static String getTestCaseDeclaringClass() {  
  107.         return testCaseDeclaringClass;  
  108.     }  
  109.   
  110.     private void openTargetWebSit(String website) {  
  111.         if (CookiesUtil.getCk() != null) {  
  112.             webDriver.manage().timeouts().pageLoadTimeout(3, TimeUnit.SECONDS);  
  113.             try {  
  114.                 webDriver.get(website);  
  115.             } catch (Exception e) {  
  116.             }  
  117.             webDriver.manage().addCookie(CookiesUtil.getCk());  
  118.         }  
  119.         try {  
  120.             webDriver.get(website);  
  121.         } catch (Exception e) {  
  122.         }  
  123.         webDriver.manage().timeouts().pageLoadTimeout(-1, TimeUnit.SECONDS);  
  124.     }  
  125.   
  126.     /**  
  127.      * @author xin.wang  
  128.      * @see 获取webdriver对象实例  
  129.      */  
  130.   
  131.     public static RemoteWebDriver getWebDriver() {  
  132.         return webDriver;  
  133.     }  
  134. }  

如果被测网站为了区分不同的功能集合,提供了不同的域名入口,可以在上面基类基础上再封装一层,不同入口的用例继承各自封装好的基类:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package ec.qa.autotest.ui.testbase.impl;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.testng.ITestContext;  
  6. import org.testng.annotations.AfterSuite;  
  7. import org.testng.annotations.BeforeMethod;  
  8. import org.testng.xml.XmlTest;  
  9.   
  10. import ec.qa.autotest.ui.constants.PropertiesKeys;  
  11. import ec.qa.autotest.ui.utility.CookiesUtil;  
  12. import ec.qa.autotest.ui.utility.PropertiesUtil;  
  13.   
  14. /**  
  15.  * @author xin.wang 供应商门户网站测试基类  
  16.  */  
  17. public class SupplierPortalTestBase extends TestBase {  
  18.     @BeforeMethod(alwaysRun = true)  
  19.     public void initDriver(ITestContext tc, Method m, XmlTest xt) throws Exception {  
  20.         ConfigDriverParameters cp = new ConfigDriverParameters();  
  21.         cp.setPageLoadTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.SUPPLIER_PORTAL_PAGELOAD_TIME)));  
  22.         cp.setTargetWebSite(PropertiesUtil.getProValue(PropertiesKeys.SUPPLIER_PORTAL_AUTO_TEST_WEBSITE));  
  23.         cp.setSerachElementTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.IMPLICITLYWAIT_TIME)));  
  24.         cp.setTestMethod(m);  
  25.         preCondition(cp);  
  26.     }  
  27.   
  28.     @AfterSuite(alwaysRun = true)  
  29.     public void terminTestSuite(XmlTest xt, ITestContext tc) {  
  30.         CookiesUtil.setCk(null);  
  31.     }  
  32.   
  33.     public void beforeClass(XmlTest xt, ITestContext tc) {  
  34.         // TODO Auto-generated method stub  
  35.   
  36.     }  
  37.   
  38.     public void afterClass(XmlTest xt, ITestContext tc) {  
  39.         // TODO Auto-generated method stub  
  40.   
  41.     }  
  42.   
  43.     public void beforeTest(XmlTest xt, ITestContext tc) {  
  44.         // TODO Auto-generated method stub  
  45.   
  46.     }  
  47.   
  48.     public void afterTest(XmlTest xt, ITestContext tc) {  
  49.         // TODO Auto-generated method stub  
  50.   
  51.     }  
  52. }  

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package ec.qa.autotest.ui.testbase.impl;  
  2.   
  3. import java.lang.reflect.Method;  
  4. import org.openqa.selenium.support.PageFactory;  
  5. import org.testng.ITestContext;  
  6. import org.testng.annotations.AfterSuite;  
  7. import org.testng.annotations.BeforeMethod;  
  8. import org.testng.xml.XmlTest;  
  9.   
  10. import ec.qa.autotest.ui.admin.portal.pageobject.AdminPortalLoginPage;  
  11. import ec.qa.autotest.ui.constants.PropertiesKeys;  
  12. import ec.qa.autotest.ui.utility.PropertiesUtil;  
  13.   
  14. /**  
  15.  * @author xin.wang  
  16.  * 供应商后台管理网站测试基类  
  17.  */  
  18. public class AdminPortalTestBase extends TestBase {  
  19.       
  20.     @BeforeMethod(alwaysRun = true)  
  21.     public void initDriver(ITestContext tc, Method m, XmlTest xt) throws Exception {  
  22.         ConfigDriverParameters cp = new ConfigDriverParameters();  
  23.         cp.setPageLoadTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.ADMIN_PORTAL_PAGELOAD_TIME)));  
  24.         cp.setTargetWebSite(PropertiesUtil.getProValue(PropertiesKeys.ADMIN_PORTAL_AUTO_TEST_WEBSITE));  
  25.         cp.setSerachElementTime(Long.parseLong(PropertiesUtil.getProValue(PropertiesKeys.IMPLICITLYWAIT_TIME)));  
  26.         cp.setTestMethod(m);  
  27.         preCondition(cp);  
  28.         AdminPortalLoginPage ecHomePage = PageFactory.initElements(TestBase.getWebDriver(), AdminPortalLoginPage.class);  
  29.         ecHomePage.loginAdminPortal("admin", "111111");  
  30.     }  
  31.       
  32.     @AfterSuite  
  33.     public void terminTestSuite(XmlTest xt, ITestContext tc) throws Exception {  
  34.         // TODO Auto-generated method stub  
  35.           
  36.     }  
  37.   
  38.     public void beforeClass(XmlTest xt, ITestContext tc) throws Exception {  
  39.         // TODO Auto-generated method stub  
  40.           
  41.     }  
  42.   
  43.     public void afterClass(XmlTest xt, ITestContext tc) throws Exception {  
  44.         // TODO Auto-generated method stub  
  45.           
  46.     }  
  47.   
  48.     public void beforeTest(XmlTest xt, ITestContext tc) throws Exception {  
  49.         // TODO Auto-generated method stub  
  50.           
  51.     }  
  52.   
  53.     public void afterTest(XmlTest xt, ITestContext tc) throws Exception {  
  54.         // TODO Auto-generated method stub  
  55.           
  56.     }  
  57. }  



c.@FindBy是个什么东西?

FindyBySelenium框架的维护的一自定义标签,用来标示定位页面元素的方式一般来说你不需要更新它 

@AutoInject @PageObject 参看  http://blog.csdn.net/wangxin1982314/article/details/50221641

c   @PageObject (测试框架实现)

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1.     import java.lang.annotation.Documented;  
  2. import java.lang.annotation.ElementType;  
  3. import java.lang.annotation.Retention;  
  4. import java.lang.annotation.RetentionPolicy;  
  5. import java.lang.annotation.Target;  
  6.   
  7.   
  8. /** 
  9.  * @author xin.wang 
  10.  * @see 标识当前类是否是页面对象 
  11.  */  
  12. @Target(ElementType.TYPE)  
  13. @Retention(RetentionPolicy.RUNTIME)  
  14. @Documented  
  15. public @interface PageObject {  
  16.     boolean lazyLoad() default false;  
  17. }  

c   @AuotInject(测试框架实现)

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. import java.lang.annotation.Documented;  
  2. import java.lang.annotation.ElementType;  
  3. import java.lang.annotation.Retention;  
  4. import java.lang.annotation.RetentionPolicy;  
  5. import java.lang.annotation.Target;  
  6.   
  7. /** 
  8.  * @author xin.wang 
  9.  * 自动装配标签 
  10.  */  
  11. @Target(ElementType.FIELD)  
  12. @Retention(RetentionPolicy.RUNTIME)  
  13. @Documented  
  14. public @interface AutoInject {  
  15.     boolean enable() default true;  
  16. }  


目前框架实现的一些功能请查看一下博文(随时更新):

使用工厂方法生产不同浏览器的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





0 0
原创粉丝点击