Selenium自动化测试在PageObject下的架构与测试报告生成

Selenium由于其适用多种语言(本文使用的语言为java),在自动化测试领域中的使用用越来越多。使用Selenium的方式有很多,能使用的工具也很多。PageObject模式的使用提高了测试代码的可读性与可维护性,同时一定程度减少了测试代码量,降低了测试用例与测试功能间的耦合程度。

目前遇到的问题:

(1)Selenium自动化测试大部分的操作都由WebDriver完成,比如在进行一次点击操作时,首先要获取Dom元素(dom元素的获取方法有很多,详见API即可),然后再调用点击的方法,每一步都要进行获取再执行的操作多有冗余。                                                                                                                                                                                                                      

(2)在编写测试用例时,需要初始化WebDriver,对于WebDriver的初始化在每一个页面的测试case类里都要编写一次,这里也存在冗余。


(3)如何控制两步操作间的执行时间。

对于问题(1)代码冗余的问题,笔者将WebDriver中的方法重新包装了一遍。

定义接口WebDriverWrapper

package com.test.sahagin.wrapper;

import org.openqa.selenium.WebElement;

public interface WebDriverWrapper {
	
	/**
	 * 根据标签ID获取 标签元素
	 * @param id
	 * @return
	 */
    WebElement getElementById(String id);
    
	/**
	 * 根据标签name获取 标签元素
	 * @param name
	 * @return
	 */
	WebElement getElementByName(String name);
	
	/**
	 * 根据标签className获取 标签元素
	 * @param className
	 * @return
	 */
	 WebElement getElementByClassName(String className);
	 
	/**
	 * 根据标签Css 选择器获取 标签元素
	 * @param selector
	 * @return
	 */
	 WebElement getElementByCssSelector(String selector);
	 
	/**
	 * 根据标签标签名称获取 标签元素
	 * @param tagName
	 * @return
	 */
     WebElement getElementByTagName(String tagName);
	
	//******************点击操作********************//
	
	void clickByJs(String id);
	
    void clickById(String id);
	
	void clickByName(String name);
	//*****************情空操作********************//
	void clearById(String id);
	
	//*****************赋值操作*******************//
	void sendKeysById(String id, String content);
	
	
	//*****************执行js操作*****************//
	void executeJsById(String id, String js);
	
	void executeJs(String js);
	/**
	 * 选择复选框进行赋值
	 * @param formId
	 * @param tagName
	 * @param value
	 */
	void selectCheckBox(String tagName, String value[]);
	
	
	/**
	 * 通过下拉框option的text内容选择下拉框选项
	 * @param selectId  下拉框ID
	 * @param text 下拉框选项内容
	 */
	void selectDropDownListByText(String selectId, String text);
	
	/**
	 * 通过下拉框option的value内容选择下拉框选项
	 * @param selectId  下拉框ID
	 * @param value 下拉框选项值
	 */
	void selectDropDownListByValue(String selectId, String value);
	
	/**
	 * 通过下拉框option的索引内容选择下拉框选项
	 * @param selectId  下拉框ID
	 * @param value 下拉框选项值
	 */
	void selectDropDownListByIndex(String selectId, int index);
}


定义实现:WebDriverWrapperImpl                 

package com.test.sahagin.wrapper;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

public final class WebDriverWrapperImpl implements WebDriverWrapper{
	
	private WebDriver webDriver;

	public WebDriverWrapperImpl(WebDriver webDriver) {
		super();
		this.webDriver = webDriver;
	}
	
	/**
	 * 根据标签ID获取 标签元素
	 * @param id
	 * @return
	 */
	public WebElement getElementById(String id) {
		return webDriver.findElement(By.id(id));
	}
	
	/**
	 * 根据标签name获取 标签元素
	 * @param name
	 * @return
	 */
	public WebElement getElementByName(String name) {
		return webDriver.findElement(By.name(name));
	}
	
	/**
	 * 根据标签className获取 标签元素
	 * @param className
	 * @return
	 */
	public WebElement getElementByClassName(String className) {
		return webDriver.findElement(By.className(className));
	}
	
	/**
	 * 根据标签Css 选择器获取 标签元素
	 * @param selector
	 * @return
	 */
	public WebElement getElementByCssSelector(String selector) {
		return webDriver.findElement(By.cssSelector(selector));
	}
	
