在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、 實踐中遇到的問題
一、 沒法判斷「收藏成功的按鈕是否呈亮」。你們要是知道判斷方法的話,請私信告訴我,謝謝!
二、 若你們以爲我寫的代碼存在問題,那也能夠私信告訴我,我會很樂意地接受你的建議的。謝謝!