亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用Ruby實(shí)現(xiàn)簡單的事物驅(qū)動(dòng)的web應(yīng)用的教程

 更新時(shí)間:2015年04月15日 15:30:34   投稿:goldensun  
這篇文章主要介紹了使用Ruby實(shí)現(xiàn)簡單的事物驅(qū)動(dòng)的web應(yīng)用的教程,本文來自于IBM官方技術(shù)文檔,需要的朋友可以參考下

簡介

對(duì) Web 應(yīng)用程序來講,自動(dòng)化的集成測(cè)試是一個(gè)非常重要的部分, 然而由于這些測(cè)試用例太依賴具體的 Web 頁面的實(shí)現(xiàn)細(xì)節(jié),這就給編寫和維護(hù)帶來的很大的挑戰(zhàn)。 通常來講有兩種方法可以生成 Web 應(yīng)用程序測(cè)試用例。

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

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

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

例如一個(gè)在線的電子書店,對(duì)于用戶購書的場(chǎng)景,我們可以用下面的腳本來進(jìn)行集成測(cè)試 :

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

讀者可以看到, "login" , "list_books", "add_to_shop_cart" 這些術(shù)語已經(jīng)完全脫離了具體的頁面細(xì)節(jié),將不會(huì)受到頁面變化的影響, 它們是完全面向業(yè)務(wù)的,準(zhǔn)確的體現(xiàn)了應(yīng)用的業(yè)務(wù)邏輯,容易理解、易于維護(hù),并且還能拿來和業(yè)務(wù)人員進(jìn)行交流,甚至業(yè)務(wù)人員自己都能編寫測(cè)試腳本。 有這么多的優(yōu)點(diǎn),那么如何實(shí)現(xiàn)它們呢?這正是本文要介紹的重點(diǎn):利用動(dòng)態(tài)語言 Ruby 來實(shí)現(xiàn)“業(yè)務(wù)驅(qū)動(dòng)”的 Web 應(yīng)用測(cè)試。
Ruby 介紹

Ruby,中文意思為紅寶石,但是在計(jì)算機(jī)領(lǐng)域,它代表一種相當(dāng)優(yōu)秀的面向?qū)ο蟮哪_本程序語言。它誕生于 1993 年,近年來隨著 Ruby on Rails 這個(gè)“Killer application”在 Web 開發(fā)領(lǐng)域迅速躥紅。Ruby 在最初設(shè)計(jì)時(shí)吸收了很多別的語言的精華,例如 perl 語言的文本處理能力,Python 語言的簡單性和可讀性,以及方便的擴(kuò)展能力和強(qiáng)大的可移植能力,Smalltalk 語言的純面向?qū)ο笳Z法思想,這就使它具備了很多其他語言的優(yōu)點(diǎn)。Ruby 的設(shè)計(jì)理念是盡量減少編程時(shí)不必要的瑣碎工作,讓程序員在完成任務(wù)的同時(shí)充分的享受編程的樂趣。

Ruby 的特點(diǎn)如下:

    面向?qū)ο螅涸?Ruby 中,一切皆是對(duì)象,包括其他語言中的基本數(shù)據(jù)類型,比如整數(shù)。

    例如在 Java 中,對(duì)一個(gè)數(shù)求絕對(duì)值用 Math.abs(-20), 但在 Ruby 中一切皆對(duì)象,-20 這個(gè)數(shù)也是對(duì)象,所以可以這么做 -20.abs , 是不是更加形象和直觀?
    解釋型腳本語言:無需編譯,直接執(zhí)行,開發(fā)周期短,調(diào)試方便。
    動(dòng)態(tài)性:已經(jīng)定義的類可以在運(yùn)行時(shí)修改。

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

為了展示如何使用 Ruby 進(jìn)行業(yè)務(wù)驅(qū)動(dòng)的測(cè)試,同時(shí)又不讓讀者陷入到過多細(xì)節(jié)中,本文假想了一個(gè)簡單的在線購書應(yīng)用 ( 簡稱 51book),這個(gè)應(yīng)用支持如下主要功能:

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

