メドピア開発者ブログ

集合知により医療を再発明しようと邁進しているヘルステックカンパニーのエンジニアブログです。読者に有用な情報発信ができるよう心がけたいので応援のほどよろしくお願いします。

新人エンジニアが開発合宿に参加してみて@湯河原

こんにちは!メドピア10月入社の新米エンジニアの宮原です。 今回のブログでは、メドピアで恒例となっている開発合宿に参加してきましたので、こちらの様子をお届けしたいと思います。

メドピアでは、これまでにも年2〜3回ぐらいのペースで開発合宿を開催しています。湯河原で開発合宿を行うのは、昨年3月以来になります。

tech.medpeer.co.jp tech.medpeer.co.jp

合宿テーマ

開発合宿のテーマは毎回異なり、技術研鑽や技術的負債の解消、他にも新規サービス立ち上げ等を行ったこともあります。過去の開発合宿では新規サービス立ち上げをテーマに実施され、弊社のサービスとして事業化されているものもあります。

合宿に行く前に各自、取り組む内容について宣言してから開発します。今回はこんな感じです。

  • 業務改善ツールの開発
  • メドピア既存サービスへの新機能開発
  • 新技術を使ったサービス開発

取り組み方は自由でチームを組んでも良し。個人でモクモクと取り組むも良し。特に制約は無いので、自身が取り組みたかった開発がしやすいです。 後日、オフィスにて合宿に参加できなかったエンジニアやデザイナーさんたちへ、成果報告LTをすることになりました。

開発合宿向きの旅館「湯河原 おんやど 恵」さん

今回の合宿は湯河原の「おんやど 恵(めぐみ)」さんにお邪魔しました。メドピアでは過去の合宿でも利用させていただいております。こちらの旅館は、SE出身の社長さんが経営されている旅館で、エンジニアに嬉しい「開発合宿プラン」などが用意されています。お隣にコンビニができたこともあり、お酒やお菓子などの補給線が確保されより開発向きになりました。

f:id:nyagato_00_miya:20181212153651p:plain

おんやど恵み 開発合宿プラン

当日は、湯河原駅に直接集合!湯河原駅近くの「トルティーノ」さんでランチをとってから一同、おんやど恵へ向かいます。

f:id:nyagato_00_miya:20181212153942j:plain
総勢15名の参加となりました!

開発の様子

到着後すぐに会議室へ向かいます。各々合宿で取り組むテーマを発表し、いざ開発スタートです。

会議室には、電源タップ、USB充電器、おやつ、ホワイトボード、腰サポートグッズ等、設備も充実。開発スタートから、もくもく作業をする人もいれば、リフレッシュも兼ねて一足先に温泉に浸かりに行く人も。 ※ディスプレイのレンタルプランもあるそうです。

f:id:nyagato_00_miya:20181212154443j:plain
今回のテーマをそれぞれ発表し、いざ開発開始です
f:id:nyagato_00_miya:20181212154251j:plain

基本的に、食事・お風呂・就寝以外の時間は開発タイムです。初日から夜遅くまで開発に没頭するメンバーもいました。

f:id:nyagato_00_miya:20181212154705j:plain
斯く言う私も、モクモクしていました

湯河原ご飯レポート

※美味しそうなご飯の写真が続きます。空腹時の閲覧はご注意ください

f:id:nyagato_00_miya:20181212155007p:plain f:id:nyagato_00_miya:20181212155013p:plain f:id:nyagato_00_miya:20181212155017p:plain

f:id:nyagato_00_miya:20181212155021p:plain
十二庵さんの豆腐プリンは絶品でした

最終日にランチに行った「うおたつ」さんには足湯もありました。 湯河原では、"足湯駆動開発"が大変捗ります。

最終日

2泊3日の楽しい合宿を終え、成果発表を行います。
技術研鑽に務める人もいれば、がっつりと作り込みデモまでする人まで各々の成果が発表されました。今回の合宿では、最も優れた発表には商品が進呈される!とのことで、みんな気合の入った発表が多かった印象です。

f:id:nyagato_00_miya:20181212154900p:plain
合宿の成果が発表されました

画像認識に取り組んでみました

私は、“食品判別AI”を作ってみました。メドピアにはグループ会社からDiet Plusというアプリがリリースされています。ユーザーから送られてきた食べ物の写真を、管理栄養士さんが確認して健康サポートをしてくれます。
そこで、食品の判別は自動化できそうだなと考えていたこともあり、合宿でやってみることにしました。

学習データの加工や、ニューラルネットワークの構築に時間を要しましたがなんとか形にすることができました。 今回は、GCPにVMのインスタンスを立てて、この中でSystemd + Nginx + uWSGI + Flaskのアプリケーションを動かしています。

f:id:nyagato_00_miya:20181212173511p:plain
お寿司が正しく判別された様子。

TensorFlowのサンプルの中に、再学習するサンプルが用意されています。簡単に画像認識を試す場合は、こちらを活用してみてください。
便利なことにTensorFlowでは、dockerイメージが公開されています。こちらを活用することで、めんどうな環境構築を一瞬で終わらせることができます。
(公式から公開されていると安心感がありますね) https://www.tensorflow.org/install/docker

例えば、猫の分類など行ってみましょう。ロシアンブルー、ペルシャ、メインクーン、ベンガルなどの画像を10枚程度集め、それぞれディレクトリに入れます。 こちらのディレクトリを指定して再学習を実行します。

$ cd cats
$ python3 retrain.py --image_dir ~/cats

学習結果を確認するには、label_image.pyを使います。以下のファイルをGithubからダウンロードし、retrain.pyと同じディレクトリに置きます。 https://github.com/tensorflow/tensorflow/raw/master/tensorflow/examples/label_image/label_image.py

以下の様に、再学習で生成された学習データを活用して判定させます。

$ python3 label_image.py \
--graph=~/tmp/output_graph.pb \
--labels=~/tmp/output_labels.txt \
--input_layer=Placeholder \
--output_layer=final_result \
--image=/cats/test/test_cat.jpg

するとどうでしょう、入力した猫の画像から、猫の種類を判別してくれます。学習データが10数枚であれば、ローカル環境で十分学習させることが可能です。
例で述べさせていただいた内容は、公式にチュートリアルとして掲載されています。ぜひ、トライしてみてください。
https://www.tensorflow.org/hub/tutorials/image_retraining

まとめ

