Coding UI 測試的那些事兒

通常來講對一個網站作測試,最直接的方法就是用手點,眼睛看。用手點和眼睛看把網站的功能點都過一遍,好比在百度首頁的搜索框裏輸入 「coding」,點擊「百度一下」,用眼睛看會不會彈出有關 「coding」 的搜索頁面。不過,你點了2天以後就會發現,這些點擊和「眼睛確認」是一個機械式重複的過程。css

當你遇到重複操做的事情,你就要想一想如何讓機器去作這些事。用人腦去從事這種低等人工智能的活動絕對是種浪費。前端

設想下,若是有段程序,自動把你打開瀏覽器,而後跳轉到百度首頁。再輸入框裏填充 「coding」,點擊搜索,套轉到搜索結果頁面以後,自動確認這個頁面上是否有 「coding」 的字樣。如有,輸出「測試經過」。若無,輸出「測試失敗」。你只須要點開程序,而後去吃個晚飯,而後回來看測試結果就行了(我就是這麼幹的),一切都如此簡單和美妙。python

那麼,須要什麼工具來實現這個美妙的過程呢?首先你須要一雙「手」來點擊和一對「眼」來獲取信息 —— Selenium。 還須要一個腦子來操縱「手和眼」判斷測試對錯 —— Junit。 其實,Selenium 支持多種語言,好比說,ruby, python, Js, C#。他們都有相應成熟的測試框架,因爲我用的是用 Java,相應的測試框架就用了 Junit 。這點已被前端小哥和 Ruby 大神吐槽致死。前端小哥說,既然你要測頁面爲何不用 JS 呢?由於前端就是用 JS 寫的,同源的語言會更好。 Ruby 大神說,用 Ruby 你會少寫不少行代碼。 其實,我那時就對 Java 熟悉一點,最後用 Java 寫了。 這裏,雖然本人沒有親自嘗試過,但我仍是想推薦下用 JS。 如今的網站,頁面上會有着大量的 ajax 請求,頁面的測試必須等待某些頁面元素的更新。在這方面 JS 會比 Java 方便點。ajax

UI 測試工具 Selenium 簡介

selenium 是一個操縱瀏覽器來進行測試的框架。分爲 Selenium 1 ( RC ), Selenium 2 ( WebDriver ), 江湖傳言今年聖誕節會發布 selenium 3,主要是加強對移動端瀏覽器的測試。還有就是 Selenium IDESelenium Grid。 這裏不介紹,能夠看文檔.瀏覽器

Selenium 1 ( RC ), Selenium 2 ( WebDriver ) 的區別就是對瀏覽器操縱的方式。 RC 的原理就是經過對原始的頁面元素中注入一段特定的 JS 代碼來實現的。 學過 JS 的人都知道, JS 能夠操控 DOM 元素,點擊,刪除,獲取元素屬性和文本。你能夠把這些操做當作一個個 JS 函數。 只是瀏覽器對非同源的 JS 有限制, 舉個簡單的例子, 百度首頁上的 JS 代碼不能與淘寶首頁進行交互 (不能訪問它的 cookie 等)。 所以,就須要RC(Remote Control), 將特定的 JS 代碼加到服務器放回的數據中,再發送給瀏覽器,這樣就避開了同源的問題。 而後瀏覽器運行這些 JS 函數,進行測試。ruby

WebDriver 用的方式更爲直接,它自己就是瀏覽器的 API,因此是直接對瀏覽器進行操做。無需經過 JS 代理操做。
我的建議用 WebDriver。 由於,據「路邊社」可靠消息 selenium 3 會逐步拋棄 RC。服務器

這4個多月了,一直在用 selenium 寫自動化測試,由小白到如今稍微熟悉。填了很多坑。 也算是有些心得,接下來若是有時間,我會在 coding 開個 selenium-study 的公有項目來具體講解一些實戰心得。 關於selenium的學習, 最好的教材是 selenium 官方文檔。 若是你的英文不太好,那麼百度一下「蟲師 博客園」,裏面有不少不錯的學習材料。 要是開發中遇到 bug 最好用英文在 google 裏搜。 至於百度搜出來的那坨*,誒,,往事不堪回首。cookie

UI 測試用例設計

