ナガモト の blog

Full Cycle Developerを目指すエンジニアが有用そうな技術記事や、ポエムのようなよしなしごとを投稿するブログです。

Railsアプリ開発におけるテスト戦略 〜オレオレベタープラクティス〜

いきなりですが、戦術・戦略という言葉を正しく理解していますか?大雑把でもいいのでどう違うのか、どちらがより抽象度が高く・具体性が低いのか理解しておきましょう。

ざっくり言うと、戦略は大局的な目的や方策のことであり、戦術は戦略を実現するための具体的な手段や計画のことです。*1*2

大切なのは、戦略が間違っていてはどんなに優れた戦術を用いても大きく状況を改善するのは難しいということです。*3

ソフトウェアのテストにおいても、具体的な書き方・ルールの整備など優れた戦術を取っているにも関わらず、そもそもの戦略を間違えているがばかりに状況が改善しないことがあります。当記事はソフトウェアテスト(特にRailsRSpecの場合)における戦略を紹介します。

Railsアプリ開発におけるテスト戦略について語る前によくある課題と戦術、それから発生する問題を説明します。

テストコードによくある課題

  • テストが不足している
  • テストを書くコストが高い
  • テストを読む難易度が高い

これらの問題は表裏一体で繋がっています。そもそもテストを読む難易度が高いがために、書くコストが高くなり、コストが高いためにテストを書けずに不足してしまいます。

(RSpecで)とりがちな戦術

  • letは遅延評価なので冒頭ですべて定義しておく
  • よく使用するデータセットをテスト実行前に入れておく
  • FactoryBotで汎用性の高いデータを定義して使い回す
  • 定義済みレコードにupdateをかけて使い回す
  • shared_xxでまとめて定義して使い回す
  • オリジナルな記法・メソッドを定義して多数のexpectaion記述を端折る
  • eachやwhileなどのループで記法で多パターンのテストを行う

大抵は書く量を減らして読みやすくしたり、書きやすくしようという狙いで採用されます。*4 これらの戦術は用法用量を守って用いれば薬になるでしょうが、毒になる場合もあります。また、そもそもの戦略が間違っている場合、戦術レベルの対応では状況はじわじわと悪くなる一方です。

発生しがちな問題

  • 仕様変更やリファクタリングでshared_xxなど共通化した箇所が軒並み使えなくなる
  • 通化されているため、ある特定のケースにのみ、テスト項目を増やすことが難しい
  • 複数ファイルを行き来しなければテストの動作を把握できない
  • テストコードの複雑度が上がり、テストコードをテストする必要性を感じ始める

ではこういった状況に陥らないためのオレオレベタープラクティスを説明していきます。

Railsアプリ開発におけるテスト戦略 〜オレオレベタープラクティス〜

ベタープラクティスは次の流れで行います。

  • テストによりどんな課題を解決したいか確認する
  • ソフトウェアテストについての基礎基本を開発メンバー全員に理解してもらう
  • E2Eテスト, Controllerテスト, Modelテスト各レイヤの落とし所を決める
  • 戦略についてチームで共通認識を作る
  • 戦術についてチームに浸透させる

テストによりどんな課題を解決したいか決める

私はRailsアプリを開発する際にはスピーディな開発改善サイクルを回すことが重要だと思っています。そのためには高い頻度でリリースをしたいです。しかし、自動テストなしではデグレ発生が恐ろしく頻繁なデプロイはできません。そのため、解決したい課題は次の通りです。

「品質の担保を容易にし、安全に高い頻度でリリースを行えるようにする」

この課題について何を今更と思う人は多いでしょう。しかし継続的に開発していく中でテストを書くという行為がただの作業になってしまうことはたまにあります。そのような状態では非効率的なテストを書いてしまったり、実際にはありえないような意味のないテストを書いてしまいます。そんなときはそもそもの目的・課題に立ち返りましょう。

