您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
自动化测试平台方案可行性探索
 
   次浏览      
 2018-6-28
 

 

编辑推荐:

本文来自于简书,本文主要介绍了需求分析,方案设想,核心代码的基础父类,PageObject具体实现类等。

1.需求分析

随着产品规模不断完善,功能模块逐渐增加,传统的人工测试逐步变得低效。为了提高测试效率,可以将简单的功能测试点交由自动化执行,让测试人员可以空出更多的时间去关注业务,流程。而传统的自动化测试脚本由于维护性差,成本高,收益低等因素导致难以有效的推行。而测试平台化规划好的话能将业务与代码的耦合度降低,有利于后期维护与可持续集成。

2.方案设想

所有数据均保存在数据库中,提供Web页面进行操作,其中

1.页面数据:源自PageObject设计模式,具体表现形式为一个页面一项数据,以米多来发管理后台登录页为例:

2.自定义方法:平台提供浏览器基础操作并提供功能用以保存测试人员自定义的方法,例如:

平台提供基础的点击元素以及向元素输入信息基础功能。结合页面数据保存登录页的自定义方法向用户名输入框中输入用户名,向密码输入框中输入密码,向验证码输入框中输入验证码,点击登录按钮等。后续通过关键字驱动进行调用。

3.自定义类方法:自定义方法并不能解决所有的需求,有些复杂的逻辑时,上述的方式并不适用,所以需要通过类中实现逻辑方法并提供给外界调用。例如需求:在一个table中需要通过判断某元素的内容,符合预期后再进行操作

以上三种结合起来生成测试用例。并与测试数据形成测试用例集(关键字驱动以及数据驱动相结合的混合驱动模式)再通过所选用配置最终形成自动化执行的测试脚本。(配置:解决测试用例运行环境,浏览器等相关问题)然后交给执行引擎执行并且输出测试报告

3.核心代码

1.基础父类

/**
* 基础父类,所有PageObject类均继承该类
*
* @author miduo
*
*/
public class Page {
private WebDriver driver;
public Page (WebDriver driver) {
super();
this.driver = driver;
if (this.driver != null) {
this.driver.manage(). window().maximize();
}
}
public WebDriver getDriver() {
return driver;
}
@Auto(key = "click")
public void click (String locator) { findElement(locator).click(); }
@Auto(key = "input")
public void input(String locator, String value) {
findElement(locator). sendKeys(value); }
@Auto (key = "open")
public void open(String url) {
driver.get(url); }
/**
* 通过反射获取类自定义方法
*
* @param key
* @return
*/
protected Method getCustomMethodByKey (String key) {
Method[] methods = getClass() .getMethods();
for (Method method : methods) {
Auto autoKey = method. getAnnotation(Auto.class);
if (autoKey != null && autoKey.key().equals(key)) {
return method;
}
}
return null;
}
protected final WebElement findElement(String locator) {
int index = locator.indexOf(".");
String type = locator.substring(0, index). toLower Case ();
String value = locator.substring(index + 1);
switch (type) {
case "id":
return findElement (By.id(value));
case "name":
return findElement (By.name(value));
case "css":
return findElement (By.cssSelector(value));
case "xpath":
return findElement (By.xpath(value));
case "class":
return findElement (By.className(value));
case "tag":
return findElement (By.tagName(value));
case "link":
return findElement (By.partialLinkText(value));
default:
return null; } }
private final WebElement findElement(By by) {
return new WebDriverWait(driver, 10).until( new ExpectedCondition <WebElement> () {
@Override
public WebElement apply (WebDriver d) {
return d.findElement(by); }
}); } }

2.PageObject具体实现类

public class LoginPage extends Page {
public LoginPage(WebDriver driver) {
super(driver);
}
/**
* PageObject自定义类方法:登录
*
* @param userName
* @param password
* @param captcha
*/
@Auto(key = "login")
public void login(String userName, String password , String captcha ) {
input( "id.Account", userName);
input( "id.Password", password);
input( "id.Captcha", captcha);
click("xpath. //input [ @type ='submit']"); } }

3.自定义方法

public class Step {
private Class<? extends Page> clazz;
private String methodKey;
private Object value;
public Step () { super();
}
public Step(Class<? extends Page> clazz, String methodKey, Object value ) {
super();
this.clazz = clazz == null ? Page.class : clazz;
this.methodKey = methodKey;
this.value = value; }
public Class<? extends Page> getClazz() {
return clazz;
}
public void setClazz(Class<? extends Page> clazz) {
this.clazz = clazz;
}
public String getMethodKey() {
return methodKey;
}
public void setMethodKey(String methodKey) {
this.methodKey = methodKey;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value; } }

