亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Ruby > 正文

使用Ruby實現簡單的事物驅動的web應用的教程

2020-10-29 19:41:05
字體:
來源:轉載
供稿:網友

簡介

對 Web 應用程序來講,自動化的集成測試是一個非常重要的部分, 然而由于這些測試用例太依賴具體的 Web 頁面的實現細節,這就給編寫和維護帶來的很大的挑戰。 通常來講有兩種方法可以生成 Web 應用程序測試用例。

    手工編寫腳本:測試人員需要知道 Web 頁面上有哪些表單、輸入框、選擇框、按鈕等,以及這些表單元素的名稱,ID 等屬性,然后才能利用一些工具來編寫測試用例。
    通過工具錄制生成:比如 IBM Rational Functional Tester 就提供了錄制用戶在 Web 界面的操作,自動生成測試用例的功能。

方法 1 需要測試人員了解太多的 Web 頁面細節,這就使得測試人員不能把精力集中在業務邏輯上,一旦 Web 頁面發生變化,將不得不花費大量精力更新腳本。方法 2 能夠自動生成測試腳本,但是這些腳本的可讀性很差,導致很難維護。同樣如果 Web 頁面發生變化,測試人員也需要重新錄制所有的腳本。

那么有沒有辦法克服上述問題,讓工作更加輕松一點呢?答案是肯定的!

例如一個在線的電子書店,對于用戶購書的場景,我們可以用下面的腳本來進行集成測試 :

login 'test@test.com','pass4you'     // 登錄
list_books                           // 列出書籍
add_to_shop_cart  '誰說大象不能跳舞'  // 把《誰說大象不能跳舞》這本書加入到購物車中

讀者可以看到, "login" , "list_books", "add_to_shop_cart" 這些術語已經完全脫離了具體的頁面細節,將不會受到頁面變化的影響, 它們是完全面向業務的,準確的體現了應用的業務邏輯,容易理解、易于維護,并且還能拿來和業務人員進行交流,甚至業務人員自己都能編寫測試腳本。 有這么多的優點,那么如何實現它們呢?這正是本文要介紹的重點:利用動態語言 Ruby 來實現“業務驅動”的 Web 應用測試。
Ruby 介紹

Ruby,中文意思為紅寶石,但是在計算機領域,它代表一種相當優秀的面向對象的腳本程序語言。它誕生于 1993 年,近年來隨著 Ruby on Rails 這個“Killer application”在 Web 開發領域迅速躥紅。Ruby 在最初設計時吸收了很多別的語言的精華,例如 perl 語言的文本處理能力,Python 語言的簡單性和可讀性,以及方便的擴展能力和強大的可移植能力,Smalltalk 語言的純面向對象語法思想,這就使它具備了很多其他語言的優點。Ruby 的設計理念是盡量減少編程時不必要的瑣碎工作,讓程序員在完成任務的同時充分的享受編程的樂趣。

Ruby 的特點如下:

    面向對象:在 Ruby 中,一切皆是對象,包括其他語言中的基本數據類型,比如整數。

    例如在 Java 中,對一個數求絕對值用 Math.abs(-20), 但在 Ruby 中一切皆對象,-20 這個數也是對象,所以可以這么做 -20.abs , 是不是更加形象和直觀?
    解釋型腳本語言:無需編譯,直接執行,開發周期短,調試方便。
    動態性:已經定義的類可以在運行時修改。

本文的重點不是介紹 Ruby 語言本身,有興趣的讀者可以參見 參考資源 部分。
案例分析
51book

為了展示如何使用 Ruby 進行業務驅動的測試,同時又不讓讀者陷入到過多細節中,本文假想了一個簡單的在線購書應用 ( 簡稱 51book),這個應用支持如下主要功能:

    1.登錄 : 用戶必須登錄才能購買書籍。
    圖 1. 登錄

2015415152602575.jpg (314×90)

    2.瀏覽書籍:包括按標題搜索書籍。
圖 2. 瀏覽和搜索書籍

2015415152632077.jpg (567×387)

3.把書籍添加到購物車中,參見 圖 2 中的“Add to cart”鏈接。
4.改變購物車中書籍的數量,并且重新計算。

2015415152701463.jpg (461×173)

業務操作

通過上面的介紹,讀者應該對 51book 有了一個簡單的了解,接下來我們考慮如何進行業務驅動的測試,首先需要定義面向業務的操作,這樣才能在測試用例中使用它們。 簡單起見,我們定義如下業務操作:
表 1. 業務操作