ソフトウェアテストについての基礎基本を開発メンバー全員に理解してもらう

ソフトウェアテストについて学んだことはありますか?「単体テスト結合テストホワイトボックステストブラックボックステスト・分岐網羅・条件網羅・境界値分析」これらの意味はわかるでしょうか?

私は大学・大学院で研究のためにソフトウェアテストの基礎基本を学びました。*5意識の低い学生でしたが、そこで学んだ知識はテストを設計するときに非常に役立っています。テストは経験則で自然と書いたり設計したりできるようになると思われがちですが、やはり基礎基本を抑えるとテストの勘所を掴むのが早くなり、効率よくどんどん良いテストを設計できるようになります。

ja.wikipedia.org

E2Eテスト, Controllerテスト, Modelテスト各レイヤの落とし所を決める

まず大前提として、すべてのレイヤで網羅率100%となるようなテストを行うのは現実的ではありません。そのため、基本的には品質の高いテストで効率よくバグを検出する方針をとることになります。

ソフトウェアテストの一分野、組み合わせテストでは「大多数のバグは少数因子の値の組み合わせで検出できる」と知られています。*6*7ソフトウェアは多数のモジュール(因子)の組み合わせとみなすことができるため、小さい各モジュール毎の単体テストを厚く行うことが比較的少ないテストで多数のバグを検出できるよいテスト方針となります。そもそも、複数のモジュールを組み合わせたテストを設計するのと、モジュール毎にテストを設計するのでは後者の方が簡単ということも単体テストを厚く行う方針の追い風です。

単体テストなどのソフトウェアテスト用語をRailsに対応させると次の通りです。

つまり、Modelテストを厚く行うことが効率の良い品質の高いテストになります。しかしながら、各レイヤ毎にしか検証できない項目や低い割合とはいえ組み合わせたときにのみ検出されるバグもあるため、Controllerテスト・E2Eテストも行わないというのはよくないと考えます。

理論とこれまでの経験も踏まえた結果として、私がよく利用する落とし所はこれです。

「Modelテストをほぼすべてのメソッドを検証する程度に厚く、 Controllerテストを正常系・準正常系のレスポンスをそれぞれ1パターン以上、E2Eテストをサービスにおけるクリティカルな機能*8について行う」

※時々のリソースや状況次第です

戦略についてチームで共通認識を作る

当然ですがテストコードもアプリケーションコードと同じく全開発メンバーが書くでしょう。あるメンバーはControllerテストのみを厚く書き、Modelテストを書かない。別のメンバーはModelテストしか書かない。そのような状況では品質の高いテストが実行できているとは言えません。

テスト戦略について決めているのであれば共有しましょう。チーム全員で決めて納得感を醸成することもいいでしょう。(少人数チームに限る)

戦術についてチームに浸透させる

戦略を共有し、同じ粒度のテストを書いていても、それぞれが自由きままに勝手にテストコードを書いていてはカオスになるでしょう。RailsというFWを用いてアプリケーションコードについては規約を重んじ、統一感のある書き方をしている。そんなエンジニアであれば、テストコードでも統一感ある書き方をした方がよいということはすぐ理解できるでしょう。

RSpecを用いたテストコードの書き方については次の記事に参考資料をまとめてあります。チームが大きくなるときまでには、そのチーム合った書き方・規約を大まかにでも定められるといいでしょう。 ngmt83.hatenablog.com

まとめ

Railsアプリ開発におけるテスト戦略 〜オレオレベタープラクティス〜」は、

  • ソフトウェアテストの基礎基本を大まかに理解する
  • 「Modelテストはほぼすべてのメソッドを検証する程度に厚く、 Controllerテストは正常系・準正常系をそれぞれ1パターン以上、E2Eテストはサービスにおけるクリティカルな機能についてのみ行う」
  • チームが大きくなるまでにRSpecの書き方・規約を大まかに定める
  • テストの目的・戦略を定期的に見つめ直す

