概要
とあるRailsアプリに急遽とあるライブラリが必要となりました。
関連するgemをgithubで検索したりぐぐってもヒットしないため、自作することにしました。
ソースコード・ライブラリはgithubやrubygemsに公開しています。
開発したgem: niwa_textream
Yahoo! Textreamをスクレイピングするgemを開発しました。
ミーハーなので、Selenium等で流行りのPage Object Patternを適用してみました。
- 言語:ruby
- テスト:RSpec
- CI:Travis CI
- コーディングルールチェック:Rubocop
$ bundle gem niwa_textream -t #gem(niwa_textream)の雛形を作る
$ vim niwa_textream/niwa_textream.gemspec # gemspecを編集する。TODOを書き換える。
niwa_textream.gemspec
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'niwa_textream/version'
Gem::Specification.new do |spec|
spec.name = "niwa_textream" # ライブラリ名を書き換える
spec.version = NiwaTextream::VERSION
spec.authors = ["niwatolli3"] # authorsを書き換える
spec.email = ["niwatolli3@gmail.com"] # 自分のメアドに変える
spec.summary = %q{A scraping library for Yahoo! Textream} #summaryを書く
spec.description = %q{NiwaTextream provides scraping feature for Yahoo! Textream.} # descriptionを書く
spec.homepage = "https://github.com/niwatolli3/niwa_textream" #urlを記述。今回はgithubにソースを公開したため、githubのurlを記述
spec.license = "MIT" # ライセンスを記述
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
# to allow pushing to a single host or delete this section to allow pushing to any host.
if spec.respond_to?(:metadata)
spec.metadata['allowed_push_host'] = "https://rubygems.org" # rubygems.orgにpushできるようにするため
else
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
end
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.12"
spec.add_development_dependency "rake", "~> 10.0"
# for test
spec.add_development_dependency "rspec" # rspecを使うため追記
spec.add_development_dependency "codeclimate-test-reporter" # 追記
# for this gem
spec.add_dependency "nokogiri" # 依存するライブラリを追記
spec.add_dependency "mechanize" # 依存するライブラリを追記
end
Gemを実装する
lib/niwa_textream.rb
require "niwa_textream/version"
require "mechanize"
%w[ models/category pages/top/top_page pages/category/category_page ].each do |file|
require "niwa_textream/#{ file }"
end
module NiwaTextream
end
今回は1つのPageを実装する度にテストコードを追加したうえでgithubにpushしました。
githubにpushされるとTravis CIにフックがかかり、リグレッションテストが実行されるようにしました。
CIを回すことでデグレを防ぎ、また効率よく開発することができました。
テストコードの一例
spec/pages/thread_page/thread_page.rb
require "niwa_textream/pages/top/top_page"
describe 'ThreadPage' do
before :all do
mecha = Mechanize.new
NiwaTextream::TopPage.goTo(mecha)
@topPage = NiwaTextream::TopPage.new(mecha)
cat_name = '野球実況'
@categoryPage = @topPage.clickCategory(cat_name)
@threadPage = @categoryPage.clickCategory('副音声')
@threads = @threadPage.threads
end
describe 'thread' do
it 'have more than 1 threads' do
expect(@threads.count).to be >= 1
end
it 'have title (not empty' do
expect(@threads[0].title).not_to be ""
end
it 'have more than 1 comment' do
expect(@threads[0].num_comment).to be >= 1
end
it 'have last updated time (DateTime)' do
expect(@threads[0].last_updated).to be_kind_of(DateTime)
end
it 'have elem' do
expect(@threads[0].elem).not_to be nil
end
it 'have no prev page link' do
expect(@threadPage.prev_page_elem).to be_nil
end
it 'have next page link' do
expect(@threadPage.next_page_elem).not_to be_nil
end
it 'can go to next page and prev page link will appear' do
@threadPage = @threadPage.clickNextPage
# the prev link will appear
expect(@threadPage.prev_page_elem).not_to be_nil
# the next link will appear
expect(@threadPage.next_page_elem).not_to be_nil
@threadPage = @threadPage.clickPrevPage
end
it "can go to next page and the first post's date is older than the 1st page's last post" do
first_last_post = @threads.last
@threadPage = @threadPage.clickNextPage
next_first_post = @threadPage.threads.first
expect(next_first_post.last_updated).to be <= first_last_post.last_updated
end
end
end
rubygems.orgにpush する
$ git add . -A
$ git commit -m "hi"
$ rake build # gemファイルを生成する
$ curl -u [username] https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials # credentialを保存する
$ gem push niwa_textream-0.1.0.gem
オフィシャルのドキュメントによれば、数分で公開されるようです。
https://rubygems.org/gems/niwa_textream
公開されました。めでたしめでたし。