2015415152724682.jpg (958×273)

領域專用語言 (Domain Specific Language)

所謂領域專用語言(domain specific language / DSL),其基本思想是“求專不求全”,不像通用目的語言那樣目標范圍涵蓋一切軟件問題, 而是專門針對某一特定問題的計算機語言。正如它的名稱所宣稱的那樣,這種語言并不是通用的,只是專注于某個特定的“領域”, 例如 SQL 語言就是數據庫的 DSL,使用 SQL 可以完成各種各樣數據的操作,而不用關心底層的具體數據庫實現。由于“領域專用”,你想用 SQL 來開發一個桌面應用程序是不可能的。

我們在上一節定義的 login , add_to_shop_cart , change_quantity 就是針對 51book 在線書店的 DSL。

Martin Fowler 把 DSL 分為兩大類:外部 DSL 和內部 DSL。對外部 DSL 來講,構建它需要做的是:(1) 定義面向領域的全新的語法。(2) 用某種語言編寫解釋器或編譯器 ,由于這種語言是全新的,我們有很多工作需要做;那么對于內部 DSL 來說,我們可以選定一種靈活的語言,選取它一個語法的子集,并且利用這種語言的動態特性進行定制,這樣就避免了重新打造一個全新語言的龐大工作量。

Ruby 語言具備非常豐富的語法和異常靈活的動態特征,非常適合創建動態 DSL。本文就是利用 Ruby 來創建 51book 面向測試的 DSL。

用 Ruby DSL 實現業務操作
原理

由于 Ruby 是一種動態腳本語言,是解釋執行的,它提供了對一段文本進行 “evaluate”執行的方法。也就是說,我們可以提供一段文本(不必是完整的程序),Ruby 就可以在一個特定的上下文中執行它,當然這段文本需要符合 Ruby 的語法。

比如我們有一個文件 bookshop.txt,它包含了如下文本 : login "andy", "pass4you" , 那么怎么執行它呢?首先需要一個上下文,我們可以定義一個類來表示:
清單 1. BookshopDSLBuilder

class BookshopDSLBuilder    def self.execute( dsl)     builder=new     builder.instance_eval(File.read(dsl), dsl)    end   def login(user=nil,pwd=nil)     print user     print pwd   end end

上面的代碼非常簡單,需要關注的是靜態方法 execute, 當把 bookshop.txt 作為參數來調用它時,會有什么情況發生呢 ? 聰明的讀者可能已經猜到了,那就是 user 和 pwd 的值會被打印出來。這段代碼展示了 Ruby 語言的兩個重要特點 :

    instance_eval 方法會把一段文本當做代碼來執行。執行的上下文就是對象 BookshopDSLBuilder。 所以當它碰到文本 "login" 時,會自動調用真正的方法 login。
    在調用一個方法時,可以不加括號。這就是為什么 Ruby 會把文本 login "andy","pass4you" 當做一個方法調用的原因。

這兩個特點就給我們搭了一座“橋”,使得我們可以把那個面向業務測試的文本諸如“login”,“add_to_cart”,“search_book”等轉化為對特定方法的調用了。我們就可以在這些方法中實現某些邏輯。
Watir

我們現在已經能夠把業務測試的腳本和 Ruby 的對象 / 方法連接起來,可是還需要第二座橋把 Ruby 和 Web 應用程序連接起來,這樣才能使業務測試的腳本驅動 Web 頁面進行測試。我們希望能有一個軟件或工具可以像人一樣來驅動瀏覽器的操作,例如點擊鏈接,填充表單,點擊按鈕等等。當然它也可以檢查頁面的結果,例如期待的文本是否出現等。

開源工具 Watir 就是這樣一個工具,除了具備上述功能外,它和 Ruby 語言還能進行無縫的集成,并且對瀏覽器尤其是 IE 有超強的控制能力。所以我們選取它作為第二座橋。

下面是一個使用 watir 的簡單例子,它進入 Google 的首頁,在搜索框中鍵入 "bookshop", 然后點擊"搜索"按鈕。 Watir 充分繼承了 Ruby 語言簡單明了的特點,讀者可以看到使用 Watir 的腳本是相當直觀,相當容易的。
清單 2. Watir 例子

require "watir"ie = Watir::IE.new ie.goto "http://www.google.com"    ie.text_field(:name, "q").set "bookshop"ie.button(:name, "btnG").click

實現 Login

有了上面的兩座“橋”,具體的實現就簡單多了,對于每一個業務操作,我們需要做的是 :