これらをチームメンバー全員に共有・浸透させる。

です。

*1:「戦略」と「戦術」 - 違いがわかる事典

*2:3分でわかる孫子の兵法/戦略!戦いを避けながら、弱者が強者に勝つ | ビジネススキル大全 | ダイヤモンド・オンライン

*3:大阪から東京へ向かう際に、西へ進むという戦略ではどんなに早い乗り物(優れた戦術)を用いても東京にたどり着くために莫大なコストがかかる。

*4:他にはテスト実行時間が長く、オーバーヘッドを減らすためという狙いもある。

*5:ディペンダビリティ(高信頼性)を専門とする研究室でソフトウェアテストにおけるテストケースの自動設計について研究してました。

*6:出典論文: Software fault interactions and implications for software testing - IEEE Journals & Magazine

*7:組み合わせテストの日本語参考記事: 組み合わせテストの用語「2因子間網羅」「直交表」「All-Pairs法」 - Qiita

*8:例: ECサービスにおけるカートに入れて購入完了まで。マッチングサービスにおけるマッチング申請、承認、マッチング成立まで。ユーザ新規登録から完了まで。etc

Angularアプリにバーコードを表示する ~package選定編~

先日次のような記事を書きました。 ngmt83.hatenablog.com

今度はQRではなく1次元バーコードの表示をすることになりました。やりたいことはシンプルですが「Angular + barcode」という情報があまり揃っていなかったため、技術選定に少しだけ苦労しました。

方針

ある値(文字列)をバーコードで表示するというのは汎用的な機能であるため、スタンダードとなるpackageがあるはずだと考え、それを探して採用する方針でした。

要件

  • Angularアプリに組み込める
  • code128規格のバーコードが表示できる
  • いずれ他の規格のバーコードを表示したくなる可能性がある
  • svg形式で表示できるとなお良い

調査

Angular, barcode, generator, javascript

といったワードで検索しました。コツはQRやreaderをうまく除外することです。特にQRコードリーダーの情報が多く、私にとってはノイズでした・・・

候補

早速調査をして候補を3つ上げました。

それぞれ比較・検討していきます。

ngx-barcode - npm

github.com Angularから使用しやすくしたpackageです。ドキュメントは充実しているわけではありませんが、簡単に使えそうです。

不安なのは2年前から更新されていないことです。

angular-barcode - npm

github.com 同じくAngularから使用しやすくしたpackageです。ドキュメントは充実しているわけではありませんが、使用例にオプション設定まで細かく書いてあったので使い方はすぐわかりました。

こちらも2年前から更新されていないことが不安要素です。

jsbarcode - npm

github.com Angularを想定しているものではなく、環境を選ばないシンプルなpackageのようです。1年以内に更新があります。

barcode関連の最大手packageと言えるほどの人気です。*1*2ユーザが非常に多く、ドキュメントも充実しています。デモまであって至れり尽せりです。*3

決定

3つを比較していたのですが、そもそもngx-barcode, angular-barcodeはJsBarcodeに依存*4*5しており、JsBarcodeをAngularから使いやすいようにラップしたpackageのようでした。

とすると実現できることはどれもJsBarcode以下で、使い方やオプションを調べるときは結局JsBarcodeを参照することになりそうです。

また、ラップした2つは更新頻度が低いです。バーコードの規格はそう変わらないという点では更新がないのも自然ではあります。しかし更新頻度の高いAngularとの組み合わせを考えると不安です。

以上よりJsBarcodeを利用することに決定しました。

f:id:ngmt83:20190531073357p:plain
JsBarcodeのデモで作成したバーコード

予告

AngularアプリにおいてJsBarcodeを用いたバーコード表示方法を投稿する予定です。

RSpecでテストを書くときの参考資料神7

RSpecをどう書くかは著名な方々が既に語り尽くしている印象です。そのため非常に参考となる7つの資料、通称神7*1の紹介をします。

