まともなUIテストを書きます

--01--

PageObjectについて

 

PageObjectは、UIのテストを書くのモードです。要するに、あなたはこのオブジェクトを置くためにページの一部のすべての詳細を知ることができ、テストを書く人のために、1つのPageObjectは、ページ上の検索ボックスとして(検索結果をページ、または地域を表し、サイドバーはとても)独立したオブジェクトであってもよいです。この利点は、2つの領域に分割されています。

  1. (どのようにHTMLの内部組織)実装の詳細のすべてをカプセル化します
  2. 外部インタフェースは非常にはっきりしているので、コードをより多くのセマンティック

ここでは、説明するために単純な例をリスト:

私たちは、シナリオをテストしているしたい:私たちは、検索アプリケーションであり、ユーザーは、ThoughtWorksのを入力し、私たちは10件の結果があり、検索結果の最初のページを判断しました。ネイティブカピバラ場合は、次のようにコードが一般的になります。

1 
2
3
4
5
6
visit '/search'
fill_in 'Search', :with => 'ThoughtWorks'
click_button '#search'
expect(find('#result').find('.tips')).to have_content("10")

まず、/検索ページを入力して、キーワードThoughtWorksの検索を入力し、[次の10 #resultの.tipsの言葉でボタン#search、最終的な判断をクリックします。

PageObject場合は、コード(疑似コード)になります。

 

search = SearchBox.new
result = SearchResult.new
search.type "ThoughtWorks"
expect(result.count).to eq(10)

--02--

site_prismプロフィール

 

site_prismは、宝石のためのカピバラのページオブジェクトモデリングの上に構築されています。非常にセマンティック書き込みページオブジェクトすることができsite_prismを使用して、あなたは、コードは非常に読みやすくすることができます。

ページセクションのオブジェクトの上に位置ページ上のいくつかのブロックは、コンテンツエリア、サイドバーのような、例えば、対応することができる、各論理セクションを複数のオブジェクトを有することができます。今人気のSPAについては、我々は唯一のページと、十分なセクションの番号が必要です。

1 
2
3
4
5
6
7
8
class MovingHome < SitePrism::Page
set_url 'http://localhost:8100/bundles/moving-home'
element :container, "#tmsCheckout"
section :personal, PersonalSection, "#acc-personal"
section :contact, ContactSection, "#acc-contact"
end

set_url方法はまた、webdriverをURLが実際にリクエストを送信し、現在のページに到達するためにどのように働きました。あなたは、それ自体が要素、および要素に対応するCSSセレクタを宣言するために、ページ要素法を使用することができますので、あなたは、要素名でHTML要素を対応するセレクタにアクセスすることができます。

例えば、容器の場合、我々はそれにアクセスするには、この方法をテストすることができます。

1 
2
3
4
@moving = MovingHome.new
@moving.load
@moving.container.should be_visible

及び対応する断面要素、ブロック、ブロックタイプ、ブロックセレクタの名前を宣言する。私たちはブロックの名前によって適用することができるように:

1 
2
3
4
@moving.personal.name.set "Juntao"
expect(@moving).to have_personal
expect(@moving).to have_contact

(ディスプレイ等:ブロック)ブロックを表示するかどうかを決定するために使用Have_ブロックプレフィックスと名前。

 

--03--

プロジェクトのインスタンス

 

現在、いくつかの新しい機能を追加するページの必要性、いくつかのUIテストを追加し、対応する必要性を投影しています。以前のすべてのコードは、プロセス指向され、マルチコードが繰り返し組織機能を介してコードではなく、実際のページのモジュールの関連付けに排気されます。だから私はsite_prismを使用するには、いくつかの試みを行いました。

ビジネスシナリオはこれです:ユーザが(例えば移転を申請することに対応するブロードバンド/ケーブルテレビの移動など)リロケーションの申請を希望する、この時のユーザーはそう、ようにいくつかの個人情報、連絡先情報、古いアドレス、新しいアドレスとを記入する必要があります我々は彼に達し、彼は移転を完了することができます。現時点では、このページには、フォームに編成情報に基づいて関連性があります。

 

あなたが見ることができ、ページ自体はのPageObjectを抽出することが、私たちには非常に便利である、比較的明確な組織されています。各ブロックは、セクションクラスのサブクラスとして抽出することができます。

 

3.1最初の試み

例えば、個人情報の一部のためのもの:

 

このブロックは、以下のように、我々は簡単に対応するページ要素を見つけ、抽出することができ、いくつかの部品アドレス、名前、生年月日などが含まれています。

1 
2
3
4
5
6
7
8
9
10
11
12
13
14
class PersonalSection < SitePrism::Section
element :myservice, "#personal-my-services"
element :title, "#personal\\.title"
element :first, "#personal\\.firstName"
element :last, "#personal\\.lastName"
element :dob_day, "#personal\\.dobDay"
element :dob_month, "#personal\\.dobMonth"
element :dob_year, "#personal\\.dobYear"
element :summary, ".tms-accordion-summary-content"
element :next, ".tms-btn-next"
end

最も直接的な方法は、直接法を使用することですセットを呼び出します。

1
2
3
4
5
6
7
8
9
10
11
12
def fulfill_personal
@moving.personal.myservice.set "MINE"
@moving.personal.title.select "Mr"
@moving.personal.first.set "Juntao"
@moving.personal.last.set "Qiu"
@moving.personal.dob_day.select "21"
@moving.personal.dob_month.select "Jan"
@moving.personal.dob_year.select "1985"
@moving.personal.next.click
end

这样在Cucumber测试中就可以写成:

1
2
3
4
5
6
7
8
Given /I am on moving home page/ do
@moving = MovingHome.new
@moving.load
end
When /I fulfill my personal information/ do
fulfill_personal
end

3.2 面向对象

这样的代码事实上已经沦为了面向过程的方式了,更好的做法是讲fulfill_personal放入Personal本身中:

1
2
3
4
5
6
7
8
9
10
11
def fulfill(personal)
myservice.set personal["myservice"]
title.select personal["title"]
first.set personal["first"]
last.set personal["last"]
dob_day.select personal["dob_day"]
dob_month.select personal["dob_month"]
dob_year.select personal["dob_year"]
next_button.click
end

这样,外部的使用者只需要调用即可:

1
2
fixture = YAML::load_file('fixtures/moving.yml')
@moving.personal.fulfill(fixture["personal"])

对应的moving.yml文件定义如下:

1
2
3
4
5
6
7
8
personal:
myservice: "MINE"
title: "Mr"
first: "Juntao"
last: "Qiu"
dob_day: "1"
dob_month: "Jan"
dob_year: "1985"

3.4 Misc

为了达到视觉效果,UI上通常会有一些延迟的效果。比如点击一个按钮,在100ms之后弹出一个对话框,但是这种效果会导致测试的随机失败。

为了解决这个问题,我们可以通过给元素添加wait_until_前缀来等待。比如我们的测试中,在点击了下一步的按钮之后,预期有一个查看收费详情的对话框出现。根据一般的实现方式,这个对话框是预先写在页面上的,然后在合适的实际通过JavaScript将其显示在页面上(这样我们就不能通过查看该元素是否存在在页面上来编写断言了)。

 

1
element :lightbox_view_fees, "#tmsLBViewFees"
1
2
3
Then /I can see the lightbox View Fees shows up/ do
@moving.wait_until_lightbox_view_fees_visible
end

--04--

最后的结论

 

通常,我们的UI测试会和特性描述写在一起,以Cucumber为例,在feature文件中,我们会编写诸如这样的描述:

1
2
3
4
5
6
Feature: Platinum Move
Scenario: Platinum Move
Given I am on moving home page
When I select to move my service "Foxtel from Telstra"
And I select a "Telstra technician install"
Then I can see the lightbox "View Fees" shows up

而一个良好的实现,我是说,像feature描述一样清晰的实现,可能是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Given /I am on moving home page/ do
@moving = MovingHome.new
@moving.load
end
When /I select to move my telstra service "([^"]*)"/ do |selected|
setup_data
@moving.service.fulfill selected
end
Then /I can see the installation form/ do
expect(@moving).to have_move_service
end
Then /I cannot see the installation form/ do
@moving.move_service.should_not be_visible
end
And /I select a "([^"]*)"/ do |install|
@moving.move_service.select_install install
end
Then /I can see the lightbox "([^"]*)" shows up/ do |name|
@moving.lightbox(name).should be_visible
end

基本上,每个step仅仅对应1行(或者很少的几行)代码,而这些代码背后有一组组织良好的PageObject。

 


作者:邱俊涛

原文地址:http://icodeit.org/2015/01/page-object-with-site-prism/


 

おすすめ

転載: www.cnblogs.com/VVsky/p/11375473.html
おすすめ