(1) 在一個 Ruby 對象中 (BookshopDSLBuilder) 實現一個同名的方法

(2) 在方法實現中,利用 watir 來操作界面元素。當然前提是我們需要知道界面上有哪些元素。

先來看一看 Login 的實現:
清單 3. Login

class BookshopDSLBuilder  include Test::Unit::Assertions #include ruby unit 的 Assertion  def self.execute( dsl)   builder=new   builder.instance_eval(File.read(dsl), dsl)   builder  end  def initialize   @login_url = 'http://localhost:3000/bookshop/login'  #51Book 的入口  #creat a ie instance   @ie= Watir::IE.new               # 創建一個 Watir 的實例 end  def login(user=nil,pwd=nil)   @ie.goto @login_url   @ie.text_field(:id,"user_name").set(user)   # 設置用戶名  @ie.text_field(:id,"user_password").set(pwd)  # 設置密碼  @ie.button(:type,"submit").click        # 點擊提交按鈕 end end

實現 add_to_shop_cart

把書籍添加的購物車中這個操作相對復雜,因為它接收的參數是一個書籍的標題,而在界面上"Add to Cart"卻是一個只包含 book id, 不包含標題的鏈接,所以無法直接定位。
清單 4. Add to Cart

 <table width='100%' class='book'>   <tr>     <td>title:</td>     <td>Agile development</td> # 標題在這里  </tr>   <tr>     <td>description:</td>     <td>The book of agile development</td>   </tr>   <tr>     <td>price:</td>     <td>30.0</td>   </tr>   <tr>     <td colspan="2"> #Add_To_Cart Link 卻在這里      <a href='/bookshop/add_to_cart/1' >Add to Cart</a>     </td>   </tr>   </table>

這種情況下就可以利用 Watir 對 xpath 強大的支持,先找到標題,在從標題找到鏈接,最后點擊鏈接即可。
清單 5. 使用 XPath

def add_to_cart(title)      table = @ie.table(:xpath,      "http://table[@class='book']/tbody/tr/td[text()='"+title+"']/../../../")   if table[1][2].text == title     href = table[4][1].links[1].href     @ie.link(:href,href).click   end end

對于其他的業務操作,具體的實現方式也是大同小異,這里不再一一介紹,有興趣的讀者可以參見 附件 中的代碼,最后我們來看一個面向業務的 Web 頁面測試例子:
清單 6. 一個完整的例子

 login 'andy','pass4you'  add_to_cart 'Agile development' add_to_cart 'Savor Blue' add_to_cart 'Programming Ruby'  change_quantity 'Agile development',10  change_quantity 'Savor Blue',10  change_quantity 'Programming Ruby',10  recalculate_cart  assert_total_price_is 900  search_book 'Ant cookbook' add_to_cart 'Ant cookbook' assert_total_price_is 910

總結

到目前為止,我們已經通過 Ruby 完整的實現了“業務驅動” 的 Web 應用測試,實際上我們通過 Ruby 實現了一個面向業務的抽象層,利用 Watir 把業務操作映射到了對 Html 頁面的操作。這樣當 Html 頁面發生了變化的時候,只需要調整映射,而不需要更改業務層的操作。同時由于它們是完全面向業務的,就使得開發人員或測試人員能把精力集中到業務邏輯的測試上,而不用陷入實現的細節。