私はこれまでレビュやエンジニアインターンに教える際に何度となく神7のお世話になりました。そん経験を踏まえてどの資料にどのようなことが記述されているか、どんな人が読むべきかを併記します。

神7

神7はざっくり次の3つのタイプに分けることができます。

  • RSpecやテストについて全体感を掴めるもの
  • 特有の記法や書き方を扱うもの
  • より良く書くための戦略や概念の理解に役立つもの

RSpecやテストについて全体感を掴めるもの

RSpec入門者どころか、テスト入門者は学ぶことが非常に多いです。そのため、情報がまとまっている資料をおすすめします。全体感を掴んでから細部の理解に努めると捗ります。

Read Everyday Rails - RSpecによるRailsテスト入門

leanpub.com

特徴

  • RSpecでテストを書くために必要なことがすべて書いてある*2
  • 構成が非常にわかりやすく、0から勉強する人は写経しながらページを順番通りにめくるのが良い
  • 内容が充実してる分本のボリュームも大きい

この資料を読んだほうがいい人

順序立てて、体系的に学びたい人、ソフトウェアのテスト・RSpecに関してそもそも未経験の人。

本の内容量に圧倒されたり、心が折れないようにだけ注意が必要です。*3この本を最後まで理解できれば、非常にレベルが高い人になれます。いきなりそのレベルに到達しようとせず、必要と余裕に合わせて読み進めましょう。

RSpecえかきうた

techracho.bpsinc.jp

特徴

  • RSpecでテストコードを0から書き上げる流れを説明している
  • テストコードがどんなパーツで構成されているか、それをどう設計するか概要を掴みやすい
  • さっと読み、参考にしやすい文量

この資料を読んだほうがいい人

新しくテストを書くぞとなった時にどこから手をつけたら良いかわからない人。describe・context・itの意味するところ、それらの並べ方が良くわからない人。

RSpecの書き順を紹介する記事です。1例なので異なる書き順の人もいるかもしれませんが、お手本として真似するのにおすすめな王道の書き順だと考えていいです。自分のポリシー・書き方が定まっていない人は真似してみましょう。

特有の記法や書き方を扱うもの

使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 - Qiita

qiita.com

特徴

  • Qiitaにて無料で入門記事として適度なボリュームで分けて公開されている
  • 前述のEveryday Rails(略)の日本語訳者(jnchito - Qiita)が書いているため、文章として非常にわかりやすい

この資料を読んだほうがいい人

テストに関しては知っているが、RSpecの書き方はほぼ知らない人。Everyday Rails(略)を買うか悩んでいる人。

RSpecのシンプルな記法から、実務で書く際に役立つTipsやリンクなども親切に挿入されています。「この人の文章読みやすいな!」と感じたらぜひ前述のEveryday Rails(略)を購入しましょう。

Better Specs { rspec guidelines with ruby }

www.betterspecs.org

特徴

  • RSpecのスタイルガイド*4
  • BADとGOODの例を併記して説明してある

この資料を読んだほうがいい人

RSpecの書き方はほぼ知らない人。レビュで小さめの指摘が多い人。「この書き方ならMiniTestでよくない?」「RSpecらしく書いて欲しい」と言われる人。

多言語に翻訳されたページがあるので、留学生インターンなど日本語ネイティブではない駆け出しのエンジニアにもおすすめしやすいです。

GitHub - willnet/rspec-style-guide: 可読性の高いテストコードを書くためのお作法集

github.com

特徴

  • RSpecのスタイルガイド
  • 特に可読性が高いテストを書くことに重点をおく
  • 技術顧問を生業とするwillnetさんが多くの現場を通して得た経験に基づいている

この資料を読んだほうがいい人

RSpecの書き方はほぼ知らない人。レビュで「RSpecらしく書いて欲しい」と言われる人。読みにくいテストコードに悩んでいる人。