開発合宿では、普段の業務でなかなか取り組めないタスクや負債を潰したり、新しい技術に集中して取り組める絶好の機会だと思います。 また、2泊3日という短い時間で成果を出す必要があるので、自身がこの短期間にどこまで出来るかを確認できる良い機会でもあると思います。 以上!2泊3日のメドピア開発合宿@湯河原 おんやど 恵のレポートでした。

追伸

合宿後の発表会で、僭越ながら私が、kenzoさんと同着で表彰されました。 まさかの同着1位ということもあり、2人で商品同等額を山分けさせていただきました。
頂いた賞金は、HHKB 無刻印を買う軍資金にさせていただこうと思っています。


(☝︎ ՞ਊ ՞)☝︎是非読者になってください


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html

RubyWorld Conference2018にRubyスポンサーとして参加しました

こんにちは。メドピアのRailsエンジニアの小林です。遅くなってしまいましたが、11/1, 11/2に島根県松江市で行われたRubyWorld Conferenceに行ってきたので、レポートをお届けいたします。

2018.rubyworld-conf.org

多くの興味深いセッションが行われましたが、内容はRubyWorld Conferenceの公式YouTubeチャンネル*1から動画で見れるため、本記事では基調講演の大枠のまとめと、ブース出展の様子をお伝え致します。

今回、メドピアは初のブース出展(Rubyスポンサー)でした!そもそもRuby関連のイベントへのブース出展することが初なので、準備に手間取ることを予想して前日入りしました。

f:id:marikokobayashi:20181115235854j:plainf:id:marikokobayashi:20181116000544j:plain
f:id:marikokobayashi:20181115235910j:plainf:id:marikokobayashi:20181116000516j:plainf:id:marikokobayashi:20181116002319j:plain

1日目は開会挨拶と来賓挨拶からスタート。まずは島根県知事代理・松江市市長代理がいらっしゃってのご挨拶。島根県・松江市がRubyを使ったIT企業の支援に力を入れていることが伝わってきます。

