Ruby on Rails開発のインターン (Day 21)
こんにちは、皆さん!
今日は引き続き、マップのバグの修正と最近のバグ修正で発生した新たなバグに取り掛かろうと思う。
- トピック:
- 疑問:
- 422エラーをわざと起こすにはどうしたらいいのか?
- 問題:
- アドミンとしてサインインしようとすると、422エラーが発生する
- 学習した内容:
- 422エラーの存在と曖昧だがその要因
- 今後やってみたいこと:
- リソース:
422エラーとは?
このサイトの情報が役に立つかもしれません↓↓
developer.mozilla.org
先に述べたエラーのほかに422エラーたるものが存在し、HTTPリクエストが正しく機能し、コード中の関数にも問題がないうえ、データ処理がうまくいかなかったときに起きるそうだ。ここまではあくまで予想だが、職場のアドミンサインインがうまくいってないのはデータベースに本来はない何かがどこかのタイミングで追加されたからではないかと思っているところ。とりあえず、どこで問題が起きているのかもよくわからないから解決もなかなかきついって感じだな。
追記***
後になって、環境変数の設定に問題があったのだと判明した。しかし、一気に環境変数を刷新したのでどの特定の環境変数が問題を起こしていたかまではわかっていない...。
まとめ
後は、マネージャーが早くエラーの確認をして、明日にはマップのテストに戻らせてくれればいいな
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 20)
こんにちは、皆さん!
これは職場で起きた最も恥ずかしいことだと思う...。寝坊して、勤務開始時間を越してから起きてしまったという。なんとまあ...。自分の不注意さに関しては本当にマネージャーに申し訳ないなと感じてるところ。遅くまで起きているのはいつでも悪いことだね(笑)
今後は、もう少し自分に寝る時間を与えてあげたいね(笑)。
- トピック:
- 疑問:
- OwlCarouselでCarouselのように自動で写真をスライドするにはどうすればよいのか?
- 問題:
- 学習した内容:
- OwlCarousel はスマホ対応のCarouselを提供してくれるジェムである
- 今後やってみたいこと:
- OwlCarouselを自分のアプリケーションで使う
- リソース:
OwlCarouselとは何か?
OwlCarouselはルビージェムの一つでスマホ対応のCarouselを提供するものである。まあ、通常のBootstrapのCarouselとは少し違う部分もあるけど...。
ここにあるのがOwlCarouselのデモサイト。ぜひ、どんなものなのか試してみてください。
おそらく、スマホでも扱いやすいドラッグとスワイプ機能が見受けられるでしょう。これらはBootstrapのCarouselでは実行されていないので、スマホにやさしいウェブにしたいのなら検討したいところかと思われる。
OwlCarouselで簡単なアプリを作る
完成品がこちら↓↓
Railsにおいてowlcarouselを使った簡単なデモ
まとめると、すごいシンプルなものだった。でも、とりあえず、始める前にjquery-rails
ジェムがしっかりインストールされていることを確認しよう。(リンク)
まずはGemfile
にジェムを追加
gem 'owlcarousel-rails'
そして、bundle install
.。で、ここで以下の二つのファイルに必要なコンテンツが含まれるように設定したいので下記のコードを追加していく。
まずは、下記のをapp/assets/javascript/application.js
に追加
//= require owl.carousel
そしたら、今度は下記の2行をapp/assets/stylesheets/application.css
に追加
*= require owl.carousel *= require owl.theme
これでセットアップは完了!
あとは、以下のように簡単にスライドを作ることができる。(内容は自分の好きなものにしましょう)
<div class="owl-carousel"> <div> Your Content </div> <div> Your Content </div> <div> Your Content </div> <div> Your Content </div> <div> Your Content </div> <div> Your Content </div> <div> Your Content </div> ... </div>
それで最後に内容を定義した直後に下記のjQueryコードを入れれば動きは完成!!
<%= javascript_tag do %> $(".owl-carousel").owlCarousel(); <% end %>
そしたら、ローカルでテストしてみよう(これでうまく機能するはず)。
まとめ
Gemfile
にも入っていたが、まだ実装していないようだが、おそらく写真を表示するときに使うのではないかと思っている。とりあえず、新しくて面白そうなもの見つけた気がするので、試していこうかな(笑)。ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 19)
こんにちは、皆さん!
5つ目の週がやってた。もうインターンの半分以上が終わった。最近、少しばかり自分がここまでやってきた内容に関して思い返すことがあるが、随分たくさんことを習わせてもらったなと思う。ジェムのGithubのREADMEがどれだけ役に立つのか、Trelloを使ってやることリストを管理するのがどれだけ便利なのか、グーグルマップの実装方法、便利なジェムの存在、そして、RspecとCapybaraを使ったテストなど学んだ内容がとにかく豊富。
ここからもインターンを最大限に活用できるように日々集中して、残りのインターンをやり切りたいと思う。
- トピック:
- 疑問:
- 問題:
- 学習した内容:
- Fakerジェムは様々な種類のランダムデータを作ることができ、特にテストを実行する際に役に立つ
- 今後やってみたいこと:
- Fakerで何か面白いものを作る
- リソース:
Fakerジェムでランダムなデータを作る方法
これは結構面白いジェムで、使えるランダムデータを作成してくれるという。主な活用方法といえばランダム名前登録またはテスト用の辺が浮かぶ。
職場ではこれをテストの時に使うデータ作成のために使っているのを見かけた。そうすることで、テストされるデータに偏りが出ず、様々なテストがパスするはずの値をいちいち打ち出すことなく使うことができるのだ。
さて、そんな便利なジェムをインストールするには、以下のをGemfile
に入れて、
gem 'faker'
bundle install
をコマンドで実行するだけ!
そしたら、ランダムデータを使いたいファイルの中でFakerのものを使う下記のようなコードを書くことができる
require 'faker' Faker::Name.name #=> "Christophe Bartell" Faker::Internet.email #=> "kirsten.greenholt@corkeryfisher.info"
例えば、Rspecの中でFakerを使いたいのなら、
# この部分だけはspec_helper.rbに入れた方がいいかもしれない require 'faker' RSpec.describe User do describe "valid user" do it "successfully create a user" do user_name = Faker::Name.name user = User.new(name: user_name) expect(user).to be_valid end end end
僕の場合、これで"Harry Stark"という名前が作られた。設定次第でこれを成功とするか失敗とするかはあなた次第だが、僕の場合は苗字と名前の間にスペースがあるだけでいいという設定だったため成功という結果になった。
このコードなら毎回テストを行うたびに異なるユーザーでテストすることができて、テストの信頼性が上がるということだ。
まとめ
それで、その間、Gemfileをもっと詳しく調べてみたら、Fakerというおもしろいジェムを見つけた。このジェムは本当に様々な値を定義してあって、すぐに使い始めれる気がした。このようなジェムが存在するとは思ってもいなかった(笑)。Railsがどれだけ便利なのか改めて気づいたよ。
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 18)
こんにちは、皆さん!
ついに今週もラスト1日!
昨日に引き続き、職場のプログラムでcapybaraテストが実行できるようにエラーの原因を探そうと思う。
- トピック:
- 疑問:
- 問題:
- capybaraテストが職場のプログラムで実行されない (解決した)
- 学習した内容:
- テストの時に新しく追加されたデータを自動的に削除する方法
- 今後やってみたいこと:
- Railsの'will-paginate'についてもっと学習する
- リソース:
Railsでdatabase cleanerを使う方法
この目的のためにとても便利なジェムがある。そして、使い方も簡単。2ステップで完了。
***ここではRspecの場合だけについて言及する。CucumberとMinitestユーザーの方々すいません。***
最初に、ジェムのインストール。Gemfile
に下記のを入れて、 bundle install
コマンドを打ってください。
group :test do gem 'database_cleaner' end
これをテストのグループに入れたのは同じデータをキープするためにデータベースのお掃除をするのはテスト環境の時だけでいいからだ。
次に、データベースお掃除の設定を書いていく。これは簡単で基本的には下記のをspec/spec_helper.rb
ファイルに入れればよい。
RSpec.configure do |config| config.before(:suite) do DatabaseCleaner.strategy = :transaction DatabaseCleaner.clean_with(:truncation) end config.around(:each) do |example| DatabaseCleaner.cleaning do example.run end end end
この設定はdb/seeds.rb
の状態に還元するというものだ。つまり、新しく追加されたデータのみが削除されるということだ。 これは便利!!
おまけ:
もし、capybaraテストも使っているのなら、上記に挙げた設定の代わりに、下記のものを使った方がいい。capybaraテストで作ったデータがテストされる前に削除されてしまう可能性があり、エラーの原因になりかねないからだ。
***必ずrequire 'capybara/rspec'
の後に下記のを入れてください!***
RSpec.configure do |config| config.use_transactional_fixtures = false config.before(:suite) do if config.use_transactional_fixtures? raise(<<-MSG) Delete line `config.use_transactional_fixtures = true` from rails_helper.rb (or set it to false) to prevent uncommitted transactions being used in JavaScript-dependent specs. During testing, the app-under-test that the browser driver connects to uses a different database connection to the database connection used by the spec. The app's database connection would not be able to access uncommitted transaction data setup over the spec's database connection. MSG end DatabaseCleaner.clean_with(:truncation) end config.before(:each) do DatabaseCleaner.strategy = :transaction end config.before(:each, type: :feature) do # :rack_test driver's Rack app under test shares database connection # with the specs, so continue to use transaction strategy for speed. driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test unless driver_shares_db_connection_with_specs # Driver is probably for an external browser with an app # under test that does *not* share a database connection with the # specs, so use truncation strategy. DatabaseCleaner.strategy = :truncation end end config.before(:each) do DatabaseCleaner.start end config.append_after(:each) do DatabaseCleaner.clean end end
まとめ
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 17)
こんにちは、皆さん!
今日はついに実際に使っているマップにテストを書いていこうと思う。ここまではずっとcapybaraテストを勉強する用のアプリに書いてきた。さあ、ここから習ったものを使って実際に使用するものに反映していこう。
- トピック:
- 疑問:
- 問題:
- 学習した内容:
- capybaraテストからCSSの値を引き出す方法
- Rubyでsubstringする方法
- capybaraテストでJavaScriptを実行する方法
- マップ上のすべてのマーカーを返してくれる関数はないので、マーカーを足すときに配列などどこかにそのコピーを持っておいてそこからマーカーにアクセスできる
- 今後やってみたいこと:
- リソース:
capybaraテストでCSSの値にアクセスする方法
最初に、div#map
(IDが"map"のdivタグ)にあるマップにアクセスしたかった。
それで、下記のようにアクセスした。
find('#map')
そして、次はそこからスタイルを取り出す方法。これに関しては全くリソースが見当たらなかった。
find('#map').style('width')
結構適当にあてずっぽうで行ったところもあるが、これでスタイルにアクセスすることができた。
style.width
のようにドットとスタイル名でアクセスするJavaScriptとは違って、スタイル名を()の中に入れる。
それを変数に入れて、後で使う。
map_width = find('#map').style('width')
とここで、うまくいかなかったので、とりあえず、この変数の内容をアウトプットしてみた。驚くことにHashだったのだ。
{"width"=>"400px"}
ということで、改めて、実際の値を取り出す方法をHashのやり方に変えた。map_width['width']
みたいに。
ここまででも、なかなか複雑だが、さらに、面倒くさいことに得られた値には"px"がついているので、数字として運用するにはさらにこれを取り除く必要がある。
# 横幅のHashにアクセス map_width_hash = find("#map").style("width") # 横幅の値の文字列版を入手 map_width_string = map_width_hash['width'] # 数字の値にするためにpxをカットして、そのあとにそれをintegerに変換する map_width = map_width_string[0..(map_width_string.length-2)].to_i
ちなみに、ここでRubyにおいてどうやってsubstringをやるのか学んだ(笑)
capybaraテストでJavaScriptを実行する方法
やり方は簡単。下記のような関数をcapybaraテストの中に入れればよい。
page.execute_script("example('Hello')")
この例だと、"example"という名前の関数を'Hello'という引数を入れたものを実行する。
***ひとつ大事なことは実行したいJavaScriptのコードがcapybaraテストで訪れるサイト内でアクセスできるようにしなければならないということ!! 僕の場合は直接map.html.erb
に入れた。(パイプラインを使っている人は大丈夫だと思う)***
まとめ
結局、職場のプログラムでcapybaraテストによるマップのテストはまだうまくいかなかったが、最終的なアイデアをしっかりコード化できた。
本当のマップは少しばかり複雑なので、もう少しコードを書くのに時間がかかりそう。うまくここまでやってきたコードが直結するといいな。
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 16)
こんにちは、皆さん!
今日はどうやったらグーグルマップ上でマーカーをクリックするのかを見つけようと思う。これは以前のに比べれば、そんなに難しくはないだろうと思うが、後でマーカーから出た情報をもとにテストを書くのに少し時間がとられる気がする。あんまり時間を取られすぎなければいいが。
- トピック:
- 疑問:
- 問題:
- capybaraでグーグルマップ上のマーカーをクリックする方法を探す
- 学習した内容:
- capybaraで自動でスクショを取る方法
- 今後やってみたいこと:
- リソース:
- Testing Your App In The Browser With Capybara (Rails Backend, React Frontend)
- GitHub - mattheworiordan/capybara-screenshot: Automatically save screen shots when a Capybara scenario fails
- How can I click on a google map with capybara to create a marker - Stack Overflow
capybaraでスクショをとる
僕が試しに直接page.save_screenshot('screenshot.png')
というコードをposts_controller_spec.rb
内で実行しようとしたら、失敗して、下記のエラーメッセージが出てきた。
Selenium::WebDriver::Error::WebDriverError: Unable to find Mozilla geckodriver. Please download the server from https://github.com/mozilla/geckodriver/releases and place it somewhere on your PATH. More info at https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver.
それで、このサイトにある指示通り、インストールしたのち、 今度はこの
$ export PATH=$PATH:/usr/local/bin/ $ whereis geckodriver geckodriver: /usr/local/bin/geckodriver
ここまで設定ができたら、capybaraテストを実行したときに、URLの左側にロボットのマークが表示されるはず。これはロボットが自動でそのページに指定された行動をとることを表す。そして、私たちはその一連の動作をこのページでライブで見れるということだ。
そして、そのデモが終わると、スクショが/tmp/capybara/screenshot.png
で見つかるでしょう。このフォルダーは.gitignore
でネット上には送られないようになっているので、心配無用。(まあ、でも、逆に見つけにくかったけど笑)
僕は下記のコードで実行して、クリックした後にボタンの内容が"Thank you"に変わるというコード。
<div id="map" style="width: 400px; height: 400px;"></div> <button id="button" onclick="changeContent()">Click Me!</button> <%= javascript_tag do %> function initialize(){ var map_center = new google.maps.LatLng(51.5, -0.12); var map = new google.maps.Map(document.getElementById('map'), {zoom: 15, center: map_center}); var center_marker = new google.maps.Marker({position: map_center, map: map}); var info = "<p>Success!</p>"; var infowindow = new google.maps.InfoWindow({ content: info }); center_marker.addListener('click', function(){ infowindow.open(map, center_marker) }); } function changeContent(){ document.getElementById('button').innerHTML = "Thank you"; } <% end %>
下のは実際にcapybaraに撮られたscreenshot.png
。"Click Me!"が"Thank you"になっているのが確認できる。よって、テスト成功である
capybara-screenshotジェムを使ってより簡単にスクショ機能を実装する方法
ところで、もっと簡単にスクショを取る方法を見つけた。それはcapybara-screenshot
ジェムを使うことだ。使うためにはまず、Gemfile
に下記のようにジェムを入れる。
gem 'capybara-screenshot', :group => :test
僕はRspecを使っているからここより先の内容はRspecを使う際のインストラクションになる。ほかの媒体を使う場合はこのサイトを参照にしてください。
そしたら、rspec_spec.rb
の中に下記のを入れる (僕の場合、require 'capybara/rspec'
を他のところからインポートしているが、下記のを入れるときは必ずrequire 'capybara/rspec'
より下に入れてください。)
require 'capybara-screenshot/rspec'
そしたら、もうスクショをとるためのコードを書く準備は整った!
僕の場合は、下記のを古いバージョンのスクショと入れ替える感じでposts_controller_spec.rb
に追加した。
Capybara.save_path = "app/assets/images" Capybara::Screenshot.screenshot_and_save_page
1行目はスクショがどこに保存されるかで、2行目のコードでスクショを保存する。
そしたら、驚くことにスクショだけでなく、ディベロッパーツールで表示されるhtmlコードまでもがapp/assets/images
に保存されていた。
僕がcapybaraでグーグルマップ上のマーカーをクリックさせた方法
within_frame(locator_of_frame_with_map) do map = find(locator_of_map).native page.driver.browser.action.move_to(map, x, y).click.perform end
まあ、でも、これはなぜだかわからないが残念ながらうまくいかなかったので、within_frame
のくくりを消した。また、僕は下記のようにマップを実行しているから、
<div id="map"></div>
下記のようにルビーコードを書いた
map = find('#map').native page.driver.browser.action.move_to(map, 200, 190).click.perform
説明はこうだ:
- 1行目でマップオブジェクトにたどり着く。よって、2行目でマップに何かできる。
- 2行目でマウスを(x, y)=(200, 190)のポイントに行かせた。これは400x400のマップの中心のやや上である。
- この場所を選んだ理由はそこがちょうどマップの中心に位置するマーカーのクリックできるところであるからだ。
- そして、その場所でcapybaraにクリックをさせる。これはつまりマーカーの詳細を表示するようにしたことになる。
最初はマップ内の座標を得ようと思ったが、できず、考えてみた結果、僕たちがマップ上にクリックするときだって画面の中心という感じでしか画面上のものをとらえることはできないから、このxとyの座標はすごく腑に落ちた。
以下がcapybaraテストの結果:
さらに、マップ上の複数のマーカーをクリックさせるという内容も実行した。解決法はいたってシンプルで、僕がマーカーオブジェクトにアクセスでき、そこからマーカーの位置を知ることができるから、マップの中心をその新しいマーカーの位置にずらすことで先ほどと同じ場所をもう一回クリックすればいいのだ。
下記のビデオにこの時、自動で複数のマーカーを1個ずつクリックしたものが記録されている。
CapybaraとRspecでGoogle mapのテスト!
まとめ
明日はこのcapybaraテストの内容を職場のプログラムに組み込めれるようにがんばりたい。明日もいいことありますように!!
ご精読ありがとうございました。では、また次回まで✌
Ruby on Rails開発のインターン (Day 15)
こんにちは、皆さん!
今日もまた天気のいい日。今日はcapybaraテストのシンタックスを勉強して、本題に入れるようにがんばる。
- トピック:
- 疑問:
- 問題:
- グーグルマップにおいて、capybaraでマーカーをクリックする
- 学習した内容:
- どうやって簡単なcapybaraテストを書くか
- 今後やってみたいこと:
- capybaraでスクショをとる
- リソース:
Capybaraテストの基本フレーム
capybaraテストに関するビデオチュートリアルを発見(残念ながら、英語版)。それの内容を参考に下記が基礎的なフォームになる。
# spec/features/test_spec.rb require 'rails_helper' RSpec.feature "test" do scenario "test whether you can write out a proper test" do # your code here end end
実際のテストに入る前にrails_helper
する必要がある。 それと、通常、capybaraテストはspec/features
フォルダー内でファイルを作り、そこに書いていく。
いくつかの基礎的なcapybaraテストのシンタックス
https://github.com/Eric1015/capybara-post-test
それで、書いたコードは下記のもの:
# spec/features/posts_controller_spec.rb require 'rails_helper' RSpec.feature "adding post" do scenario "allow a user to add a post" do #パート1 visit posts_new_path #パート2 fill_in "Title", with: "Rspec Introduction" fill_in "Body", with: "This is my post about Rspec" #パート3 click_on("Create Post") #パート4 expect(page).to have_content("Rspec Introduction") expect(page).to have_content("This is my post about Rspec") end end
さあ、掘り下げていきましょう!!
最初に、visit posts_new_path
はその名の通り、 指定したURLに行くってこと。この場合、/posts/new
になる。
下の写真はこのページのスクショ。
見ての通り、"Title"と"Body"の2つのインプットがある。
次の部分はその2つのインプットに"Title"には"Rspec Introduction"を、そして、 "Body"には"This is the first post about Rspec"を入れる。これはつまり、下の写真通りのことを自動でやってくれるってこと。
そして、3つ目のパート、click_on("Create Post")
は"Create Post"というボタンを押してくれる。これはインプットした情報をもとに新しい投稿を作る(ポストというモデルを使用しているため)。その後、showアクションをとるようにしているため、 下記のような結果になる。
そして、最後のパート。ここで、初めてテスト(ここまではcapybaraにユーザーが実際に投稿を作る一連の操作をさせただけ)。テストの内容は今現在のページに2つのものが存在すること。それは、"Rspec Introduction"というテキストと"This is my post about Rspec"というテキスト。そして、確かにshowのページにこれらがあるため、無事にテストは成功という結果になる。
まとめ
とりあえず、明日は次のステージであるマップ内のマーカーのクリック方法を探っていこうと思う。早く方法を見つけれることを願う!
ご精読ありがとうございました。では、また次回まで✌