良くない例・それが何故良くないか・どう書けば改善されるかがそれぞれのトピックで説明されているため、強い納得感が得られます。レビュア側としても指摘をする際にこのページのリンクを渡すと説明がしやすいです。各現場毎にRSpecの書き方はあると思いますが、このガイドをベースにするといいと思います。

Clean Test Code Revised - Speaker Deck

特徴

  • 読みやすいテストコードのための決定版となるスライド
  • 可読性を下げるものとそれを排除するプラクティスと具体例が示される

この資料を読んだほうがいい人

読みにくいテストコードに悩んでいる人。動くだけのテストコードから読みやすいテストコードへと次の段階を目指す人。細部のよい書き方はわかるが、全体の理想を掴みきれていない人。

なんで読みにくいんだろうに対する回答となる資料です。こちらの記事を合わせて閲覧するとより深い理解を得られるでしょう。

RSpecしぐさ

www.slideshare.net

特徴

  • BDD・TDDを踏まえたRSpecとは何かを知ることができる
  • spec等の語彙について深く理解できる

この資料を読んだほうがいい人

MiniTestととの違いが気になっている人。Specをテストという意味だと思ってる人。自然言語としてテスト仕様書としても読みやすいRSpecを書きたい人。

RSpecに関連することを概念的な部分から説明している資料です。この資料を読めば、テストを設計を意味をより大切に感じられると思います。

最後に

他にもおすすめな資料があればぜひ教えてください。

*1:今名付けました

*2:RSpecの書き方・テストとは何か・何のためにテストをするのか・テストはどのような流れで取り組むか等

*3:テストを書きたいだけなのに・・・という感想を聞いたことがある

*4:ベターなコーディング規約のようなもの

Full Cycle Developer ~ さういうエンジニアに私はなりたい~

先日このツイートを目にしました。

このツイートは私がフルスタックエンジニア(という呼び方)に対して抱いていた小さな違和感に答えを出してくれました。 そして私はFull Cycle Developerにこそなりたいのではないか?と思ったので改めて調べてみました。

Full Cycle Developer とは?

設計・開発・テスト・リリース・運用・サポートというソフトウェアのライフサイクル全体を担うエンジニア

のことです。

出典

出典はこの記事のようです。英語ですがわかりやすく説明されていたので興味がある人はぜひ読んでください。 medium.com

参考情報

日本語の情報としてはajitofmで言及されていました。有名な企業の取り組みと合わせて語られていて、とても理解しやすかったです。 ajito.fm 特にFull Cycle Developerについては28分ごろから語られます。

冒頭で引用した (やさいち|yasaichi) (@_yasaichi) | Twitter さんのツイートも参考になります。

Full Cycle Developer の要旨

紹介した資料で十分な理解は得えられますが、私がFull Cycle Developerに関して重要そうだと感じたことを紹介したNetflixの記事とajitofm#37からいくつか抜粋します。

  • Full Cycle Developerには各種使いやすいツールの導入が必要
  • ツールやプラクティスのセットを提供・支援する横断的な組織があるとより良い
  • Full Cycle Developerは全てのライフサイクルにエンジニアリングを適用し、自動化などシステム中心のアプローチによってスケールさせる
  • Full Cycle Developerが生まれた背景にはマネージドサービスの充実や学習環境が整ってきたことがある
  • 近年のエンジニアはFull Cycle DeveloperとSpecialistに二極化している
  • それぞれ向き不向きや好みがあり、Full Cycle Developerのみで良いわけではない

所感

私はこれまでなんとなくフルスタックエンジニアになりたいだとか、CTOを依頼された時に自信を持ってYESと言えるエンジニアになりたい*1とぼんやり考えていました。また、特定の領域に尖ったものを持てず、器用貧乏なだけではないかと悩むこともありました。 しかし、今回Full Cycle Developerという定義づけ・呼び方を知り、自分の目指す姿の輪郭を捉えることができた気がします。

