應用Selenium和Ruby進行面向領域的Web測試(2)

發表于:2011-07-27來源:未知作者:領測軟件測試網采編點擊數: 標簽:
def on page_type, block page = page_type.new $selenium assert page.visible?, not on #{page_type} page.instance_eval block if block_given? pageend 這個方法神秘地返回了page對象,這里是一個

  def on page_type, &block page = page_type.new $selenium assert page.visible?, "not on #{page_type}" page.instance_eval &block if block_given? pageend

  這個方法神秘地返回了page對象,這里是一個比較取巧的技巧。實際上,我們只想利用page != nil這個事實來斷言頁面的流轉,比如,下面的代碼描述登錄成功的頁面流轉過程:

  on LoginPage do assert_equal 'Welcome!', welcome_message login_as :name => 'xxx', :password => 'xxx'endassert on WelcomeRegisteredUserPage

  除了這個基本斷言之外,我們還可以定義一些業務相關的斷言,比如在購物車頁面里,我們可以定義一個判斷購物車是否為空的斷言:

def cart_empty? @driver.get_text('xpath=

') == 'Shopping Cart(0)'end

  需要注意的是,雖然我們在page object里引入了Test::Unit::Asseration模塊,但是并沒有在斷言方法里使用任何assert*方法。這是因為,概念上來講 page object并不是測試。使之包含一些真正的斷言,一則概念混亂,二則容易使page object變成針對某些場景的test helper,不利于以后測試的維護,因此我們往往傾向于將斷言方法實現為一個普通的返回值為boolean的方法。

  3. Test Data

  測試意圖的體現不僅僅是在行為的描述上,同樣還有測試數據,比如如下兩段代碼:

  on LoginPage do login_as :name => 'userA', :password => 'password'endassert on WelcomeRegisteredUserPageregistered_user = {:name => 'userA', :password => 'password'}on LoginPage do login_as registered_userendassert on WelcomeRegisteredUserPage

  測試的是同一個東西,但是顯然第二個測試更好的體現了測試意圖:使用一個已注冊的用戶登錄,應該進入歡迎頁面。我們看這個測試的時候,往往不會關心用戶名啊密碼啊具體是什么,我們關心它們表達了怎樣的測試案例。我們可以通過DataFixture來實現這一點:

  module DataFixture USER_A = {:name => 'userA', :password => 'password'} USER_B = {:name => 'userB', :password => 'password'} def get_user identifier case identifier when :registered then return USER_A when :not_registered then return USER_B end endend

  在這里,我們將測試案例和具體數據做了一個對應:userA是注冊過的用戶,而userB是沒注冊的用戶。當有一天,我們需要將登錄用戶名改為郵箱的時候,只需要修改DataFixture模塊就可以了,而不必修改相應的測試:

  include DataFixtureDatuser = get_user :registeredon LoginPage do login_as userendassert on WelcomeRegisteredUserPage

  當然,在更復雜的測試中,DataFixture同樣可以使用真實的數據庫或是Rails Fixture來完成這樣的對應,但是總體的目的就是使測試和測試數據有效性的耦合分離:

def get_user identifier case identifier when :registered then return User.find '

.' endend

  4.Navigator

  與界面元素類似,URL也是一類易變且難以表達意圖的元素,因此我們可以使用Navigator使之與測試解耦。具體做法和Test Data相似,這里就不贅述了,下面是一個例子:

navigate_to detail_page_for @producton ProductDetailPage do

.end

  5. Shortcut

  前面我們已經有了一個很好的基礎,將Selenium測試與各種脆弱且意圖不明的元素分離開了,那么最后shortcut不過是在蛋糕上面最漂亮的奶油罷了——定義具有漂亮語法的helper:

  def should_login_successfully user on LoginPage do assert_equal 'Welcome!', welcome_message login_as user end assert on WelcomeRegisteredUserPageend

  然后是另外一個magic方法:

  def given identifer words = identifier.to_s.split '_' eval "get_#{words.last} :#{words[0..-2].join '_'}"end

  之前的測試就可以被改寫為:

  def test_should_xxxx should_login_successfully given :registered_userend

  這是一種結論性的shortcut描述,我們還可以有更behaviour的寫法:

  def login_on page_type on page_type do assert_equal 'Welcome!', welcome_message login_as @user end enddef login_successfully on WelcomeRegisteredUserPageenddef given identifer words = identifier.to_s.split '_' eval "@#{words.last} = get_#{words.last} :#{words[0..-2].join '_'}"end

  最后,測試就會變成類似驗收條件的樣子:

  def test_should_xxx given :registered_user login_on LoginPage assert login_successfullyend

  總之shortcut是一個無關好壞,只關乎想象力的東西,盡情揮灑Ruby DSL吧!

  結論

  Selenium是一個讓人又愛又恨的東西,錯誤地使用Selenium會給整個敏捷團隊的開發節奏帶來災難性的影響。不過值得慶幸的是正確地使用Selenium的原則也是相當的簡單:

  通過將脆弱易變的頁面元素和測試分離開,使得頁面的變化不會對測試產生太大的影響。

  明確指定測試數據的意圖,不在測試用使用任何具體的數據。

  盡一切可能,明確地表達出測試的意圖,使測試易于理解。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97