	/**
	 * 根据标签标签名称获取 标签元素
	 * @param tagName
	 * @return
	 */
	public WebElement getElementByTagName(String tagName) {
		return webDriver.findElement(By.tagName(tagName));
	}
	
	
	public List<WebElement> getElementByPath(String path) {
		return webDriver.findElements(By.xpath(path));
	}
	
	//******************点击操作********************//
	
	public void clickByJs(String id) {
		executeJsById(id,"arguments[0].click()");
	}
	
	public void clickById(String id) {
		this.getElementById(id).click();
	}
	
	public void clickByName(String name) {
		this.getElementByName(name).click();
	}
	
	//*****************情空操作********************//
	public void clearById(String id) {
		this.getElementById(id).clear();
	}
	
	
	//*****************赋值操作*******************//
	public void sendKeysById(String id, String content) {
		this.clearById(id);
		this.getElementById(id).sendKeys(content);;
	}
	
	
	//*****************执行js操作*****************//
	public void executeJsById(String id, String js) {
		WebElement ele = this.getElementById(id);
		((JavascriptExecutor)webDriver).executeScript(js, ele);
	}
	
	@Override
	public void executeJs(String js) {
		((JavascriptExecutor)webDriver).executeAsyncScript(js);
		
	}

	@Override
	public void selectCheckBox(String tagName, String[] value) {
//		List<WebElement> eles = this.getElementByPath("//*[@id='" + formId + "']/**/input[@name='"+ tagName +"']");
		List<WebElement> eles = webDriver.findElements(By.name(tagName));
		if (eles != null) {
			for (WebElement ele : eles) {
				for (int i = 0; i < value.length; i ++) {
					WebElement ch = ele.findElement(By.xpath("/following-sibling::span[2]"));
					if (ch != null && ch.getText().equals(value[i]))
						ele.click();
				}
			}
		}
	}

	
	@Override
	public void selectDropDownListByText(String selectId, String text) {
		Select select = new Select(getElementById(selectId));
		select.selectByVisibleText(text);
	}

	@Override
	public void selectDropDownListByValue(String selectId, String value) {
		Select select = new Select(getElementById(selectId));
		select.selectByValue(value);
	}

	@Override
	public void selectDropDownListByIndex(String selectId, int index) {
		// TODO Auto-generated method stub
		Select select = new Select(getElementById(selectId));
		select.selectByIndex(index);
	}

	
	
	
}


这样在执行页面操作时,调用里面的方法就可以了。并且使用PageObject模式 之前注入的是WebDriver,现在需要注入WebDriverWrapper。再新建一个PageObject类时,可以直接继承BaseTestPage

package com.test.pages;

import org.sahagin.runlib.external.TestDoc;

import com.fujitsu.test.sahagin.wrapper.WebDriverWrapper;

public class BaseTestPage {
	protected WebDriverWrapper wd;

	public BaseTestPage() {
		super();
	}
	
	public BaseTestPage(WebDriverWrapper wd) {
		super();
		this.wd = wd;
	}
	//在这里可以添加页面共有的操作。
	@TestDoc("「管理メニュー」を押下する")
	public void clickManageMenu() {
		wd.clickByJs("managementMenu");
	}
	
	@TestDoc("「利用者一覧」を押下する")
	public void clickUserList() {
		wd.clickByJs("userList");
	}
	
	@TestDoc("「属性一覧」を押下する")
	public void clickAttributeList() {
		wd.clickByJs("attributeList");
	}
	
	@TestDoc("「共通公開範囲一覧」を押下する")
	public void clickPublishList() {
		wd.clickByJs("publishList");
	}
	
	@TestDoc("「案件書式一覧」を押下する")
	public void clickItemFormatList() {
		wd.clickByJs("itemFormatList");
	}
	
	@TestDoc("「案件ロック一覧」を押下する")
	public void clickItemLockList() {
		wd.clickByJs("itemLockList");
	}
}


对于问题(2)

首先写一个工具类用于初始化WebDriver。

package com.test.sahagin.util;

import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;

public class WebDriverUtil {
	
	private static WebDriverUtil webDriverUtil = new WebDriverUtil();
	
	private WebDriverUtil() {}
	
	public static WebDriverUtil getInstance() {
		return webDriverUtil;
	}
	
	public WebDriver initWebDriver() {
		DesiredCapabilities capabilities = configDesiredCapabilities();
		return new InternetExplorerDriver(capabilities);
	}
	