2015415152602575.jpg (314×90)

    2.瀏覽書籍:包括按標(biāo)題搜索書籍。
圖 2. 瀏覽和搜索書籍

2015415152632077.jpg (567×387)

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

2015415152701463.jpg (461×173)

業(yè)務(wù)操作

通過上面的介紹,讀者應(yīng)該對(duì) 51book 有了一個(gè)簡單的了解,接下來我們考慮如何進(jìn)行業(yè)務(wù)驅(qū)動(dòng)的測(cè)試,首先需要定義面向業(yè)務(wù)的操作,這樣才能在測(cè)試用例中使用它們。 簡單起見,我們定義如下業(yè)務(wù)操作:
表 1. 業(yè)務(wù)操作

2015415152724682.jpg (958×273)

領(lǐng)域?qū)S谜Z言 (Domain Specific Language)

所謂領(lǐng)域?qū)S谜Z言(domain specific language / DSL),其基本思想是“求專不求全”,不像通用目的語言那樣目標(biāo)范圍涵蓋一切軟件問題, 而是專門針對(duì)某一特定問題的計(jì)算機(jī)語言。正如它的名稱所宣稱的那樣,這種語言并不是通用的,只是專注于某個(gè)特定的“領(lǐng)域”, 例如 SQL 語言就是數(shù)據(jù)庫的 DSL,使用 SQL 可以完成各種各樣數(shù)據(jù)的操作,而不用關(guān)心底層的具體數(shù)據(jù)庫實(shí)現(xiàn)。由于“領(lǐng)域?qū)S谩保阆胗?SQL 來開發(fā)一個(gè)桌面應(yīng)用程序是不可能的。

我們?cè)谏弦还?jié)定義的 login , add_to_shop_cart , change_quantity 就是針對(duì) 51book 在線書店的 DSL。

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

Ruby 語言具備非常豐富的語法和異常靈活的動(dòng)態(tài)特征,非常適合創(chuàng)建動(dòng)態(tài) DSL。本文就是利用 Ruby 來創(chuàng)建 51book 面向測(cè)試的 DSL。

用 Ruby DSL 實(shí)現(xiàn)業(yè)務(wù)操作
原理

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

比如我們有一個(gè)文件 bookshop.txt,它包含了如下文本 : login "andy", "pass4you" , 那么怎么執(zhí)行它呢?首先需要一個(gè)上下文,我們可以定義一個(gè)類來表示:
清單 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

上面的代碼非常簡單,需要關(guān)注的是靜態(tài)方法 execute, 當(dāng)把 bookshop.txt 作為參數(shù)來調(diào)用它時(shí),會(huì)有什么情況發(fā)生呢 ? 聰明的讀者可能已經(jīng)猜到了,那就是 user 和 pwd 的值會(huì)被打印出來。這段代碼展示了 Ruby 語言的兩個(gè)重要特點(diǎn) :

    instance_eval 方法會(huì)把一段文本當(dāng)做代碼來執(zhí)行。執(zhí)行的上下文就是對(duì)象 BookshopDSLBuilder。 所以當(dāng)它碰到文本 "login" 時(shí),會(huì)自動(dòng)調(diào)用真正的方法 login。
    在調(diào)用一個(gè)方法時(shí),可以不加括號(hào)。這就是為什么 Ruby 會(huì)把文本 login "andy","pass4you" 當(dāng)做一個(gè)方法調(diào)用的原因。

這兩個(gè)特點(diǎn)就給我們搭了一座“橋”,使得我們可以把那個(gè)面向業(yè)務(wù)測(cè)試的文本諸如“l(fā)ogin”,“add_to_cart”,“search_book”等轉(zhuǎn)化為對(duì)特定方法的調(diào)用了。我們就可以在這些方法中實(shí)現(xiàn)某些邏輯。
Watir