Matzの基調講演 The power of the community

  • Rubyのこれまで歩んできた道
  • ピッケル本 (正式名: Programming Ruby: The Pragmatic Programmer's Guide、英語で初めて出版されたRuby本)の出版社のAddison-Wesleyから本を書きたいと連絡が来たときのお話
  • 最初のRubyConfのときのお話
  • Rubyのユーザー数の増加
  • Rubyコミュニティについて
  • Rubyのハイプサイクル
  • 「あきらめない」こと
  • 一歩踏み出すこと
  • Matzの引退とRuby4について(!)

などについて語っていただきました。

特にRubyコミュニティのお話が印象的でした。 もしRubyコミュニティが存在しなかったら、Rubyは今のような形では存在していなかっただろうとMatzはおっしゃいます。

Matzが発案したものではない機能が今ではRubyに欠かせないものとなっていますし、周囲の人がRubyのカンファレンスや勉強会の開催、Rubyの本の執筆等の活動をしたことでRubyは発展してきました。

RubyコミュニティはNiceなコミュニティです。

ですがRubyコミュニティの良いフィードバックをより長く強く維持していくために、Matzは「もう一歩だけ先に行ってほしい」と言っていました。

コンフォートゾーン、居心地が良い環境にいつづけるだけでは進歩がなくなってしまう。

新しいカンファレンスに出てみる、友だちを作ってみる、新しいことを試してみる、他の人を褒める、目を見て握手してみる、アイディアを出し合ってみる。そういったことをしてみて下さい、とのことでした。

「宿題を出します。カンファレンス全体で感じたことをなにかでシェアして下さい。ブログでもTwitterでもFacebookでもMediumでもQiitaでもいいのでシェアして下さい。皆さんにも一歩踏み出していただけたらいいなと思っています。それが未来を良くすると思います」とのことでした。

f:id:marikokobayashi:20181116000215j:plain

メドピアのスポンサーセッション(1日目のお昼)

メドピアのスポンサーセッションは1日目のお昼!CTOの福村が登壇しました。

f:id:marikokobayashi:20181116000247j:plainf:id:marikokobayashi:20181116000328j:plain

発表資料はこちらです。

メドピアの事業紹介、メドピアの働きやすい制度、それからエンジニア発信のしくみである「プルリク振り返り会」と、そこで過去に上がったTipsについて話してくれました。

今メドピアでは数多くのプロジェクトが走っており、PRが上がってきたら同プロジェクトのメンバーがPRをレビューするという体制になっています。

しかしそれだとプロジェクトを横断して全エンジニアが知っておいたほうが良い知識が共有されないので、そのようなPRを振り返って話すのが「プルリク振り返り会」です。この取り組みは他社のエンジニアさんとお話すると「良いね」と言ってもらえることが多いです。

気になるという方は、是非取り入れてみてください。また、取り入れた際は感想を共有してもらえると嬉しいです!

レセプション(懇親会)

1日目の最後にはレセプションがありました。夕食や美味しいお酒とともに、和気あいあいと、島根の学生や各地からの参加者と交流していた弊社メンバーたちでした。 しかし突然の出来事が…!

レセプションの中でTシャツのプレゼント企画を行っていたのですが、弊社参加メンバーの名前が突然壇上から呼ばれ、Tシャツが当たってしまいました!しかもMatzがそれにサインしてくださいました!

喜びと驚きで興奮状態の我々、写真を撮ったりしてはしゃいでいたうちに、近くにいらっしゃったRuby/Railsコミッターの松田さんにお声がけしたところ、松田さんもサインをくださり、そして松田さんがさらに他のRubyコミッターを呼び寄せ、その場にいらっしゃったRubyコミッターによるサインリレーが始まってしまい…

f:id:marikokobayashi:20181116001032j:plainf:id:marikokobayashi:20181116001056j:plain
(弊社メンバー大はしゃぎだったため失礼をしていたら大変申し訳ありません)

…最終的にこのようなTシャツになっていました。Rubyistからしたら完全にお宝ですね。

f:id:marikokobayashi:20181116001418j:plain

今回参加したメドピアメンバーにとって、思い出に残る1日となりました。

Chad Fowler氏基調講演 Don't Stop Moving

2日目のスタートは、RubyConfやRailsConfの共催者、The Passionate Programmer: Creating a Remarkable Career in Software Development (邦題: 情熱プログラマー ソフトウェア開発者の幸せな生き方 )の著者として知られるChad Fowler氏による基調講演でした!

私は彼の著書「情熱プログラマー」は読んだことがあり、感銘を受けた人間の一人ですが、講演を聴くのは初めてなのでわくわくしながら聞きました。

今回は、モチベーションの保ち方や、プログラマーとして生き抜くための戦略について教えてくださいました。

深さと広さ

テクノロジーの仕事をするときは、色々なテクノロジーを広く少しづつ学ぶか、一つのことを深く極めるか、どちらかの戦略を取ると思います。まず、どちらのキャリアを選ぶか決めましょう、という話でした。Chad氏は色々なテクノロジーを広く学ぶ方を選びました。

その道を進んだChad氏は、いろいろな人が新しいテクノロジーを追いかけていることを目の当たりにしますが、「こんな新しいものがいっぱいあるのだ」と驚いてしまったときに、自分のキャリアの中での初心を思い返そうと考えたそうです。

テクノロジーに興味を持ったきっかけとなったビデオゲームである World War Craft のことを思い出してみたら、キャラクター育成の際に最初に「魔術師」「戦士」などを選び、スキルツリーからスキルカテゴリを選んで、どのように育成するかを選んでいました。

それと同じことで、テクノロジーの仕事をするときも、ひとつひとつの細かいことを気にせず、スキルカテゴリを見つけ出すことが大事だとのことです。

1996年頃にメンターの先輩から教わったことがあったそうです。当時は、ディレクトリサービス/UNIX/プログラミング言語という3つのカテゴリを軸に理解すれば、良いキャリアのスタートとなると言われたとのことでした(それぞれのカテゴリについて理解すればその中で具体的に何を選んで学ぶかは重要ではないとのこと)。

2018年の今、同じことを考えた場合、Chad氏が見出した3つのカテゴリは

  • オペレーティングシステム
  • データベース
  • プログラミング言語

とのことです。 さらに、それぞれのカテゴリの中でさらに、3つのカテゴリを見つけると良いとのことです。例えば言語であれば

  • オブジェクト指向言語(Ruby、Pythonなど)
  • Haskell/OCamlのような関数型言語
  • LISP

を挙げていました。これらは、「必要だから学べ」ということではなく、自分の知っている部分と別のカテゴリにおいては考え方の違いを知るのに頭を使うので、実際にはRubyだけで食べていくことができても、 違うカテゴリのものを学ぶことはテクノロジーを広く知るためには役に立つということをおっしゃっていました。

Technology is a fashion

  • ファッションは進化し続けています。全てに付いていくは大変です。テクノロジーもそれと同じ。全部追いかけ回すと全部やらなければいけない、全部最新の流行を理解しないといけないと思うとやる気が無くなってしまう。それよりも自分が安定して取り組めるものにきっちりついていったほうが良いというお話がありました。

自発的な動機づけと外的な動機づけ

  • 外からアメやムチで人を動かそうとしても、結果は出せず、自発的な動機があって初めて結果が出せます。ダニエル・ピンク氏の著書 Drive (邦題: モチベーション3.0 )でも、モチベーションを持つには「自発的であること」「熟練すること」「目標があること」が大事と書かれています。

  • Chad氏も、最初にDave Thomas氏に「情熱プログラマー」を書いてくれと言われた時は、正直大変だなと思ったらしいです。本を書いて有名になりたい気持ちもあったが、それは外的動機づけなのであまり気持ちが乗らなかったとのこと。 しかし、この本を書くことでだれか1人の人間でも幸福にする事ができるかもしれないという自発的なモチベーションを持ったことで、書き上げることができたというお話でした。

「情熱プログラマー」を読んだことでソフトウェア開発者としての生き方を見つめ直したという人も多いのではないでしょうか。その著者自身の執筆のモチベーションのお話を伺ったことで、私ももっと自発的な動機づけをもって物事に取り組もうという気持ちが高まりました。

ブース

ブースでは、弊社のメインサービスである医師向けコミュニティサイト「メドピア」の紹介の他に、子会社Mediplatの遠隔診療サービス「first call」と、同じく子会社FitsPlusの管理栄養士による食事アドバイスアプリ「DietPlus」のご紹介をさせていただいておりました。

f:id:marikokobayashi:20181116002650j:plain

また、PeerWaterというお水とメドベアのステッカー(メドピアの熊キャラクターなので「メドベア」です)を無料で配布していたのですが、ステッカーの評判が良かったですね。ちなみにMatzにも1日目にブースにいらっしゃった時に渡したのですが、気に入っていただけたのか、2日目にもブースに来てくださって数枚持って帰ってくださっていたぐらいです。(メドベアグッズ出したらもしかして需要あるんでしょうか…)

観光

あまり観光の時間は多く取れなかったのですが、前日入りした日には少し松江の空気を味わうことができました。

f:id:marikokobayashi:20181116000111j:plainf:id:marikokobayashi:20181116000015j:plainf:id:marikokobayashi:20181116000032j:plainf:id:marikokobayashi:20181116000052j:plain

初日夕食には美味しいご飯をいただきました。お邪魔したのは「おでん庄助」さん。地元の人にも知られたおでん屋さんです。我々が向かったときはもうすでにメニューの売り切れが多くて「メニューは選べないけど盛り合わせなら出せますよ」とのことでした。

f:id:marikokobayashi:20181116132531j:plainf:id:marikokobayashi:20181116132617j:plain

いただいた盛り合わせはどれも美味しかったです。東京だったらもっと高いであろう夕ご飯が地方価格でしかも美味しい…ワインの種類も豊富に用意されており弊社のワイン大好き社員が感激のあまりワイン講義を初め出すほどでした。

次回以降のRWCなどで松江市観光を検討されている方へ向けたアドバイスを一つ書いておきます。松江市周辺で外食できるお店は全体的に東京より閉まるのが早かったりメニューがなくなるのが早いので、東京の時間感覚で行くとご飯難民になる可能性があります。

この日私達は8時ぐらいからご飯場所を探しましたが、他のお店で「もうご飯がない」と断わられていました。庄助さんで美味しいおでんにありつけたのは運が良かったです。

2日目のアフターパーティには出ずに帰りましたが、初の島根・松江だったメンバーが多かったので、もっとゆっくりすればよかったかもしれないですね。しかしそれはまたいつか機会があるときにリベンジしたいですね。

まとめ

Ruby関連のイベントにスポンサーブースを出すのは初めてで慣れない箇所もありましたが、メドピアを知っていただく機会が増え、多くの方との交流ができたことが嬉しかったです。

個人的な話となりますが、私は地方出身の人間なので、地方のIT産業の活性化には興味があります。

松江の学生は、学生のうちからこのような世界レベルのRubyプログラマーのセッションを自分の地元で聞ける機会に恵まれていて素晴らしいなと思いましたし、島根県・松江市にはこういった取り組みをぜひこれからも続けてほしいと思いました。

弊社としても、今後もこのようなスポンサーの機会がまたあれば良いなと思っております。

f:id:marikokobayashi:20181116002540j:plain

以上、RubyWorld Conference2018のレポートをお届けいたしました!


(☝︎ ՞ਊ ՞)☝︎是非読者になってください


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html

メドピア に整地部ができたってよ!

はじめに

こんにちは、メドピアの駆け出しエンジニアの川﨑です。

最近我が広島カープが日本シリーズ進出を決めて機嫌が良いのでブログ書きたいと思います。

今回僕がお届けするのは、先月の9月14日 「Rails開発での技術的負債との付き合い方」 をテーマに開催された 「MedBeer」 にて、 Classi株式会社のCTOである佐々木 達也(@sasata299)さんの発表にて紹介された「整地部」がMedPeerでもできたよ!というお話です。

整地部とは?

整地部の定義に関しては、以下にある佐々木 達也さん の興奮する資料が分かりやすいです。

一言で言うと

技術的負債となっているコードを少しずつでも良くしたい人たちの集まり

です。

どんな風に進めたか?

記念すべき第一回は、弊社Railsの技術顧問である前島(@willnet)さんがいらっしゃる水曜日に開催されました。

進め方としては、僕が前々から直したいと思っていた箇所を自分なりに修正したPRを作っていたので、そのPRを元にモブプロで洗練させる形をとりました。

今回の整地対象は?

MedPeerでは製薬企業様から医師の方々へ向けた講演会をWeb上で行えるサービスを展開しており、講演会サービスのTOPページではオススメの講演会をスライドで表示しています。

そのスライドに表示する講演会の情報を抽出するロジックが今回の整地対象となりました。

対象となった理由は以下の通りです。

  • 講演会の情報を抽出するロジックが少し複雑
  • ロジックが書かれているモデルが300行を超え肥大している
  • ActiveRecord のメソッドを使えば良いところが散見される
  • メソッド/変数/定数の名前がわかりにくい

どんなことをしたのか?

前提として

・ロジックが書かれているモデルが300行を超え肥大している

という問題に辛さを感じていたので、以下前島さんの記事を参考にしつつ、対象の処理を単機能として一つのクラスへ切り出す方針で進みました。

tech.medpeer.co.jp

クラスに切り出した後は主に以下のことを行いました。

  • 1メソッドでやるべきでない処理を分けてわかりやすくする
  • メソッド/変数/定数の名前をいい感じにする
  • ActiveRecord のメソッドを使った方が良いところは使うようにする

実例

ここで実際に整地された例を一つご紹介します。

今回クラスへ切り出したコードの中で次のようなメソッドがありました。

  def today_conferences(conferences)
    newly_start_at(conferences.find_all { |c| c.start_at.today? }, TODAY_RECOMMENDATION_COUNT)
  end

  def newly_start_at(conferences, limit) 
    conferences.sort_by(&:start_at)[0..limit] 
  end

このメソッドでやりたいことは次の通りです。

  1. 取得した講演会から当日開催のものだけ抽出
  2. 開催日の昇順ソート
  3. 先頭からlimit取得

やりたいことは実装できていますが辛いですね。

今回は ActiveRecord のメソッド where,order,limit を使って次のように修正を行いました。

  def today_conferences
    conferences.where(start_at: Time.zone.today.all_day)
               .order(:start_at)
               .limit(TODAY_RECOMMENDATION_COUNT)
  end

Rubyの世界でのごちゃごちゃした処理がなくスッキリ書けているので、やりたいことが明確になり可読性が上がったかと思います。

実際やってみた感想

実際やってみて特にデメリットは感じないほど良い活動だったと思います。

メリットはたくさんありましたが、個人的に強く感じたことは次の2点です。

  • レベルが高いエンジニアの方と一緒にモブプロするのすごい勉強になる
  • プロジェクトへ貢献するチャンス(特に僕のような新人エンジニア)

一つ目はそのままの意味で、実装するときの考え方や気をつけることを学べる場にもなると思います。

二つ目についてですが、新人エンジニアは実力的にプロジェクトへ大きく貢献することが難しいと思います。

そういった状況でも、整地部の活動へ積極的に参加することで、技術的負債を作らない方法を学びながらプロジェクトに貢献できる点がメリットだと感じています。

今後はどんな感じで進めて行くのか?

実際に活動してみて割と大きな修正が必要なものが見えてきたこともあり、今後は以下のような方法で活動を進めて行く予定です。

・活動頻度は1回1.5h/隔週
・大きな修正は技術力の高いエンジニアでモブプロ
・新人エンジニアは上記モブプロを見て勉強したり、自分で修正できる箇所があれば整地する(必要であればペアプロ依頼)

また、工夫ではないですが、整地活動をする上でやっておいた方が良いこととして、以下2点を意識すると良いと思いました。

・新人エンジニア場合、余裕があれば事前に自分なりに修正したPRを作っておく
・小さいもので良いので、1つはPRを作るところまで対応する

今後の活動へ向けた気持ち

当然ですが大きな成果が出たりする活動ではないので、地道に続けていくことが重要だと思います。

佐々木 達也さんの発表でもありましたが、小さな修正を続けて成功体験を増やしていくことがとても重要だと感じておりますので、僕自身も積極的に活動へ参加したいと思っております。

おわりに

今回はMedPeerで始まった新たな取り組みについてのご紹介でした。

技術的負債は作らないのが一番ですが、長くシステムを運用していく中で浮き彫りになってくるものもあるかと思います。

技術的負債に目をつぶらず、積極的に立ち向かうチームが社内にできたことそのものがとても素晴らしいことだと感じています。

今後も負債に負けない柔軟で堅牢なシステムを維持するべく整地部は突き進みます!!!


(☝︎ ՞ਊ ՞)☝︎是非読者になってください


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html

「MedBeer -Rails開発での技術的負債との付き合い方-」を開催しました!

身長体重が変わっていないにも関わらず、5年前より体脂肪率が4.5%増加したエンジニアの村上(@pipopotamasu)です。

本日は9/12(水)に開催したMedBeerというイベントを報告したいと思います。

medpeer.connpass.com

f:id:ec0156hx39:20180921184837j:plain f:id:ec0156hx39:20180921165847j:plain @GINZA SIX 12F 株式会社リンクアンドモチベーション内 イベントスペース

MedBeerとは?

MedBeerとは、年1回くらいのペースでメドピアが主体となって行なっている技術イベントになります。 基本的にRailsに関することをテーマに発表を行い、今回で4回目の開催となりました。

第1回から着々と規模が大きくなっており、前回は約60名、今回は約120名程が参加されました。

また「Beer」という名をつけているので、10種類ほどのビールとそれにおつまみ(今回はからあげエンジニアが参加するということでしたので、日本で初めて外食メニューとして唐揚げを出した三笠会館の唐揚げを用意しました)を用意していました。

MedBeer -Rails開発での技術的負債との付き合い方-

サブタイトルにも書いてある通り、今回のテーマは「Rails開発における技術的負債」です。 このテーマでメドピアからは2名、またClassi株式会社CTOの佐々木さん、クックパッド株式会社の小室さんをお招きし、計4名で上記テーマに沿って発表を行いました。

Rails Good Parts, Bad Parts

まず初めのトップバッターはメドピアの技術顧問、前島真一(@willnet)さんです。

f:id:ec0156hx39:20180921183445j:plain

発表では「負債の増加を防ぐにはどうしたら良いか?」という観点から、Railsで負債の増加を防ぐ方策を提示していただきました。 重要な要素を一部抜粋すると以下のようになります。

  • Railsが用意する便利機能と、要注意な機能の扱い方を知ることで負債を貯めずに開発することができる
  • そのためにはレビューや社内教育などを通してRailsに習熟することが大事

また発表の中では、前島さんの主催するクリーンなRailsのコードを議論するコミュニティ「clean-rails.org」を紹介していただきました。 皆さんもRailsの設計や実装で悩んだ時など、こちらで相談したらいかがでしょうか?

発表資料は以下になります。

小さな成功体験を積み重ねてチームで負債に立ち向かう

2番目は、Classi株式会社でCTOである佐々木 達也(@sasata299)さんに、負債返却についてClassiで行なった事例について発表していただきました。

f:id:ec0156hx39:20180921184318j:plain

負債返却に必要なものは「負債返却のリソース」と「負債返却いけるいけるという気持ち」の2つが必要で、後者を中心に話していただきました。 既存コードの改修のためにモブプロ/ペアプロの導入や、整地部というコードをリファクタリングする活動を設けたりと、とても参考になる事例を含む発表でした(ちなみに整地部はメドピアで取り入れようとする動きがあります)。

発表資料は以下になります。

メドピアにおけるライブラリアップデート

3番目は私、メドピアの村上大和(@pipopotamasu)が発表させていただきました。

f:id:ec0156hx39:20180921183639j:plain

「メドピアにおけるライブラリアップデート」という題の通り、メドピアでどのようにライブラリのアップデートを行なっているかを発表しました。 メドピアではGemをアップデートするためのフローがあり、1ヶ月毎にそのフローに沿ってアップデートを行い、バージョンが最新と乖離しないように(=負債をためない)しています。具体的にどんなフローでアップデートを行なっているのかの説明と、そのフローをJavaScriptのライブラリに適用させようとしていることをメインで話しました。

発表資料は以下になります。

クックパッドの巨大 Rails アプリケーションの改善

最後に発表したのは、クックパッド株式会社の小室 直(@hogelog)さんです。クックパッドの巨大なRailsアプリケーションの改善について発表していただきました。

f:id:ec0156hx39:20180921184340j:plain

お台場プロジェクトというクックパッドの巨大レポジトリの改善プロジェクトのお話がメインでした。「巨大なRailsアプリケーションの改善は計測と可視化から」という言葉通り、CIにかかった時間・アプリのロード時間・コード量・依存Gem数など詳細にデータをとり、改善結果がそれらの数値にどう影響あったかを逐次確認できる という状態にして、プロジェクトメンバーのモチベーション向上やメンバー以外への成果の共有にも繋がるため、とても参考になりました。

発表資料は以下になります。

終わりに

冒頭にも書きましたが、今回のMedBeerは今までで最も規模の大きいのものになりました。 多くの皆さまに参加いただき、他社の事例も知ることができ、実りの多いイベントでした。 また、急遽会場を貸していただき、当日の準備も手伝っていただけたリンクアンドモチベーション社の皆さまも本当にありがとうございました。 様々な人の協力もあり、第4回MedBeerも良いイベントにすることができました。

今回参加された人もされなかった人も、次回のMedBeerでお待ちしてます!!!


(☝︎ ՞ਊ ՞)☝︎是非読者になってください


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html

開発環境のレンダリング完了時間を1/10にした話(Rails)

ビール大好きですが、3回に1回は年齢確認をされる26歳エンジニアの村上(pipopotamasu (pipopotamasu) · GitHub)です。

今回はリクエストからレンダリング完了までの時間を減らした取り組みについて書こうと思います。

f:id:ec0156hx39:20180820162919p:plain

きっかけ

メドピアではメインプロダクトをRuby on Railsで開発しています。 Railsで開発を始めてから2年半、すくすくとアプリケーションが成長してきています。 しかし成長していくにつれ問題が出てくるのが世の常、以下のような問題が生じてきました。

「ページ読み込みが遅い...」 f:id:ec0156hx39:20180816143017p:plain

Webアプリケーション開発者は開発環境で1日に何十回とページ読み込みをさせると思いますが、Railsの成長と共にそれがめちゃくちゃ遅くなってきたのです。

環境

メドピアのフロントエンド環境はassets pipeline(browserify-railsを用いてビルドしている)で管理している部分と、Webpackerで管理している部分があります。 今回の取り組みは、JavaScriptをassets pipelineからWebpackerへ移行している過渡期に行いました。

問題は何か?

さて、ページの読み込みがめちゃくちゃ遅いという問題にぶちあたりましたが、これだと問題が大き過ぎるのでもうちょっと細分化してみましょう。 以下はリクエストからページレンダリング完了までの流れになります(超ざっくりです)。

f:id:ec0156hx39:20180817113222p:plain

①~⑤まで確認してみたところ、②と④、⑤に時間がかかっていることがわかりました。

まずdev toolの計測を見てみましょう。 f:id:ec0156hx39:20180817131401p:plain

青色が待機時間、サーバーから応答が返るまでの待ち時間です。最初のHTML取得で結構時間がかかっていることがわかります。 ピンク色はブロック時間、ネットワーク接続の待ち行列で費やした時間を表しています。

最初のHTML取得までの時間、つまり②の時間が遅いことについては、開発環境であるためRailsのconfig.cache_classesをfalseにしていてコードのキャッシュをさせないようにしているので、遅いのはある程度仕方がないのですが、それにしても遅い...。サーバ側でのViewのレンダリングにかなりの時間を費やしています。

# config/environments/development.rb

config.cache_classes = false

f:id:ec0156hx39:20180820005252p:plain

またdev toolの計測を見てみると、CSSやJavaScriptといったアセットを取得しに行く時間、つまり④、⑤も異常に遅いです、全リソースを読み込むのに15秒もかかってるorz。そもそも読み込もうとしているJavaScriptが多すぎますね。

原因は何か?

②が遅い原因

アプリケーションログを遡っていくと、あることに時間を費やしているのがわかりました、browserifyのビルドです。 JavaScriptに何かしらの変更を加えた時に、browserifyのビルドが走っていてそれが遅く感じる原因のようです。 f:id:ec0156hx39:20180820005453p:plain

どうやらbrowserifyはWebpackなどと違い、デフォルトで差分ビルドができず(watchifyというプラグインが必要)、JavaScriptを変更した後にエントリーポイントで読み込むファイルを全ビルドしていたためにかなり遅くなっていました。 読み込んでいるJavaScriptの種類にもよりますが、約4~6秒ほどかかっていました。

④と⑤が遅い原因

読み込もうとしているJavaScriptが多すぎて、ブラウザの同時接続数(Chromeは6)をオーバーしているためです。前述したdev toolのピンク色がブロック時間、つまり接続待ちを表しています。

そもそも何故こんなにも読み込むJavaScriptが多いのでしょうか?

どうやらdevelopment環境のデフォルトで、assets pipelineで本来一纏めにされるJavaScriptがデバック用にバラバラで読み込まれる設定がされているようです。

# config/environments/development.rb

config.assets.debug = true

これにより読み込むJavaScriptが多くなりすぎて、接続待ちに時間が多く費やされていました。

対策

browserifyのビルドが遅い問題

watchifyを導入して、差分ビルドをさせるようにするという案もありましたが、最終的にWebpackに置き換えるという形にしました。 これについては別に記事を書いているのでよろしければご覧ください。

tech.medpeer.co.jp

最終的にbrowserifyの全ビルドから、Webpackの差分ビルドに置き換えたことにより、 4~6秒 → 1.5秒 に短縮することができました。

f:id:ec0156hx39:20180820010534p:plain

読み込むJavaScriptが多すぎる問題

デバックモードもそれはそれでデバックしたい時には便利なので、単純にconfigの値をfalseにするだけだと切り替えが面倒です。

# config/environments/development.rb

config.assets.debug = false # デバッグしたい時にtrueに書き換えてappサーバを再起動する必要がある

しかしconfig.assets.debugがfalseの時、Railsのjavascript_include_tagヘルパーのdebugオプションをtrueにすることで、デバックモードに切り替えることができます。

railsguides.jp

このオプションを利用して、debugしたい時だけURLに特定のパラメータを付与するとdebugモードに切り替わるヘルパーを作成しました。

  def javascript_include_tag_with_debug_option(js, options = {})
    javascript_include_tag js, options.merge(debug: params[:js_debug].present?)
  end

このヘルパーを利用することで、通常時のリクエストはdebugモードはOffですが、以下のように特定のパラメータを付与するとOnにできるようになりました。 https://hostname.jp/articles?js_debug=on

終わりに

今回は開発環境の話でしたが、本番環境でもリソース取得時間の改善の余地がまだまだあります。 「サイトの読み込み時間を爆速にする」ことに興味がある方は是非一度メドピアに遊びに来てください。

また9月12日にメドピアでRailsの技術的負債をテーマにした「MedBeer」というイベントを開催します。

medpeer.connpass.com

負債の予防・返却に興味がある人、ビールが飲みたい人は是非参加してください。


(☝︎ ՞ਊ ՞)☝︎是非読者になってください


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html

開発合宿@伊豆大島に行ってきました!

こんにちは。メドピアのサーバサイドエンジニアの小林です。

まずはじめに、この度の西日本豪雨で被災された方々にお見舞い申し上げますとともに、被災地の一日も早い復興を心よりお祈り申し上げます。

今回のブログでは、メドピアでは恒例となっているエンジニア・デザイナー開発合宿に参加してきましたので、レポートさせていただきます。

メドピアでは、これまでにも年2〜3回ぐらいのペースで開発合宿を開催しています。

この夏は、東京の離島、伊豆大島へ…!メドピアとしても合宿で島へ行くのは初めてのことでした。

1日目

東京港竹芝ターミナルから船に乗っていざ、出発! 船は予想通り(予想以上に?)揺れるので酔い止め薬必須です。

船に揺られること2時間、着いたのは伊豆大島の北の玄関口、岡田港です。

f:id:marikokobayashi:20180711194653j:plain

ここから更に三原山に登り、車で30分程経った頃、標高500mほどに位置する大島温泉ホテルさんに到着。

【公式サイト】伊豆大島・三原山温泉/大島温泉ホテル

f:id:marikokobayashi:20180711195031j:plain

到着…したは良いものの…あたりは一面の霧でした…!肌寒い…!

私はあたり一面を山に囲まれた田舎出身者ですが、今回は事前にちゃんと標高を調べていなかった中、実家の標高より高い場所に来てしまい *1、軽装で来た(薄手のカーディガンは持っていましたが…)ことを若干後悔しました。

しかし、今回は観光に来たのではなく合宿。山を降りようにもこの霧の中ではいまいち降りる気も湧いてきません。 合宿所にこもるにはうってつけではないでしょうか…!?!?

f:id:marikokobayashi:20180711210044j:plain
名物の椿フォンデュの天ぷらが美味しかったです。ところてんが食後のデザートのあとに出てきました

今回は、ホテル内に全員が集まれる会議室や広間のような場所は借りていないため、借りた客室の中で一番広い部屋にいったん集まって、それぞれが何をやるか発表しあって合宿スタートです!

f:id:marikokobayashi:20180711210732j:plainf:id:marikokobayashi:20180711210218j:plain
1部屋に集まってやること発表会

2日目

2日目も、特に皆出かける予定もなく、宿でもくもく…。

f:id:marikokobayashi:20180711211007j:plainf:id:marikokobayashi:20180712153054j:plain
もくもくしている様子
ちなみに温泉は昼は3時から夜の12時まで入れるようになっていましたので、3時になるとすぐにお風呂に入り出す人もいました。
f:id:marikokobayashi:20180711210927j:plainf:id:marikokobayashi:20180711211022j:plain
2日目のご飯の様子

最終日

最終日はすぐにやってきます。3日間あるとはいえ、1日目の夕方に宿に到着して3日目の朝には宿を出発。 ご飯・睡眠・お風呂の時間も考えると、開発にあてられた時間は実質1日強といったところです。

最終日の朝、宿を出発したあと、帰りの船に乗るまで時間がありましたが、あいにくの雨でしたので、一旦皆で元町港の近くにある御神火温泉さんに立ち寄り、休憩所で開発をしたりそれぞれ好きなように過ごしていました。

f:id:marikokobayashi:20180712201548j:plainf:id:marikokobayashi:20180711211250j:plain

その後、出発1時間ほど前になってやっと雨が止んできたので、岡田港にバスで向かい、近辺でお土産を購入したり、アイスを食べたりと束の間の夏気分を味わいました。

f:id:marikokobayashi:20180711211439j:plainf:id:marikokobayashi:20180711211411j:plain
べっこうずしが美味しかったそうです(私は食べれなかった)

成果発表会

成果発表会は後日会社で行いました!FirebaseやGraphQL、Google Cloud Speech APIなどのライブラリを試した人、資格取得に向けた資料作りをした人、パフォーマンスチューニングに挑んだ人などがいて様々な種類の発表がありました。エンジニア・デザイナー以外のメンバーにも聞いていただけました!

f:id:marikokobayashi:20180711212134j:plainf:id:marikokobayashi:20180711212238j:plainf:id:marikokobayashi:20180712152154j:plainf:id:marikokobayashi:20180711212207j:plain

まとめ・感想

今回は伊豆大島ということで、最初は「夏の海!観光!」といった期待をしていた人が少なくなかったようですが、実際は天気もあまり優れず山の上にこもりきりということになりました…!! そのぶん開発自体に集中できたという人も多いのではないかと思います。

私個人としては、今回は3人1チームで1つ新サービスを立ち上げるということにチャレンジしました。

私は合宿に参加するのが1年前から数えて3回目になりました。 これまでにも合宿中に新サービス作りにチャレンジしようとしたこともありましたが、今まではRails開発経験の浅さもあって(と言ってしまうと言い訳じみていますが…)人に見せられるような形での新サービスを3日で作り上げるということはできなかったのですが、今回は3人のチームで、各々の分担を決めて限られた日程の中でスケジュール立てして作っていったので、発表のときには「新サービスこんな感じで作ったよ!」と紹介することができ、達成感がありました。

合宿に参加する意義としては、新しいライブラリを試したり、普段業務で後回しになって手を出せずにいるようなリファクタリング等に取り組める場として使えるというのももちろんですが、「短期間でどうやって人に見せられるような成果を出せるか?」の経験を積むことが出来るという側面もあるように感じました。

今後も開発合宿を定期的に開催していただける予定のようなので、次回あたりには是非私の地元の県での合宿の開催を検討してもらえないかな〜と密かに狙っています。

以上、メドピア開発合宿@伊豆大島の様子をお伝えしました!

f:id:marikokobayashi:20180711213126j:plain


是非読者になってください(︎ ՞ਊ ՞)︎


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html

Rails未経験/経験年数が2年以内のポテンシャルエンジニア絶賛募集中です!*2

Rails開発してみたい人、新しい技術に意欲的な人、リードエンジニアに教育されてみたい(?)人、医療に関わるサービス開発を行ってみたい人、その他メドピアに興味を持った方などは、是非、コンタクトを取って頂ければと思います!

*1:長野県民は実家の標高を言えるらしい(詳しくはググってください)(私も急に聞かれたけどおおよそ正確な値を言えました)

*2:リードエンジニアも募集中です!

poltergeistからheadless chromeへ移行する時に気をつけること

こんにちは。メドピアのRuby(Rails)化をお手伝いしている@willnetです。最近は子育てに忙しくしています 👶

先日、メドピアで利用しているcapybaraのjavascript driverをpoltergeistからheadless chrome(selenium-webdriver)に移行しました。driverを変更するにあたって既存のテストコードをいくつか修正する必要があったので、そこで得た学びを共有したいと思います。

なぜ移行したのか

ここ数年、Railsでエンドツーエンドのテストを書くときにはpoltergeistを使う、というのがデファクトスタンダードだったはずです。それ以前はみんなcapybara-webkitを使っていましたが、poltergeistはバックエンドにPhantomJSを使っており、Qtに依存しているcapybara-webkitと比べてビルドが簡単だったことから徐々にシェアを増やしていったように思います*1

そんな中、だいたい1年ほど前にChromeのバージョン59からヘッドレスモードが実行できるようになりました。これをうけて、PhantomJSの開発が停止されました。PhantomJSをメンテするのはだいぶ大変だったみたいです。

これは当然、依存しているpoltergeistにも影響します。PhantomJSの依存をやめる構想もあったようですが、リポジトリを眺めている限りではあまり進捗しておらず、さらにpoltergeistの開発自体あまりアクティブではないように見えます。

ここまでの経緯を考えると、headless chromeに切り替えるのは無難な選択と思われるのですが、移行時期には考慮が必要でした。headlessモードが使えるchromeがリリースされた当初は、chromedriver(chromeを別プロセスから動かすのに必要なもの)に大きめのバグがあり、すぐに移行するには不安な状況でした。しかしそれから1年ほど経過した今なら問題なく移行できるのではないか?となったのでした。

そんなわけで、フィーチャスペックのときに使うドライバをpoltergeistからheadless chromeに変更しました。

f:id:willnet:20180619182309p:plain

移行に必要なこと

リリースから1年経ってこなれたと言っても、poltergeistからheadless chromeへの変更は単純に入れ替えただけでは完了しません。テストコードの変更も必要です。

僕たちはcapybaraのインターフェースを経由してheadless chromeやpoltergeistを利用しているので、移行してもテストの書き方は基本的には変わりません。ただ、ドライバによって対応しているメソッドとしていないメソッドがあるため、poltergeistのときは動いていたコードがheadless chromeでは動かないケースがあるのでした。そういうところは動くように書き換えてあげる必要があります。

大抵の箇所は機械的に置換していくようなやり方でOKなのですが、テストの内容によってはもっと頑張らなければならないところがあるのでそれを紹介します。

ファイルダウンロードのテストを変更する

例えばリンクをクリックするとcsvがダウンロードできるようなページがあったとします。poltergeistを利用している場合、次のようにレスポンスヘッダを見て、Content-Typeが text/csv であることをもってテストを成功をみなすという方法があります。

context 'CSVダウンロード用のページに遷移したとき' do
  before { visit csv_download_path }

  it 'かつ"CSVダウンロード"をクリックしたらCSVファイルがダウンロードできること' do
    click_on 'CSVダウンロード'
    expect(page.response_headers['Content-Disposition']).to eq("attachment; filename=\"download.csv\"")
    expect(page.response_headers['Content-Type']).to eq("text/csv")
  end
end

上記のコードは、headless chromeに切り替えるとうまく動きません。どうやらheadless chrome(正確にはselenium webdriver)はレスポンスヘッダを見るAPIを提供していないようです。バグとかではなくそういう設計方針の模様

レスポンスヘッダを見れないとしたら、実際にダウンロードしたファイルの内容を確認するしかありません。こちらのエントリを参考にしつつ、実際にダウンロードしたファイルの中身をチェックする方法に変更しました。

まず、次のようなヘルパーメソッド群をモジュールとして定義し、フィーチャスペックで使えるようにします。

module DownloadHelper
  TIMEOUT = 10
  PATH    = Rails.root.join('tmp/downloads')

  module_function

  def downloads
    Dir[PATH.join('*')]
  end

  def download
    downloads.first
  end

  def download_content
    wait_for_download
    File.read(download)
  end

  def wait_for_download
    Timeout.timeout(TIMEOUT) do
      sleep 0.1 until downloaded?
    end
  end

  def downloaded?
    !downloading? && downloads.any?
  end

  def downloading?
    downloads.grep(/\.crdownload$/).any?
  end

  def clear_downloads
    FileUtils.rm_f(downloads)
  end
end

RSpec.configure do |config|
  config.include DownloadHelper, type: :feature
  config.before(:suite) { Dir.mkdir(DownloadHelper::PATH) unless Dir.exist?(DownloadHelper::PATH) }
  config.after(:example, type: :feature) { clear_downloads }
end

これにより、先程のテストを次のように変更することができます。

context 'CSVダウンロード用のページに遷移したとき' do
  before { visit csv_download_path }

  it 'かつ"CSVダウンロード"をクリックしたらCSVファイルがダウンロードできること' do
    click_on 'CSVダウンロード'
    expect(download_content).to eq "row1,row2\n"
  end
end

さてこれで解決…と思いきや、もうひとつ対処が必要だったりします。どうやら、 headless chromeはデフォルトでファイルダウンロードをしないようです。そこでstackoverflowの回答を参考に、ファイルダウンロードを許可するようにしました。具体的には次のようにconfig/rails_helper.rbに記述しています(bridge変数以下がファイルダウンロードを許可しているコード)。

Capybara.register_driver :headless_chrome do |app|
  driver = Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
      login_prefs: { browser: 'ALL' },
      chrome_options: {
        args: %w(headless disable-gpu window-size=1900,1200 lang=ja no-sandbox disable-dev-shm-usage),
      }
    )
  )
  bridge = driver.browser.send(:bridge)
  path = "session/#{bridge.session_id}/chromium/send_command"
  bridge.http.call(
    :post, path,
    cmd: 'Page.setDownloadBehavior',
    params: {
      behavior: 'allow',
      downloadPath: DownloadHelper::PATH.to_s,
    }
  )
  driver
