在APP发展普遍的社会上,咱们测试人员的测试技能也要跟着进步,对面APP的测试,每次都要快速上线新版本的迭代测试中,测试人员每次都要作不少次的回归测试,让人以为好疲累。对面这种状况,如今使用Appium来作自动化测试,能够帮助测试人员可以准确快速地作不少次回归测试啦!java
Appium的环境搭建和配置,在本文我就很少说了,具体请详见个人博文“Appium的环境搭建和配置” 。android
今天整理下,之前用开源中国APP当练手项目的实践经验,在环境搭建好的前提下,大概包括如下几方面:git
1、测试用例的设计apache
写测试用例前,先要了解APP的全部功能模块,明确测试范围,肯定测试用例的颗粒度。app
假如测试项目的测试时间比较紧迫,通常都是建议重点先测试用户使用频率比较高的基本功能点。框架
假如测试项目的测试时间比较充裕,那测试用例的颗粒度能够作到最小,把覆盖面扩大到全部功能点上。ide
根据我对开源中国APP的功能了解,大概设计了部分测试用例,可见下图或码云上的测试用例文件。测试
2、代码测试框架的设计ui
个人设计是这样的this
一、 每一个测试用例,写一个测试TestCase文件。
二、 全部TestCase文件都会使用到的方法,写在一个BaseTest类里,由TestCase文件来继承使用。好比:启动Appium、截图。
三、 部分TestCase文件会使用到的方法,能够按功能点来建一个类,再调用。好比:登陆功能、注销功能、收藏结果比对。
四、 每一个TestCase文件均可以单独执行。
五、 也能够把全部TestCase文件放到XML文件里,运行TestNG Suite,批量执行测试用例。
3、源代码
源代码,只涉及到安卓机的,可见下图,也能够详见源代码(已上传码云)。
如下是“综合-开源资讯-收藏”测试用例,OscLoginNewsCollection类,源代码以下:
package com.appium.osc; import java.io.File; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.Assert; import org.testng.Reporter; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import io.appium.java_client.AppiumDriver; import io.appium.java_client.MobileElement; import io.appium.java_client.android.AndroidDriver; public class OscLoginNewsCollection extends BaseTest { private AppiumDriver<MobileElement> driver; @BeforeClass public void setUp() throws Exception { driver = this.getAppiumParameter(); } @Test(description = "综合-开源资讯-收藏成功") public void LoginNewsCollection() throws InterruptedException { this.screenshot("LoginNewsCollection1.jpg", driver); // 登陆 OscLogin Login = new OscLogin(); Login.login(driver); this.screenshot("LoginNewsCollection2.jpg", driver); // 点击【综合】 WebElement itemMe = driver.findElement(By .id("net.oschina.app:id/nav_item_news")); itemMe.click(); // 点击【开源资讯】 WebElement layoutView = driver.findElement(By .id("net.oschina.app:id/layout_tab")); WebElement linearLayout = layoutView.findElement(By .className("android.widget.LinearLayout")); List<WebElement> support = linearLayout.findElements(By .className("android.support.v7.a.a$f")); WebElement supportText = support.get(0); supportText.click(); // 等待30秒内寻找这个元素 (new WebDriverWait(driver,20)).until( new ExpectedCondition<MobileElement>(){ @Override public MobileElement apply(WebDriver d) { MobileElement recyclerView = driver.findElement(By .id("net.oschina.app:id/recyclerView")); List<MobileElement> titleView = recyclerView.findElements(By .id("net.oschina.app:id/ll_title")); if(titleView.size()>0){ MobileElement textView=titleView.get(0); return textView; } return null; } }); //进入开源资讯列表界面后截图 this.screenshot("LoginNewsCollection3.jpg", driver); // 点击资讯标题 MobileElement recyclerView = driver.findElement(By .id("net.oschina.app:id/recyclerView")); List<MobileElement> titleView = recyclerView.findElements(By .id("net.oschina.app:id/ll_title")); // String titleText = ""; for(int i=0;i<titleView.size();i++){ MobileElement textView=titleView.get(i); MobileElement lay_info = textView.findElement(By.id("net.oschina.app:id/lay_info")); if(lay_info != null){ MobileElement subTextView = textView.findElement(By .id("net.oschina.app:id/tv_title")); String titleText = subTextView.getText().substring(7); System.out.println("=====列表标题:" + titleText ); subTextView.click(); break; } } //进入详情页面 MobileElement actionBar = driver.findElement(By.id("net.oschina.app:id/action_bar")); MobileElement actionBarTexts = actionBar.findElement(By.className("android.widget.TextView")); String actionBarText = actionBarTexts.getText(); System.out.println("=====进入" + actionBarText); // 等待30秒内寻找这个元素 (new WebDriverWait(driver,30)).until( new ExpectedCondition<MobileElement>(){ @Override public MobileElement apply(WebDriver d) { MobileElement lay_container = driver.findElement(By .id("net.oschina.app:id/lay_container")); return lay_container; } }); //打印详情页面的标题 String inforDetailsTitle = ""; if(actionBarText.equals("软件详情") == true){ MobileElement tv_software_name = driver.findElement(By .id("net.oschina.app:id/tv_software_name")); inforDetailsTitle = tv_software_name.getText().substring(13); System.out.println("=====详情标题:" + inforDetailsTitle); }else if(actionBarText.equals("问答详情") == true){ MobileElement tv_ques_detail_title = driver.findElement(By .id("net.oschina.app:id/tv_ques_detail_title")); inforDetailsTitle = tv_ques_detail_title.getText(); System.out.println("=====详情标题:" + inforDetailsTitle); }else{ MobileElement tv_title = driver.findElement(By .id("net.oschina.app:id/tv_title")); inforDetailsTitle = tv_title.getText(); System.out.println("=====详情标题:" + inforDetailsTitle); } // 进入开源资讯详情界面后截图 this.screenshot("LoginNewsCollection4.jpg", driver); // 收藏成功 WebElement collectionLinear = driver.findElement(By .className("android.widget.LinearLayout")); WebElement clickCollection = collectionLinear.findElement(By .id("net.oschina.app:id/ib_fav")); clickCollection.click(); //刷新页面等待3秒 try{ Thread.sleep(3000); } catch(Exception e){ e.printStackTrace(); } // 收藏成功截图 this.screenshot("LoginNewsCollection5.jpg", driver); // 从博客详情返回综合列表 WebElement returnButton = driver.findElement(By .id("net.oschina.app:id/action_bar")); WebElement clickButton = returnButton.findElement(By .className("android.widget.ImageButton")); clickButton.click(); this.screenshot("LoginNewsCollection6.jpg", driver); // 检测收藏标题是否存在于个人收藏列表中 OscCollectionResultAssert ResultAssert = new OscCollectionResultAssert(); ResultAssert.CollectionResultAssert(driver, inforDetailsTitle); // 进入个人收藏列表后截图 this.screenshot("LoginNewsCollection7.jpg", driver); Reporter.log("综合-开源资讯-登陆-收藏"); // 从个人收藏列表返回到我的信息页面 MobileElement returnButton2 = driver.findElement(By .id("net.oschina.app:id/action_bar")); MobileElement clickButton2 = returnButton2.findElement(By .className("android.widget.ImageButton")); clickButton2.click(); this.screenshot("LoginNewsCollection8.jpg", driver); // 注销 OscCancellation Cancellation = new OscCancellation(); Cancellation.Cancellation(driver); this.screenshot("LoginNewsCollection9.jpg", driver); } @AfterClass public void tearDown() throws Exception { driver.quit(); } }
4、测试报告
把全部TestCase文件放到XML文件里,运行TestNG Suite,批量执行测试用例。
如下是“综合-开源资讯-收藏”单个执行测试报告:
如下是“综合-开源资讯-收藏”单个执行的总测试报告以下图所示:
5、 测试过程当中屏幕截图
在测试过程当中屏幕截图也是很重要,它能够协助你排查问题。
如下是测试OscLoginNewsCollection类的屏幕截图gif文件:
6、 实践中遇到的问题
一、 没法判断“收藏成功的按钮是否呈亮”。你们要是知道判断方法的话,请私信告诉我,谢谢!
二、 若你们以为我写的代码存在问题,那也能够私信告诉我,我会很乐意地接受你的建议的。谢谢!