上文提到的自動化測試屬於功能測試範疇。所謂功能測試,簡單的說測試網站的功能點是否正常,好比可否註冊和登陸,可否在 coding 發冒泡,push 代碼等等。這是面向用戶的最終測試。app

既然是功能測試,天然是圍繞功能來進行用例設計。用例大體分爲兩個部分, 操做和表現。就「登陸 coding 網站」這一功能來講, 操做有,輸入個性後綴或郵箱以及密碼,點擊「登陸」按鈕。相應的 表現 爲,登陸成功則跳轉到我的中心,同時輸出提示「歡迎***!」。若失敗,則彈出相應的失敗提示。框架

在編寫程序的時候, 調用selenium的接口來進行操做,用斷言 (assertX) 來判斷表現是否正確,例如登陸:

loginPage.clearAndSendKeys("#email",email);

loginPage.clearAndSendKeys("#password",password);

loginPage.clickElement(".large.button ", "#project-list");

assertEquals("登陸不成功",baseUrl + "user", loginPage.getDriver().getCurrentUrl());

這裏的 loginPage 是我寫的一個 Page 類的實例。這個類包括 selenium 部分經常使用接口的封裝(如清除輸入框並輸入值:clearAndSendKeys(String cssSector, String inputContent)),以及一些經常使用的小測試用例,如驗證頁面提示是否正確, loginPage.verifyHint("用戶名或個性後綴不能爲空");

由於有不少操做實際上是一系列操做的組合操做,好比,測試討論評論的通知,建立討論,評論,驗證通知。多用點面向對象設計好點(方便添加新用例),但也沒必要全用。如:

createTopic(zombiePage, topic);
commentTopic(ciwangPage, topic, "@" + zombieUser.getUserName());
Notification atSomeoneNotification = new Notification(notificationFileReader.getEmailIconClass(), ciwangUser, ciwangUser.getUserName()+ " 在 "+ topic.getTopicTitle() + " 的評論中提到了你。", zombieUser, topicFileReader.getTopicTitleInDetailPage() ,topic.getTopicTitle() );
notificationTest.verifyForTwoLinkFormat(atSomeoneNotification, "討論@某人",notificationFileReader.getAtSomeoneItemIcon());

UI 定位 -- cssSelector

若是想要對元素進行操做,必須先定位到那個元素。 selenium 有不少種定位的方法:
圖片

其中,功能最強大的是 xpath 和 cssSelector,已覆蓋其餘接口的功能。 cssSelector 寫起來比 xpath 要簡潔並且易於封裝。推薦使用 cssSelector 定位。

cssSelector 教程就不寫了。有 W3Cschool 在,我就不班門弄斧。講下一些本身的「最佳實踐」吧。

1.儘可能寫的短,若是元素有 id, 千萬別客氣

2.選用有含義的類名
圖片

如上圖的任務,就該用 「.project-task」。之因此說上述 2 點,是由於前端常有改動。所以,選擇短且有含義的類名, 能夠規避很大一部分改動的風險。 但也不是所有, 上個月有一天,前端小哥忽然心血來潮。把冒泡的類名由 「tweet」 改爲了 「bubbling」,改了我兩個小時,才讓程序又跑起來。 所以,還須要第三點。

3.把選擇器寫到配置文件裏,而後用一個 fileReader 類去讀。如

public void sendComment(Page zombiePage, String commentContent){
    zombiePage.sendKeys(topicFileReader.getCommentInput(),commentContent);
    zombiePage.clickElement(topicFileReader.getCommentButton());
    assertTrue("評論沒有發送成功", zombiePage.waitElementDisappear(topicFileReader.getEmptyTopicComments()));
}

這個月有一天, 討論的評論框被改掉了。我只需該兩行配置文件,代碼就能夠跑了。

commentInput = #comment-form textarea
commentButton = #comment-form .clockwise

寫選擇器還有一個好處就是,代碼的可讀性,讓別人知道選擇器的意義。

今天寫到這裏。這篇水文能看到最後的,,我想,應該是真愛吧。若是有問題和講得不實的地方歡迎登陸 coding 私信我 (ciwang)。 Anyway, 歡迎你們拍磚


Coding 官方技術博客: http://blog.coding.net/
Coding 官網 : https://coding.net

相關文章
相關標籤/搜索