私はユーザの声を聞きたいし、サービスのドメインを理解して優先順位付けをしたいし、データから改善の糸口を探りたいし、設計をしたいし、実装したい。 欲張って、多くのスペシャリストに頼って、全体最適にあらゆるアプローチに取り組んでいきたいです。

*1:CTOに必要な能力を兼ね備えたいだけで、CTOをやりたいわけではない

「DB設計したいNight #4 そーだいさんと失敗から学びながらDB設計したいnight」参加レポート

dbnight.connpass.com に参加してきたのでそのレポートです。Togetterでいいんじゃないかと思うくらい、Tweetの引用がメインになってます。

概要

迷えるDB設計初心者達のための勉強会です。 普段はハンズオン形式ですが、今回は そーだいさん と nakunaruさんのパネルディスカッション形式です。

イベントページより

具体的なDB設計の悩みに対して、そーだいさんや主催チームが語るパネルディスカッション形式でしたが、問いかけをして参加者に考える時間を与えたり、時折参加者にアンケートや質問を取ったりとその場に合わせた・その場にいるからこそ享受できる学びがある勉強会でした。

スポンサー様

会場提供のPIXTA様、綺麗なオフィスのおかげで勉強会が捗りました!ありがとうございます。

フード・ドリンク等の費用サポートのForkwell様、懇親会でも有意義な議論ができました、会話も弾みました。ありがとうございます。

具体的な学び Twitterより抜粋

銀行システムにおける支店の扱いに関する問いについてです。 格納するデータの形式を工夫することで想定外の事態に対応するのも可能だけど、そんなときこそ基本が重要という刺さる言葉をいただきました。

不動産に関して賃貸と分譲などをどう設計するかという問いについてです。 STIでどうにかしてしまいがちだけど正規形では当然ないし、想定外に対応しにくいし、分割しておきたいですね。

あまりVIEWを使っていないので踏んだことはないですが、VIEWでVIEWを作ることは地雷だとしっかり覚えておきます。

1人でDB設計を考えているときに論理設計と物理設計が混ざることはなんども経験があります。またチームでDB設計に関する議論をするときも混同して議論が右往左往したこともありました。注意していきたいです。

参加者にVIEWの使用例を聞いた結果です。実際の具体例をあげてもらったおかげで理解が捗りました。

知見の塊ですね。マテビューなどのRDBの機能を飛び道具と呼んでいたのが印象的で「飛び道具に頼ってしまうのは設計が誤っているとき」というのはしっくり来ました。

不要そうなカラムなどを削除するときのTips非常によかったです。消したい時はぜひ参考にします。

所感・雑感

シンプルにそーだいさんすげえ!と感じました。tweetにも現れています。

また、ディスカッションや懇親会で時折「これはx章にも書いてあることなのですが〜」「私はx章が好きなんですが〜」という声も聞こえてきたので、そーだい本を読んだらDB設計についてさらに理解が深まるだろうし、有意義な議論ができそうだと思いました。(読んでないと伝わらない話ばかりをされるわけではないです)

ということで買いました。頑張って読みます。*1著者が好きな章は16章らしいです。

f:id:ngmt83:20190517013825p:plain
買ったったw

最後に

こっちもいい勉強会の予感がしますね! dbnight.connpass.com

*1:現実と向き合う、向き合った話を書いたしんどい本だと懇親会で聞きました。酒の肴にはならないそうです笑

「MySQLがこわれた」ときに諦めてクリーンインストールする方法

先日開発端末にインストールしていたMySQLが起動しなくなりました。

(実際には壊れた原因に心当たりはあり、簡単に元に戻すのが難しいということがわかっていました)

対応として今回はMySQLクリーンインストールする方針をとりました。何をどうやって入れ直すのかまとめておきます。

クリーンインストールは最終手段です。先に元に戻せないかやってみましょう。 ngmt83.hatenablog.com

やりたいこと

  • 開発端末localのMySQLを完全にアンインストール
  • 指定バージョンのMySQLをインストール
  • 接続用のユーザ作成
  • DB管理アプリ・RailsアプリからMySQLに接続

