前回の投稿(http://sakaimo.hatenablog.com/entries/2014/12/29) では、JAVAで書かれていたコードをRubyでやってみました。この段階では「操作」の自動化だったので、今回はRSpecで「テスト」の自動化にチャレンジしてみました。
まだまだリファクタの余地はありそうなのですが、スキル不足によりひとまずここまで。。。
こゆソースコードはGitHubとかで公開したほうがいいのだろうけど、GitHubの使い方がわかんないので後回し><
- 私の環境
- macOS 10.10.1
- ruby 2.0.0p481
- rspec 3.1.7
- FireFox 34.0.5
試すときはWordPressのアカウトを取って、spec_helper.rb の中身を変えてください。
ディレクトリ構造
ディレクトリ構造
E2ETest
└ pages
└ add_new_post_page.rb
└ admin_login_page.rb
└ all_posts_page.rb
└ base_page.rb
└ delete_post_page.rb
└ edit_post_page.rb
└ spec
└ spec_helper.rb
└ test_spec.rb
pagesの中身
add_new_post_page.rb
require File.expand_path(File.dirname(__FILE__) + '/base_page')
class AddNewPostPage < BasePage
def initialize(driver)
@driver = driver
@url = "#{BASE_URL}/wp-admin/post-new.php"
end
# ページの機能
# 記事の新規投稿をする
def add_new_post(titlestr, description)
@driver.switch_to.frame("content_ifr") #WYSIWYGではframeの切り替えが必要
body.send_keys(description)
@driver.switch_to.default_content
title.send_keys(titlestr)
publish_btn.click
end
# ページの要素
private
def body
return @driver.find_element(:id, "tinymce")
end
def title
return @driver.find_element(:id, "title")
end
def publish_btn
return @driver.find_element(:id, "publish")
end
end
admin_login_page.rb
require File.expand_path(File.dirname(__FILE__) + '/base_page')
class AdminLoginPage < BasePage
def initialize(driver)
super(driver)
@url = "#{BASE_URL}/wp-admin/"
end
# ページの機能
# 一気にログイン処理しちゃう
def login
email.clear
email.send_keys(LOGIN_ID)
pwd.clear
pwd.send_keys(LOGIN_PW)
login_button.click
# ログイン後にはAllPostPageに遷移する
return AllPostsPage.new(@driver)
end
# ページの要素
private
def email
return @driver.find_element(:id, "user_login")
end
def pwd
return @driver.find_element(:id, "user_pass")
end
def login_button
return @driver.find_element(:id, "wp-submit")
end
end
all_posts_page.rb
require File.expand_path(File.dirname(__FILE__) + '/base_page')
class AllPostsPage < BasePage
def initialize(driver)
super(driver)
@url = "#{BASE_URL}/wp-admin/edit.php"
end
# ページの機能
# 記事の作成
def create_new_post(title, description)
# 新規作成画面に遷移
add_new_post.click
# 作成画面のPageObjectを作成+投稿
new_post = AddNewPostPage.new(@driver)
new_post.add_new_post(title, description)
end
# 投稿の編集
def edit_post(present_title, new_title, description)
# 指定されたタイトルの詳細画面に行く
go_to_paticular_post_page(present_title)
edit_post_page = EditPostPage.new(@driver)
edit_post_page.editPost(new_title, description)
end
# 投稿の削除
def delete_post(title)
# 指定されたタイトルの詳細画面に行く
go_to_paticular_post_page(title)
delete_post_page = DeletePostPage.new(@driver)
delete_post_page.delete_post
end
# 一覧画面での投稿のフィルタリング
def filter_posts_by_category(category)
# 本にも載ってないので割愛。あとで書いてみるかもしれない。
end
# 投稿の検索
def search_in_posts(search_text)
# 本にも載ってないので割愛。あとで書いてみるかもしれない。
end
# 投稿数の取得
def get_all_posts_count
return posts_container.find_elements(:tag_name, "tr").size
end
# 指定した文字列のタイトルが存在するかを返す(もっとうまいやり方ありそう)
def title_present?(title)
all_posts = posts_container.find_elements(:class_name, "row-title")
result = false
all_posts.each do |ele|
if ele.text == title
result = true
break result
end
end
return result
end
# ページの要素
private
def add_new_post
return @driver.find_element(:link_text, "新規追加")
end
# 各記事タイトルの要素(という言い方でいいのかな)をすべて取得
def posts_container
return @driver.find_element(:id, "the-list")
end
# 指定した投稿の編集ページに遷移するメソッド
def go_to_paticular_post_page(title)
all_posts = posts_container.find_elements(:class_name, "row-title")
all_posts.each do |ele|
if ele.text == title
ele.click
break
end
end
end
end
base_page.rb
class BasePage
def initialize(driver)
@driver = driver
@url = ""
end
# ページを開く
def open
@driver.get(@url) unless @driver.current_url == @url
end
end
delete_post_page.rb
require File.expand_path(File.dirname(__FILE__) + '/base_page')
class DeletePostPage < BasePage
def initialize(driver)
@driver = driver
end
def delete_post
move_to_trush.click
end
private
def move_to_trush
return @driver.find_element(:link_text, "ゴミ箱へ移動")
end
end
edit_post_page.rb
require File.expand_path(File.dirname(__FILE__) + '/base_page')
class EditPostPage < BasePage
def initialize(driver)
@driver = driver
end
def editPost(str_title, str_description)
@driver.switch_to.frame(content_frame) #frameの切り替えが必要
body.clear
body.send_keys(str_description)
@driver.switch_to.default_content
title.clear
title.send_keys(str_title)
publish_btn.click
end
private
# WYSIWYGのiframe
def content_frame
return @driver.find_element(:id, "content_ifr")
end
# 本文入力欄
def body
return @driver.find_element(:id, "tinymce")
end
# タイトル入力欄
def title
return @driver.find_element(:id, "title")
end
# 更新ボタン
def publish_btn
return @driver.find_element(:id, "publish")
end
end
specの中身
spec_helper.rb
require 'selenium-webdriver'
require 'pry'
Dir[File.expand_path("../../pages/", __FILE__) << '/*.rb'].each do | file |
require file
end
# 定数
BASE_URL = "https://xxx.wordpress.com"
LOGIN_ID = "イーメール"
LOGIN_PW = "パスワード"
test_spec.rb
describe "ログインして書いて編集して削除するシナリオ" do
before :all do
@driver = Selenium::WebDriver.for :firefox
end
after :all do
@driver.quit
end
it "正しいID/PWでログインできること" do
login_page = AdminLoginPage.new(@driver)
# ログインページを開く
login_page.open
# ログインする
login_page.login
# 今回はtitleに「ダッシュボード」という文字列が含まれているかで比較
expect(@driver.title).to include "ダッシュボード"
end
it "記事の投稿ができること" do
all_posts_page = AllPostsPage.new(@driver)
all_posts_page.open
# 記事の投稿
all_posts_page.create_new_post("タイトル1", "本文1")
# 記事一覧画面に行って、登録したタイトルが表示されているか、で判定(もっといい方法あるかも)
all_posts_page.open
result = all_posts_page.title_present?("タイトル1")
expect(result).to be_truthy
end
it "記事の編集ができること" do
# 記事の編集
all_posts_page = AllPostsPage.new(@driver)
all_posts_page.open
# 記事の編集
all_posts_page.edit_post("タイトル1", "タイトル2", "本文2")
# 記事一覧画面に行って、編集したタイトルが表示されているか、で判定(もっといい方法がありそう)
all_posts_page.open
result = all_posts_page.title_present?("タイトル2")
expect(result).to be_truthy
end
it "記事数の取得" do
all_posts_page = AllPostsPage.new(@driver)
all_posts_page.open
result = all_posts_page.get_all_posts_count
expect(result).to eq 1 # テスト開始時に投稿数がゼロとした
end
it "記事の削除ができること" do
# 記事の削除
all_posts_page = AllPostsPage.new(@driver)
all_posts_page.open
all_posts_page.delete_post("タイトル2")
# タイトル2へのリンクが無いことをもって判断
all_posts_page.open
result = all_posts_page.title_present?("タイトル2")
expect(result).to be_falsey
end
end
実行する
E2Etestディレクトリにいる状態で実行
前提として、既存の投稿数はゼロにしておく
E2Etest sakaimo$ rspec -fd spec/test_spec.rb
ログインして書いて編集して削除するシナリオ
正しいID/PWでログインできること
記事の投稿ができること
記事の編集ができること
記事数の取得
記事の削除ができること
Finished in 49.57 seconds (files took 0.32554 seconds to load)
5 examples, 0 failures
- 絶対もっと良い書き方があるはず。。。