掌握了該方法以后,讀者可以應用到自己的程序中,可以使得自己的測試編寫簡單,容易理解,易于維護。將會極大的提供 Web 應用的測試效率。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国内精品久久久久久久| 亚洲成avwww人| 日韩高清a**址| 色偷偷偷综合中文字幕;dd| 亚洲第一福利视频| 亚洲精品电影久久久| 亚洲欧美另类在线观看| 欧美另类在线观看| 日韩二区三区在线| 国产成人极品视频| 久久精品99无色码中文字幕| 国产精品一区二区电影| 成人福利在线观看| 亚洲一区二区免费在线| 亚洲精品国产综合区久久久久久久| 国产精品久久久亚洲| 91精品国产91久久久久久| 91精品国产成人| 成人女保姆的销魂服务| 国产欧美韩国高清| 欧美国产日韩一区| 国内精品中文字幕| 欧美日韩另类在线| 日韩激情av在线免费观看| 米奇精品一区二区三区在线观看| 青青在线视频一区二区三区| 91精品久久久久久综合乱菊| 日韩中文字幕网站| 国产精品久久久久久久久久99| 精品国产91久久久久久| 久久精品国产99国产精品澳门| 国产视频丨精品|在线观看| 成人免费视频a| 91av在线免费观看| 精品亚洲va在线va天堂资源站| 97av在线视频| 国产日韩精品综合网站| 亚洲综合中文字幕在线| 欧美黑人极品猛少妇色xxxxx| 精品国产欧美成人夜夜嗨| 国产精品久久久久高潮| 精品亚洲va在线va天堂资源站| 久久夜色精品国产亚洲aⅴ| 国产在线观看精品| 日韩免费在线播放| 日韩精品视频中文在线观看| 久久精品成人一区二区三区| 高清日韩电视剧大全免费播放在线观看| 欧美国产日韩一区二区| 亚洲欧美中文另类| 久久久免费观看视频| 日韩成人在线网站| 97av在线视频免费播放| 国产成人97精品免费看片| 国语自产精品视频在线看抢先版图片| 日韩中文字幕精品视频| 久久精品这里热有精品| 亚洲精品资源在线| 欧美不卡视频一区发布| 日韩影视在线观看| 国产精品视频自拍| 91中文字幕在线| 亚洲欧美日韩天堂一区二区| 欧美成人免费一级人片100| 欧美日韩999| 国产精品91视频| 国产精品日韩在线| 国产精品一区二区三区在线播放| 国产日韩欧美成人| 久久精品在线播放| 亚洲福利视频二区| 国产精品www色诱视频| 精品国产区一区二区三区在线观看| 午夜精品三级视频福利| 久久久国产影院| 欧美精品久久久久久久免费观看| 亚洲精品网址在线观看| 北条麻妃99精品青青久久| 亚洲国产精品视频在线观看| 久久久久久久久久婷婷| 欧美尺度大的性做爰视频| 亚洲a一级视频| 日韩有码在线观看| 国产精品福利久久久| 久久91精品国产91久久久| 欧美日韩一区二区在线| 中文字幕久精品免费视频| 色诱女教师一区二区三区| 亚洲自拍小视频| 黑人巨大精品欧美一区二区免费| 成人欧美一区二区三区在线湿哒哒| 欧美性猛交xxxx黑人| 亚洲人线精品午夜| 成人免费激情视频| 亚洲国模精品一区| 欧美成人精品三级在线观看| 97香蕉超级碰碰久久免费的优势| 久久99久久99精品免观看粉嫩| 亚洲精品av在线| 欧美一级片久久久久久久| 97视频在线观看成人| 亚洲一级片在线看| 国产999在线观看| 日韩午夜在线视频| 欧美一区深夜视频| 亚洲午夜精品久久久久久性色| 国产精品免费电影| 日韩电影在线观看中文字幕| 国产精品成人va在线观看| 日韩av电影在线免费播放| 中文字幕视频一区二区在线有码| 青青草一区二区| 国产日韩在线免费| 欧美韩国理论所午夜片917电影| 欧美亚洲在线播放| 精品国产一区二区三区在线观看| 91麻豆国产语对白在线观看| 亚洲精品国产suv| 欧美一区深夜视频| 精品少妇v888av| 26uuu另类亚洲欧美日本一| 久久久久久国产精品| 国产精品久久久久秋霞鲁丝| 91av视频在线| 国产精品第100页| 久色乳综合思思在线视频| 国产精品免费视频xxxx| 日韩精品亚洲视频| 一色桃子一区二区| 国产成人黄色av| 菠萝蜜影院一区二区免费| 亚洲精品成人久久| 欧美黄网免费在线观看| 日韩av免费在线| 日韩中文字幕不卡视频| 日韩网站免费观看高清| 亚洲男人的天堂在线| 日韩美女免费视频| 亚洲色图偷窥自拍| 欧美激情久久久久| 色99之美女主播在线视频| 久久成人18免费网站| 久久99青青精品免费观看| 国产精品美女久久久免费| 国产午夜精品免费一区二区三区| 午夜剧场成人观在线视频免费观看| 在线观看欧美视频| 国产精品成人观看视频国产奇米| 久久五月天综合| 国产精品爽黄69天堂a| 欧美亚洲在线观看| 亚洲免费伊人电影在线观看av| 亚洲一区制服诱惑| 欧美成人在线影院| 国产在线视频2019最新视频| 91视频国产一区| 国产欧美日韩免费| 两个人的视频www国产精品| 久久久www成人免费精品张筱雨| 亚洲va码欧洲m码| 中文字幕欧美日韩精品| 欧美极品欧美精品欧美视频| 国产精品丝袜高跟| 国产日韩专区在线|