	private DesiredCapabilities configDesiredCapabilities() {
		DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
        capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);
        capabilities.setPlatform(Platform.WINDOWS);
        capabilities.setCapability("silent", true);
        capabilities.setCapability("ignoreZoomSetting", true);
		return capabilities;
	}

}

然后写一个BaseTestPage

package com.test.features;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.sahagin.runlib.external.adapter.webdriver.WebDriverAdapter;

import com.fujitsu.test.pages.LoginPage;
import com.fujitsu.test.pages.PageURL;
import com.fujitsu.test.sahagin.util.DynamicProxy;
import com.fujitsu.test.sahagin.util.WebDriverUtil;
import com.fujitsu.test.sahagin.wrapper.WebDriverWrapper;
import com.fujitsu.test.sahagin.wrapper.WebDriverWrapperImpl;

public class BaseTestPage {
	
	protected WebDriverWrapper webDriverWrapper;
		
	protected WebDriver webDriver;
	 
	protected String url;
	
	public void init() {
		webDriver = WebDriverUtil.getInstance().initWebDriver();
		webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);//搜索元素时超时时间
		webDriver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);//执行js脚本超时时间
		WebDriverWrapper realWebDriverWrapper = new WebDriverWrapperImpl(webDriver);
		
		InvocationHandler handler = new DynamicProxy(realWebDriverWrapper);
		webDriverWrapper = (WebDriverWrapper) Proxy.newProxyInstance(handler.getClass().getClassLoader(),
				realWebDriverWrapper.getClass().getInterfaces(), handler);//这里使用代理,作用于下文解释
	    WebDriverAdapter.setAdapter(webDriver);
	}
	//每个功能都要登录才能操作,免登陆的用法还没有实施。Cookie的用户不起作用
	public void login() {
		webDriver.get(PageURL.LOGINPAGEURL);//将所有的URL 放在PageUrl类中进行管理。

		LoginPage loginPage = new LoginPage(webDriverWrapper);
		
		loginPage.setUsername("ksl");
		
		loginPage.setPassword("/ksl");
		
		loginPage.send();
	}
	
	public void destory() {
		webDriver.quit();
	}
}

接下来每个页面测试继承BaseTestPage即可:

package com.fujitsu.test.features;


import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.fujitsu.test.pages.LoginPage;
import com.fujitsu.test.pages.PageURL;

public class TestLoginPage extends BaseTestPage{
	

	@Before
	public void initWd() {
		super.init();
	}
	
	@Test
	public void testLoginCorrect() {
		webDriver.get(PageURL.LOGINPAGEURL);

		LoginPage loginPage = new LoginPage(webDriverWrapper);
		
		loginPage.setUsername("ksl");
		
		loginPage.setPassword("/ksl");
		
		loginPage.send();
		
	}
    
	@Test
	public void testLoginInCorrect() {
		webDriver.get(url);

		LoginPage loginPage = new LoginPage(webDriverWrapper);
		
		loginPage.setUsername("ksl");
		
		loginPage.setPassword("/ksl");
		
		loginPage.send();
		
	}
	
	
	
	@After
	public void destoryWd() {
		webDriver.quit();
	}
}


对于问题三,不可再每个操作前加上Thread.sleep()方法,加上一个动态代理即可:

package com.test.sahagin.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import com.fujitsu.test.pages.PageURL;

public class DynamicProxy implements InvocationHandler {
	
	private Object subject;
	
	public DynamicProxy(Object subject) {
		super();
		this.subject = subject;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Thread.sleep(PageURL.SLEEPTIME);//每个方法执行前都会调用sleep方法。
		
		method.invoke(subject, args);
		return null;
	}
	
}

pom文件:

<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>com.fnst</groupId>
  <artifactId>test</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <properties>  
	   <sahagin.version>0.9.2</sahagin.version>  
  </properties>
  
  <dependencies>
		<dependency>
			<groupId>org.seleniumhq.selenium</groupId>
			<artifactId>selenium-java</artifactId>
			<version>2.53.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-exec -->
		<dependency>
		    <groupId>org.apache.commons</groupId>
		    <artifactId>commons-exec</artifactId>
		    <version>1.3</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-nop -->
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-nop</artifactId>
		    <version>1.7.23</version>
		</dependency>


		
		<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
		    <groupId>commons-io</groupId>
		    <artifactId>commons-io</artifactId>
		    <version>2.4</version>
		</dependency>
		
		<dependency>
			<groupId>com.opera</groupId>
			<artifactId>operadriver</artifactId>
		</dependency>
		
		<dependency>  
	     <groupId>org.sahagin</groupId>    
	      <artifactId>sahagin</artifactId>    
	      <version>${sahagin.version}</version>   
	   </dependency>
	   
	   <dependency>
	   	<groupId>junit</groupId>
	   	<artifactId>junit</artifactId>
	   	<version>4.11</version>
	   	<scope>test</scope>
	   </dependency>  	
	   
	   <dependency>
		    <groupId>net.lightbody.bmp</groupId>
		    <artifactId>browsermob-core</artifactId>
		    <version>2.1.4</version>
        	<scope>test</scope>
		</dependency>
	   
</dependencies>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>com.opera</groupId>
				<artifactId>operadriver</artifactId>
				<version>0.16</version>
				<exclusions>
					<exclusion>
						<groupId>org.seleniumhq.selenium</groupId>
						<artifactId>selenium-remote-driver</artifactId>
					</exclusion>
				</exclusions>
			</dependency>
		</dependencies>
	</dependencyManagement>
  
  
  <build>  
   <plugins>  
   	<plugin>   
   		<groupId>org.apache.maven.plugins</groupId>  
	    <artifactId>maven-compiler-plugin</artifactId>   
	    <version>2.5.1</version> 
	    <configuration>   
	        <source>1.7</source>   
	        <target>1.7</target>   
	        <encoding>UTF-8</encoding>   
	    </configuration>   
	</plugin>	
   		<plugin>   
		    <groupId>org.apache.maven.plugins</groupId>   
		    <artifactId>maven-resources-plugin</artifactId>   
		    <version>2.4</version>   
		    <configuration>   
		        <encoding>UTF-8</encoding>   
		    </configuration>   
		</plugin> 
     <plugin>  
       <groupId>org.apache.maven.plugins</groupId>  
       <artifactId>maven-surefire-plugin</artifactId>  
       <version>2.18 </version>  
       <configuration> 
       	  <forkCount>3</forkCount>
    	  <reuseForks>true</reuseForks>
          <argLine>  
           -javaagent:${settings.localRepository}/org/sahagin/sahagin/${sahagin.version}/sahagin-${sahagin.version}.jar  
          </argLine>  
          <useSystemClassLoader>true</useSystemClassLoader>
       </configuration>  
     </plugin>  
   </plugins>  
 </build>  
</project>



关于sahagin的使用见博客: http://blog.csdn.net/vichou_fa/article/details/54909812
  

                                                                                      

        关注微信公众号每天学习一点程序员的职业经

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Selenium是一个用于自动化Web浏览器的测试工具,它提供了一组API和库,可以用多种编程语言(如Python、Java、C#等)来编写自动化测试脚本。Selenium可以模拟用户在浏览器中的操作,如点击、输入文本、提交表单等,以及获取页面元素的属性和内容。 Selenium自动化测试套件包括以下几个主要组件: 1. Selenium WebDriver:WebDriver是Selenium的核心组件,它提供了与各种浏览器进行交互的API。通过WebDriver,可以启动浏览器、打开网页、执行操作并获取结果。 2. Selenium Grid:Grid允许同时在多个浏览器和操作系统上运行测试。它可以将测试任务分发给不同的节点,从而实现并行执行测试的能力。 3. Selenium IDE:IDE是一个浏览器插件,用于录制和回放用户在浏览器中的操作。它可以生成Selenium脚本,方便初学者快速入门。 4. Selenium Client Libraries:Selenium提供了多种编程语言的客户端库,如Python、Java、C#等。这些库可以与WebDriver进行交互,编写自动化测试脚本。 使用Selenium进行自动化测试时,一般的流程包括以下几个步骤: 1. 配置环境:安装相应的浏览器驱动程序,并配置好测试环境。 2. 创建WebDriver实例:根据需要选择合适的浏览器,创建对应的WebDriver实例。 3. 编写测试脚本:使用Selenium提供的API,编写测试脚本,包括打开网页、执行操作、获取结果等。 4. 运行测试脚本:执行测试脚本,Selenium会模拟用户在浏览器中的操作,并返回相应的结果。 5. 分析结果:根据测试结果进行分析和处理,如生成报告、记录日志等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值