end

Capybara.javascript_driver = :headless_chrome

これでファイルダウンロードをheadless chromeでテストできるようになりました。

追記

最近(2019年9月)のchrome77からはこの方法だとテストが失敗するようになっています。詳細について新しい記事にしたので参考にしてください。

最近のheadless chromeを利用したファイルダウンロードのテスト方法について - メドピア開発者ブログ

ブラウザ上で見えない要素に対応する

headless chromeは、poltergeistと比べて「ブラウザ上で見える要素であるか否か」にシビアなようです。例えば、position: fixed; left: 1000px としているDOM要素があるとします。このとき、ブラウザのウィンドウサイズが(800, 600)のように小さく要素が画面外になる場合は、その要素は見えないという扱いになります。

この場合は単にウィンドウサイズを大きくしてあげればよいのですが、それでは対応できない場合は次のようにvisible: falseをつけて、見えない要素の中で指定のDOMが存在するかを確認する必要があります。

expect(page).to have_css('.super-right-dom', visible: false)

このように「画面外にあるので見えない」というのはわかりやすいのですが、なにをもって「見える」「見えない」と判断しているのか難しいなと感じるケースがあります。例えばあるページではbxSliderを利用して画像をカルーセル表示しているのですが、スクリーンショットで見えていることが確認できるDOM要素もheadless chrome的には見えない扱いをされていました。

