はじめに
こんにちは、Google Cloudのオブザーバビリティ/SRE担当者です。このたび私が翻訳しました「実践プロパティベーステスト PropErとErlang/Elixirではじめよう」という書籍がラムダノート社より去る11月1日に出版されました。書店ならびに各社オンラインストアでご購入いただけます。
実践プロパティベーステスト ― PropErとErlang/Elixirではじめようwww.lambdanote.com
電子書籍についてはラムダノート社のECサイトよりご購入いただけます。
実践プロパティベーステスト ― PropErとErlang/Elixirではじめよう(電子書籍のみ)www.lambdanote.com
「実践プロパティベーステスト」はどのような本か
本書の内容に関しては、すでにラムダノート社の書籍紹介ページで十分に説明されているので、まずはそちらをご一読ください。
プロパティベーステスト(以下、PBT)は関数型プログラミング言語界隈で発展してきた経緯もあり、ユニットテストやファジングと比較するとあまり浸透していないのが現状です。また使い始めようと思うとプロパティを書くところで難しさを覚え、独学でマスターするのはなかなかにハードルが高いものです。実際に私もその部分がネックで、PBTを学びたいと思いつつ、何度か挫折をしていました。そんな中、本書を初めてオンライン版で読んだときに、相変わらずFredのユーモアある解説に感心しつつ、この本であれば習得できるかもしれないと思いました。
本書は、まずPBTとは何か、それ自体の解説から始まり、PBTの根幹である「プロパティ」についての解説、そして探索をうまく行うために欠かせない「ジェネレーター」のカスタマイズ方法、失敗したテストを理解しやすくするための「収縮」の解説、さらにはステートフルなシステムをテスト対象にできる「ステートフルPBT」の解説、とPBTを一通り学ぶために必要な知識を網羅しています。解説に使うサンプルコードやその結果の特性はErlang/Elixirという言語やPropErというPBTフレームワークに依存する部分もありますが、他の言語のPBTフレームワークも大なり小なり同様の機能をサポートしていますので、読み替えを行うことでPBTより深く学べることでしょう。
そもそもPBT自体があまり脚光を浴びることはありませんでした。しかし計算資源をより活用して、ステートレスPBTでユニットテストを強化することはもちろん、ステートフルPBTでe2eテストを強化すること、それこそがソフトウェアエンジニアリングではないでしょうか。もちろん、PBTの場合、プロパティやジェネレーターの実装や、テストを走らせる上での時間的なコストはあります。これは私が普段触れているオブザーバビリティの領域でも同様です。網羅的かつ効率的に探索を行うことで、仕様策定時や実装時に気が付かなかった問題を発見し、その原因を突き止められる確率が高まることの価値は、ますます高まっています。そういった文脈で、本書は皆さんの道具箱に道具を1つどころか、引き出しを1つ追加してくれる、そんな一冊です。
「実践プロパティベーステスト」が出版されるまで
本書はFred Hebertによる "Property-Based Testing with PropEr, Erlang, and Elixir" という書籍の日本語訳版です。原著は2019年1月に出版されました。
以前私は同じくFred Hebertが著した "Learn you some Erlang for great good!" の日本語訳「すごいErlang ゆかいに学ぼう!」(以下、すごいE本)という本の翻訳を行いました。
すごいE本の詳細に関しては出版時にエントリーを書きましたのでご参照ください。
すごいE本ではErlangの基礎から始まり、OTPの発展的な使用方法まで網羅していました。もちろん、その中にはテストに関する章もあり、たとえばEUnitの関する基本的なところから、静的解析(Dialyzer)まで行うのですが、それ以外のより発展的な検証については一切触れられていませんでした。Erlangのエコシステムを知りつつ、他の言語で主に開発を行っていた身としては、Erlangの達人たちが使いこなしていたプロパティベーステスト(PropEr)に関する情報がもっと出てきてほしいなあと思っていました。
そんな折、2017年の半ばにFredがまたPropErに関するテキストをウェブで公開し始めました!
そこにはいままで知りたいと思っていたプロパティベーステストをPropErで実施するための考え方を、すごいE本と同様に一から紹介してくれるものでした。しかも前回とは違い、Creative Commonsではなく、All rights reservedとのこと。これは本が出るのではないか?と思いウェブ版が完成した2018年後半のある日Fredに連絡してみると出版予定とのこと。そこで、すごいE本の編集を担当し、その出版後、オーム社から独立されラムダノートを設立された鹿野さんにダメ元で連絡してみました。
「Fredが書いたプロパティベースベストに関する良書があるんですが、翻訳できませんか」
ラムダノートでこの本を出版する場合、編集作業等で割かれる時間や在庫を考えると、この本はリスクの高いものであることは明らかでした。使用言語はErlang/Elixirという、一応知られてはいる言語であるものの、まだメインストリームとは言えない言語で、さらにテーマは発展的内容のプロパティベーステスト。それだけ見ればニッチ極まりない本です。
しかし、このプロパティベーステストという手法そのものは、計算機の力を活用した素晴らしいテスト手法で、原著出版当時からメジャー言語向けフレームワークも一応存在していました。この本によって需要を起こせるかもしれない、という期待も鹿野さんは理解してくださり、プロジェクトが始まりました。翻訳権の獲得から始まり、原稿用レポジトリの用意までが整ったのは2019年4月。そこからコツコツと翻訳を続けて半分程度まで終わっていたのですが、2020年3月に新型コロナウイルスの蔓延とともに仕事や家庭の状況も一変し、なし崩し的に一時翻訳が中断してしまいました。
その後、2022年5月にようやく生活が落ち着いたこともあり、また並行して走っていた他の翻訳プロジェクトが区切りが付いたため、一気呵成に取り組み2022年6月には一度翻訳を終わらせました。しかし、今度はここから訳文自体の日本語をより自然にする編集作業が始まりました。一度スケジュールが崩れてしまったため、鹿野さんには別の大きなお仕事の合間に編集を行ってもらいつつ、自分は細かな修正をするという作業が続き、とりあえず識者レビューをいただける形までになったのが2022年11月でした。識者レビューを経て、もう一度巻頭から編集し直して、2度めの識者レビューを頂いたのが今年の9月。そこから細かな修正が行われ、10月半ばに無事に校了したという流れでした。
私はこれまでオライリー・ジャパンでの翻訳でお二人の担当に付いていただき、オーム社とラムダノートでは鹿野さん、高尾さんに編集いただいたわけですが、やはり皆さん様々に特徴があると感じました。ラムダノートのお二人の編集は、編集者として徹底して日本語を整えてくださる印象がありました。実際に自分でも読み返してみると、編集前後で日本語として読みやすさが向上していると感じました。
気がつけばきっかけとなったウェブサイトの公開から6年も経っているわけですが、しかしながらその技術的な内容はまったく陳腐化していません。これはPBTがそれだけ強力な概念であるということの証左ではないでしょうか。早く出版できなかったのはひとえに自分の至らなさではあるわけですが、ようやく出版できていまは肩の荷が降りた気持ちです。
他言語におけるプロパティベーステストについて
本書はErlang/Elixirを中心にPBTの解説をしているわけですが、その考え方は汎用的なもので、他のプログラミング言語でも写経しながら進められると思います。以下が自分が知っていたり、ぱっと調べた限りでの他の言語でのPBTフレームワーク一覧です。(網羅しているわけではありません。)
- Java: jqwik
- JavaScript/TypeScript: GitHub - dubzzz/fast-check: Property based testing framework for JavaScript (like QuickCheck) written in TypeScript
- Haskell: QuickCheck: Automatic testing of Haskell programs
- Python: Welcome to Hypothesis! — Hypothesis 6.88.1 documentation
- Go: GitHub - flyingmutant/rapid: Rapid is a modern Go property-based testing library
- Rust: Introduction - Proptest
- Kotlin: Kotest | Kotest
- Scala: GitHub - scalaprops/scalaprops: property based testing library for Scala, ScalaCheck
- Ruby: prop_check | RubyGems.org | your community gem host
もちろんフレームワークによって対応の度合いは異なるので、これらを使って本書をErlang/Elixirとまったく同様に進められるわけではありません。たとえばPythonのHypothesisではジェネレーターは意図してランダム値になるように振っていて、PropErのように意図して偏らせるようなことができません*1。また上には列挙していませんがGoのgopterというフレームワークではステートレスPBTしか実現できません*2。
謝辞
書籍中の謝辞でも書いていますが、あらためて、本書は次のみなさまのご協力なしには出版はありえませんでした。特にErlang/Elixirに関しては趣味レベルの私とは異なり、業務でErlangとPBTを使われていた経験がある、また今まさに現役でErlang/Elixirを書いている皆様方からいただけたレビューは本書の質を最後に押し上げてくださるものでした。あらためて感謝いたします。
レビュアーのみなさま(五十音順)
- 上西康太さん(@kuenishi)
- 大田健さん(@sile)
- 大原常徳さん(@ohr486)
- 篠原俊一さん(@shino)
- 宮崎達矢さん(@ta_ta_ta_miya)
ラムダノートのお二方
- 鹿野桂一郎さん
- 高尾智絵さん