我們現(xiàn)在已經(jīng)能夠把業(yè)務(wù)測(cè)試的腳本和 Ruby 的對(duì)象 / 方法連接起來,可是還需要第二座橋把 Ruby 和 Web 應(yīng)用程序連接起來,這樣才能使業(yè)務(wù)測(cè)試的腳本驅(qū)動(dòng) Web 頁面進(jìn)行測(cè)試。我們希望能有一個(gè)軟件或工具可以像人一樣來驅(qū)動(dòng)瀏覽器的操作,例如點(diǎn)擊鏈接,填充表單,點(diǎn)擊按鈕等等。當(dāng)然它也可以檢查頁面的結(jié)果,例如期待的文本是否出現(xiàn)等。

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

下面是一個(gè)使用 watir 的簡單例子,它進(jìn)入 Google 的首頁,在搜索框中鍵入 "bookshop", 然后點(diǎn)擊"搜索"按鈕。 Watir 充分繼承了 Ruby 語言簡單明了的特點(diǎn),讀者可以看到使用 Watir 的腳本是相當(dāng)直觀,相當(dāng)容易的。
清單 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

實(shí)現(xiàn) Login

有了上面的兩座“橋”,具體的實(shí)現(xiàn)就簡單多了,對(duì)于每一個(gè)業(yè)務(wù)操作,我們需要做的是 :

(1) 在一個(gè) Ruby 對(duì)象中 (BookshopDSLBuilder) 實(shí)現(xiàn)一個(gè)同名的方法

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

先來看一看 Login 的實(shí)現(xiàn):
清單 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               # 創(chuàng)建一個(gè) Watir 的實(shí)例
 end 
 def login(user=nil,pwd=nil) 
  @ie.goto @login_url 
  @ie.text_field(:id,"user_name").set(user)   # 設(shè)置用戶名
  @ie.text_field(:id,"user_password").set(pwd)  # 設(shè)置密碼
  @ie.button(:type,"submit").click        # 點(diǎn)擊提交按鈕
 end 
end

實(shí)現(xiàn) add_to_shop_cart

把書籍添加的購物車中這個(gè)操作相對(duì)復(fù)雜,因?yàn)樗邮盏膮?shù)是一個(gè)書籍的標(biāo)題,而在界面上"Add to Cart"卻是一個(gè)只包含 book id, 不包含標(biāo)題的鏈接,所以無法直接定位。
清單 4. Add to Cart

 <table width='100%' class='book'> 
  <tr> 
    <td>title:</td> 
    <td>Agile development</td> # 標(biāo)題在這里
  </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 對(duì) xpath 強(qiáng)大的支持,先找到標(biāo)題,在從標(biāo)題找到鏈接,最后點(diǎn)擊鏈接即可。
清單 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

對(duì)于其他的業(yè)務(wù)操作,具體的實(shí)現(xiàn)方式也是大同小異,這里不再一一介紹,有興趣的讀者可以參見 附件 中的代碼,最后我們來看一個(gè)面向業(yè)務(wù)的 Web 頁面測(cè)試?yán)樱?br /> 清單 6. 一個(gè)完整的例子

 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

總結(jié)

到目前為止,我們已經(jīng)通過 Ruby 完整的實(shí)現(xiàn)了“業(yè)務(wù)驅(qū)動(dòng)” 的 Web 應(yīng)用測(cè)試,實(shí)際上我們通過 Ruby 實(shí)現(xiàn)了一個(gè)面向業(yè)務(wù)的抽象層,利用 Watir 把業(yè)務(wù)操作映射到了對(duì) Html 頁面的操作。這樣當(dāng) Html 頁面發(fā)生了變化的時(shí)候,只需要調(diào)整映射,而不需要更改業(yè)務(wù)層的操作。同時(shí)由于它們是完全面向業(yè)務(wù)的,就使得開發(fā)人員或測(cè)試人員能把精力集中到業(yè)務(wù)邏輯的測(cè)試上,而不用陷入實(shí)現(xiàn)的細(xì)節(jié)。

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

相關(guān)文章

最新評(píng)論