やむを得ずこれもvisible: falseとして対応しました。しかしこのあたりはまだ深く調査できてないので、詳しい方いたら教えていただけると嬉しいです。

細かい変更点

次のような細かい点にも対応しました。このへんは単に置換するだけなので軽く箇条書きで済ませます。

  • triggerメソッドがない
    • trigger('click')を使わず、clickメソッドを使うようにした
  • ウィンドウのリサイズのお作法が違う
    • before: Capybara.page.driver.browser.resize(320, 580)
    • after: Capybara.current_session.current_window.resize_to(320, 580)
  • ブラウザのダイアログが表示される部分は、polgergeistでは自動でacceptされるが、headless chrome(というかselenium webdriver)ではどのように対応するかをaccept_alert {} みたいに書く必要がある

まとめ

polgergeistからheadless chromeへの移行において、気をつける点と変更が必要な点について紹介しました。headless chromeに移行することで、今後メンテナンスが続いていくであろうという安心感が得られます。しかし、セットアップには今回紹介したようにコツをつかむ必要があります。

この記事がこれからheadless chromeへ移行する人や、移行に苦労している人にとって参考になれば幸いです。


是非読者になってください(︎ ՞ਊ ՞)︎


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html

Rails未経験/経験年数が2年以内のポテンシャルエンジニア絶賛募集中です!*2

Rails開発してみたい人、新しい技術に意欲的な人、リードエンジニアに教育されてみたい(?)人、医療に関わるサービス開発を行ってみたい人、その他メドピアに興味を持った方などは、是非、コンタクトを取って頂ければと思います!

*1:PhantomJSもQtに依存しているけど、PhantomJSはバイナリが配布されているのでビルドせずにインストールできるというのが大きかった

*2:リードエンジニアも募集中です!