MySQLRailsでのアプリ開発に使用しており、Railsから接続できる必要があるため含めています。 また、複数バージョンのMySQLを用いる予定はありません。*1

環境

  • OS: macOS Mojave ver 10.14.4
  • shell: fish, version 3.0.2
  • パッケージマネージャ: Homebrew
  • MySQL: MySQL@5.7
  • DB管理アプリ: Sequel Pro
  • Rails: Rails 5.2.0

開発端末localのMySQLを完全にアンインストール

まずはインストールされているMySQLを確認しましょう。

brew list | grep mysql

これでbrewでインストールしてあるMySQLが確認できます。単にmysql以外にもmysql@5.7のようにバージョン指定されたものもあります。アンインストールは次のコマンドで実行できます。

brew uninstall [インストールしたいバージョンのmysql]

uninstallしただけではMySQLの実行時の各種データ・ファイルは残ったままです。仕切り直したいので次のコマンドですべて削除しましょう。

rm -rf /usr/local/var/mysql

データベースのバックアップを取りたい場合は削除する前にmysqldumpしましょう。私は忘れていてひどい目にあいました。

ちなみに「なんかそれっぽいものあるやん」とDB情報を保存していそうな /usr/local/var/mysql 以下のフォルダ(データベース名がついている)をコピーしてバックアップとするのはおすすめしません。私はそれでひどい目に(以下略

指定バージョンのMySQLをインストール

次のコマンドでインストールできるものを確認しましょう。

brew search mysql

今回はバージョン5.7を利用したいため、mysql@5.7をインストールします。

brew install mysql@5.7

これでインストール完了です。しかしこれだけではmysqlコマンドで実行はされません。

これについてはインストール中のログで次のような説明されています。(バージョンにより細部は異なる)

mysql@5.7 is keg-only, which means it was not symlinked into /usr/local,

雑に言うと「mysql@5.7はインストールしたものの、通常のコマンドでは呼び出されない」という意味です。

通常のmysqlコマンドで呼び出すためにはシンボリックリンクを貼るか、インストール先にPATHを通す必要があります。 今回はスタンダードな手法としてインストール時に表示される次の指示に従ってPATHを通しましょう。(バージョンや使用するshellにより細部は異なる)

If you need to have mysql@5.7 first in your PATH run:
  echo 'set -g fish_user_paths "/usr/local/opt/mysql@5.7/bin" $fish_user_paths' >> ~/.config/fish/config.fish

これはshellのconfigにPATHを追加する記述を行うコマンドです。そのまま実行してしまって構いません。*2

configを更新したらそれを反映するために次のコマンドを実行しましょう。(fish shellの場合です)

. ~/.config/fish/config.fish

接続用のユーザ作成

Sequel ProやRailsからMySQLに接続するためのユーザを作成します。

mysql

mysqlツールを起動し、次のようなコマンドを実行しましょう。

mysql> SET PASSWORD FOR [ユーザ名]@localhost = ‘[パスワード]’

root, rootでもいいですが、アプリからの接続ユーザが設定されている場合はそれに従いましょう。

DB管理アプリ・RailsアプリからMySQLに接続

DB管理アプリはSequel Proを使用します。*3設定は簡単で、スクリーンショットのようにユーザ名とパスワードを入力するだけです。

f:id:ngmt83:20190516181924p:plain
Seaqual ProでlocalhostのDB接続設定

Railsアプリの場合は config/database.yml にユーザ名とパスワードを記述しましょう。rails db:createなどDB接続が必要なコマンドが実行できれば成功です。

最後に

説明しておいてなんですが、そもそも開発マシンに直接MySQLのようなDBをインストールするのはおすすめできません。 MySQL環境の構築はなかなかにめんどくさいですし、切り出したコンテナに接続するのもさほど難しくないのでぜひdockerを使いましょう。

*1:その場合は大人しくdockerを使いましょう

*2:実行して変更されたconfigを確認したいときはcat ~/.config/fish/config.fish

*3:Mojaveでは不安定なのでDBeaverに乗り換えたい。https://qiita.com/nanasess/items/609c7cda4adee344221c

「何もしていないのにMySQLが壊れた」ときにとりあえずやること

※可愛いTシャツですが本題とはあまり関係ないです

先日開発端末にインストールしていたMySQLが起動しなくなりました。ちょうどいい機会なのでそんなときどうするかをまとめました。 紹介する処置は簡単に行えるもので大して時間もかからないため、原因に心当たりがあろうがなかろうがすべて試してもいいです。

前提

一度は起動する環境をつくっていたが起動しなくなった。

筆者の環境

  • OS: macOS Mojave ver 10.14.4
  • shell: fish, version 3.0.2
  • パッケージマネージャ: Homebrew

基本のエラーログ確認

最初に状況確認のためエラーログをみましょう。

tail -f /usr/local/var/mysql/[端末名].local.err

ログが十分に存在しない場合は、あえて正常に動作しない操作(mysql.server startなど)を行うのもありです。ログの内容によってはすぐに原因を特定することもできます。

よく見るメッセージの例を1つだけあげておきます。

> ERROR! The server quit without updating PID file /usr/local/var/mysql.

ログを見ても原因がわからない場合は後述する方法で1つずつ確認していきましょう。

なぜか生きているMySQLプロセスが存在する場合

すでに起動している(アクセスはできない)ためにMySQLが起動できないということがありえます。次のコマンドでプロセスを探しましょう。

ps aux | grep mysql

意図しないMySQLプロセスが見つかったときはkillしましょう。

MySQLで使用予定のポートが空いていない場合

ポートが空いていなければMySQLは起動できません。次のコマンドで使用予定ポートの状況を確認しましょう。(MySQLのデフォルトポートは3306です。)

lsof -i :[ポート番号]

停止したはずのMySQLや他のプロセスが使用していた場合は停止(kill)するか、起動するポートを変えるかしましょう。マイクロサービスなど、ポートを多く利用する人はそこそこの頻度で発生しそうです。

ソケットが残っている場合

特に指定なく使っている場合、MySQL用ソケットは1つしか作成できない(名前が重複する)ため、mysql.sockmysql.sock.lockがあると新たにMySQLは起動できません。次のコマンドで確認しましょう。

ls /tmp | grep mysql

意図しないソケットが残っていれば削除(rm)しましょう。 これは再起動やPCのクラッシュなどでMySQLを正常に停止できなかったことが原因です。これはだれでもたまに発生するでしょう。

mysqlフォルダ内のファイルのownerやパーミッションがおかしい場合

MySQL/usr/local/var/mysql内にファイルを作ったり更新したりします。それらのパーミッションが適切に設定されていない場合、MySQLが起動しなかったり特定のタイミングで異常が発生します。パーミッションは次のコマンドで確認できます。

ls -al /usr/local/var/mysql/

私の環境ではデフォルトでownerがユーザ名(私の場合はnagamoto)、groupがadminでした。

基本的にはデフォルト値から変更する必要がないため、これが原因であることは少ないです。しかし、ググって見つけた方法を片っ端から試していると誤って変更してしまうかもしれません。*1chownchmodは慎重に使いたいですし、エラーログにPermission deniedが含まれているときのみパーミッションを疑いましょう。

その他MySQLが壊れる原因

brew upgradeMySQLのバージョンをうっかり(または無意識に)上げてしまい、壊れてしまうことが多いようです。

バージョンアップはMySQL単体では動作しても他のシステムと組み合わせた時に不具合が出ることもあるので丁寧に行いましょう。

最後に

Dockerを使ったらこういう悩みは少なくなるので、ぜひ使いましょう!

*1:実際にchownを使用する検索結果はあった