4.测试用例以及测试数据

public class TestCase {
private ArrayList<Step> steps;
public TestCase() {
super();
this.steps = new ArrayList<>(); }
public ArrayList<Step> getSteps() {
return steps; }
public void setSteps(ArrayList<Step> steps) {
this.steps = steps; }
public void addStep(Step step) {
this. steps.add(step); }
public Result perform(WebDriver driver, Parameter parameter) {
Result result = new Result();
for (Step step : steps) {
Object[] value = step.getValue();
Object[] coValue = new
Object [value.length];
Boolean change= false;
if (parameter != null) {
for (int i = 0; i < value.length; i++) {
String key = value[i].toString();
coValue[i] = key;
if (key.startsWith("${") && key.endsWith("}")) {
change= true;
Object v = parameter.get(key.substring(2, key.length() - 1));
value[i] = v == null ? value[i] : v; } } }
if (!step.perform(driver, value)) {
result.setResult(false);
return result; }
if (change) {
step.setValue(coValue); } }
result.setResult(true);
return result; } }
public class Parameter {
private Map<String, Object> parameter;
public Parameter() {
super();
this.parameter = new HashMap<>(); }
public void add(String key, Object value) {
this.parameter.put(key, value); }
public void remove(String key) {
this.parameter.remove(key); }
public Object get(String key) {
return this.parameter.get(key); } }

5.执行引擎

public class Runner {
public static List <Result> perform(TestCase test Case, List <Parameter> testData) {
List <Result> list = new ArrayList<>();
System.out.println (testData.size());
if (testData != null && testData.size() > 0) {
for (Parameter parameter : testData) {
// 实例化何种浏览器与打开什么环境由配置决定,在此不实现
System.setProperty ("webdriver.chrome.driver",
System.getProperty ("user.dir") + "// chromedriver .exe ");
WebDriver driver = new ChromeDriver();
driver.get("http://*********保密********");
list.add(testCase.perform(driver, parameter)); } } else {
System.setProperty("webdriver.chrome.driver", System .getProperty ("user.dir") + "// chromedriver .exe" );
WebDriver driver = new ChromeDriver ();
driver.get ("http://*********保密********");
list.add(testCase.perform(driver, null)); } return list; } }

代码仅作为可行性分析使用,并非最终版本。

测试代码

public class Test {
private static List<Parameter> parameters;
static {
Parameter parameter = new Parameter();
parameter.add("userName", "userName_01");
parameter.add("password", "password_01");
parameter.add("captcha", "captcha_01");
Parameter paramete1r = new Parameter();
paramete1r.add("userName", "userName_02");
paramete1r.add("password", "password_02");
paramete1r.add("captcha", "captcha_02");
parameters = new ArrayList<>(); parameters.add(parameter);
parameters.add(paramete1r);
}
//通过用户自定义保存方法运行
@org.testng.annotations.Test
public void test1() {
TestCase tc = new TestCase();
tc.addStep(new Step(null, "input", "id.Account", "${userName}")); tc.addStep(new Step(null, "input", "id.Password", "${password}"));
tc.addStep(new Step(null, "input", "id.Captcha", "$ {captcha} "));
tc.addStep(new Step(null, "click", "xpath.//input [@type ='submit'] "));
Runner.perform (tc, parameters); }
//通过自定义类方法运行
@org.testng.annotations.Test
public void test2() {
TestCase tc = new TestCase();
tc.addStep (new Step( LoginPage.class, "login", "$ {userName}", "${ password}", "$ {captcha}"));
Runner .perform(tc, parameters); } }

代码执行效果

再通过一个配置文件或者数据库存储PageObject类的路径,即可通过纯数据进行驱动测试运行,后续再持续完善用户,任务,结果等相关模块即可打造较为完善的自动化测试平台,如此一来,测试人员仅需在平台中编辑测试用例与测试数据并新建相关测试任务即可。测试用例以及测试数据的格式为:

   
次浏览       
相关文章

微服务测试之单元测试
一篇图文带你了解白盒测试用例设计方法
全面的质量保障体系之回归测试策略
人工智能自动化测试探索
相关文档

自动化接口测试实践之路
jenkins持续集成测试
性能测试诊断分析与优化
性能测试实例
相关课程

持续集成测试最佳实践
自动化测试体系建设与最佳实践
测试架构的构建与应用实践
DevOps时代的测试技术与最佳实践