2023年11月11日参加了软件测试大赛的省赛。阅读了我的导师杨贵福老师的文章后,将测试”凤凰网“网站的测试代码抽象成动作序列(把动作放在一个数组中,并且支持从前向后遍历,因此称为动作序列)。杨老师文章的地址为杨贵福 | 抽象与权衡:用appium打卡百词斩和扇贝 - 知乎。
根据测试要做的动作,为ActionType枚举类增加枚举常量,如下所示。
enum ActionType{
get,
sleep,
maximize,
click,
switchTo,
sendKeys
};
根据定位元素的方式,为ElementType枚举类增加枚举常量,如下所示。
enum ElementType{
xpath,
linkText
};
为Act类编写数据成员和构造函数。
数据成员有
actionType,代表Act要做的动作;
elementType,代表Act动作定位元素的方式;
link,元素定位的值;
text,对输入框输入的值或对Act的说明。
ActionType actionType;
ElementType elementType;
String link;
String text;
在Act类中设置3个构造函数,分别为
有4个参数的构造函数,用于为输入框输入文字,需要指定动作和定位元素的方式,给出元素定位的值和输入文字;
有3个参数的构造函数和2个参数的构造函数,用于不需要定位元素的操作,例如sleep操作和get操作;
public Act(ActionType actionType, ElementType elementType, String link, String text) {
this.actionType = actionType;
this.elementType = elementType;
this.link = link;
this.text = text;
}
public Act(ActionType actionType, String link) {
this.actionType = actionType;
this.link = link;
}
public Act(ActionType actionType,String link, String text) {
this.actionType = actionType;
this.link = link;
this.text = text;
}
选择用数组的方式来实现动作序列。
新建Execute类,在Execute类中初始化动作序列的数组actseq并调用runAction()方法遍历数组中的动作并执行。(runAction()方法的功能会在后面讲到。)
Act[] actseq = {
new Act(Act.ActionType.get, "https://www.ifeng.com/"),
new Act(Act.ActionType.maximize, " "),
new Act(Act.ActionType.sleep," ", "15000"),
//资讯
new Act(Act.ActionType.click, Act.ElementType.linkText, " ", "资讯"),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//新时代
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[1]/div[4]/ul/li[1]/a",""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//更多新闻
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[1]/div/div[1]/div[4]/div[2]/div/div[2]/div[21]/a",""),
new Act(Act.ActionType.sleep," ","1000"),
//置顶
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[2]",""),
new Act(Act.ActionType.sleep," ","1000"),
//凤凰资讯
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[1]/div/div[1]/div[2]/div/div[1]/div[3]/a[2]",""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//科技
new Act(Act.ActionType.sendKeys, Act.ElementType.xpath, "/html/body/div[1]/div[3]/div[3]/div[2]/input", "科技"),
new Act(Act.ActionType.sleep," ","1000"),
//放大镜
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[1]/div[3]/div[3]/div[3]/button",""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//第一条
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div/div[2]/div[3]/div[2]/ul/li[1]/div/h2/a",""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//现场直击
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[1]/div/div[3]/div[1]/div/div[2]/span",""),
new Act(Act.ActionType.sleep," ","1000"),
//第一条
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[1]/div/div[3]/div[2]/div[2]/div[2]/div[2]/div/div[1]/div[2]/p[1]/a",""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//人参与
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div[1]/div/div[2]/div[1]/div[2]/div[1]/div[1]/div[1]/div/div[2]/h5/a[1]/span[2]",""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//点击回复
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div/div[3]/div[2]/div[1]/div[2]/div[5]/div[2]/div[1]/div/div[2]/span[1]/a[2]",""),
new Act(Act.ActionType.sleep," ","1000"),
//发表评论
new Act(Act.ActionType.click, Act.ElementType.xpath,"/html/body/div/div[3]/div[2]/div[1]/div[2]/div[5]/div[2]/div[1]/div/div[3]/div[1]/form/div[2]/a",""),
new Act(Act.ActionType.sleep," ","1000"),
//手动关弹窗
new Act(Act.ActionType.sleep," ","2000"),
//优秀
new Act(Act.ActionType.sendKeys, Act.ElementType.xpath, "/html/body/div/div[3]/div[2]/div[1]/div[2]/div[5]/div[2]/div[1]/div/div[3]/div[1]/form/div[1]/textarea", "优秀"),
new Act(Act.ActionType.sleep," ","1000"),
//箭头
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div/div[3]/div[2]/div[1]/div[2]/div[5]/div[2]/div[1]/div/div[3]/div[1]/form/div[2]/div/div/a/span", ""),
new Act(Act.ActionType.sleep," ","1000"),
//表情
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div/div[3]/div[2]/div[1]/div[2]/div[5]/div[2]/div[1]/div/div[3]/div[1]/form/div[2]/div/div/div[2]/div/div[2]/ul/li[20]/img", ""),
new Act(Act.ActionType.sleep," ","1000"),
//置顶
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div/div[3]/div[2]/div[4]/div/a[2]", ""),
new Act(Act.ActionType.sleep," ","1000"),
//凤凰网首页
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div/div[2]/div/span[1]/a[1]", ""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//视频
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div[1]/div/div[3]/div/ul/li[3]/a", ""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//更多
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div[1]/div/header/div/div[1]/div[12]", ""),
new Act(Act.ActionType.sleep," ","1000"),
//美食
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div[1]/div/header/div/div[2]/div/ul/li[2]/a", ""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//第二个视频
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div/div[4]/div[1]/div[2]/a/div/img", ""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//频道
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div[1]/div[3]/div/div[2]/div[1]", ""),
new Act(Act.ActionType.sleep," ","1000"),
//凤凰首页
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div[1]/div[3]/div/div[2]/div[2]/div/a[2]", ""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//名字
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div[1]/div/div[2]/div[2]/div[2]/div[4]/div/div[2]/span/span", ""),
new Act(Act.ActionType.sleep," ","1000"),
//个人中心
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div[1]/div/div[2]/div[2]/div[2]/div[4]/div/div[2]/ul/li/a", ""),
new Act(Act.ActionType.sleep," ","1000"),
new Act(Act.ActionType.switchTo," "),
//注销
new Act(Act.ActionType.click, Act.ElementType.xpath, "/html/body/div/div/div[1]/div/div/a[3]", ""),
new Act(Act.ActionType.sleep," ","1000"),
};
runAction(actseq);
}
runAction()方法的功能为
1.遍历动作序列的数组;
2.执行遍历到的动作。
代码如下所示。
private static void runAction(Act[] acts) throws Exception{
WebDriver driver = new ChromeDriver();
for(Act act : acts) {
switch(act.actionType){
case get:
driver.get(act.link);
break;
case maximize:
driver.manage().window().maximize();
break;
case sleep:
Thread.sleep(Integer.valueOf(act.text));
break;
case click:
switch(act.elementType) {
case xpath:
driver.findElement(By.xpath(act.link)).click();
break;
case linkText:
driver.findElement(By.linkText(act.text)).click();
break;
default:
break;
}
break;
case sendKeys: driver.findElement(By.xpath(act.link)).sendKeys(act.text);
break;
case switchTo: driver.switchTo().window(driver.getWindowHandles().toArray()[len].toString());
len++;
default:
break;
}
}
}
成功运行了每一步测试的动作。
测试结果如本账号所发布的视频“测试‘凤凰网’网站功能”的视频所示。
测试”凤凰网“网站功能
a.成功将测试“凤凰网”的代码抽象为动作序列的数组;
b.抽象后的代码更简洁;
c.当测试其他网站时可以减少工作量。
感谢我的导师杨老师对我提出将代码抽象的建议,减少了工作量;感谢他为我提供的文章,为我将代码抽象提供了思路。