バグの修正の前に再現テストを先に書く [プログラマー現役続行]
2003年以降、私自身のソフトウェア開発は、テスト駆動開発が基本です。ただ、私自身が開発せずに、指導やレビューを行ったテスト駆動開発もあります。
経験した中で大規模で技術的に複雑だったテスト駆動開発は、以下の二つです。
コピー/スキャン/プリントなどの複合機※をテスト駆動開発でスクラッチから開発した経験やノウハウは、部分的にJaSST'18 Tokyoの招待講演とJaSST'19 Tokaiの特別講演で話しました。
※ 今日のオフィスにある富士ゼロックスやリコーなどのデジタル複合機のソフトウェアは、ソースコードの量として1,000万行に達しているようです。残念ながら、ほとんどが自動テストがないレガシーコードです。
テスト駆動開発の経験がない人がテスト駆動開発のプロジェクトに従事したときに、テストコードを書くことに加えて難しいのは「テストファースト開発」と「バグの修正の前に再現テストを先に書く」ことです。
2.では、原因が分かったので、「パスしない再現テストを作成する」ことが重要です。そのようなテストを作成した経験のないエンジニアの場合、作成せずにいきなり不具合修正を行ってしまいます。不具合を修正したと報告を受けたときに、「再現テストは書いた?」と聞くと「書いていません」という返事をもらったことが多々ありました。
最後に不具合を修正して、2.で作成したテストがパスすることを確認します。同時に、既存のすべてのテストがパスすることも確認します。
不具合の原因によっては、再現テストを書くのが非常に難しことがあります。特に不具合の発生がスレッドのスケジューリングに依存する場合です。その場合には、ロギングを工夫して、テストコードからスケジューリングを指定できる機構を入れたこともあります。
経験した中で大規模で技術的に複雑だったテスト駆動開発は、以下の二つです。
- 2003年2月から2009年8月:Linux/C++によるデジタル複合機コントローラソフトウェア
- 2013年7月から20015年5月:Linux/Goによるデジタル複合機コントローラソフトウェア
コピー/スキャン/プリントなどの複合機※をテスト駆動開発でスクラッチから開発した経験やノウハウは、部分的にJaSST'18 Tokyoの招待講演とJaSST'19 Tokaiの特別講演で話しました。
※ 今日のオフィスにある富士ゼロックスやリコーなどのデジタル複合機のソフトウェアは、ソースコードの量として1,000万行に達しているようです。残念ながら、ほとんどが自動テストがないレガシーコードです。
テスト駆動開発の経験がない人がテスト駆動開発のプロジェクトに従事したときに、テストコードを書くことに加えて難しいのは「テストファースト開発」と「バグの修正の前に再現テストを先に書く」ことです。
不具合への対処手順
何らかの不具合が発見、あるいは報告されたときの手順は次のようになります。- 不具合の原因の調査
- 不具合の再現テストの作成
- 不具合の修正
2.では、原因が分かったので、「パスしない再現テストを作成する」ことが重要です。そのようなテストを作成した経験のないエンジニアの場合、作成せずにいきなり不具合修正を行ってしまいます。不具合を修正したと報告を受けたときに、「再現テストは書いた?」と聞くと「書いていません」という返事をもらったことが多々ありました。
最後に不具合を修正して、2.で作成したテストがパスすることを確認します。同時に、既存のすべてのテストがパスすることも確認します。
不具合の原因によっては、再現テストを書くのが非常に難しことがあります。特に不具合の発生がスレッドのスケジューリングに依存する場合です。その場合には、ロギングを工夫して、テストコードからスケジューリングを指定できる機構を入れたこともあります。
まとめ
パスしない再現テストを書く習慣を持つことは重要です。テスト駆動開発を行っているのであれば、テストファースト開発と共に意識して行ってみてください。2019-10-25 07:26
コメント(0)
テストファースト開発 [プログラマー現役続行]
(私自身のテスト駆動開発については、こちらにまとめてあります)
一年以上、メルペイでウェブサービスのbackendのマイクロサービスを開発していますが、組み込み系のソフトウェア開発と異なり、短期間に新たな機能を開発してリリースすることが求められます。2週間のスプリント単位でリリースしていますが、一つのスプリントで数個の機能を開発することも普通になっています。現在は、ウェブブラウザのフロントにAPIを提供しているあるマイクロサービスを担当しているため、機能の追加は、既存のAPIの仕様変更だったり、新たなAPIの追加だったりします。
2.では、既存の実装の作り(構造)とテストコードを調べることになります。新たな機能をどのように作ればよいか、理解できるまで調査します。理解できたと判断したら、3.へ移ります。
3.の開始に際して、修正を行うマイクロサービスの既存のテストのフレームワークでは、私が書きたいテストが書けない場合があります。その場合には、新たなテストフレームワークの構築を行います。実際、メルペイで最初に担当したマイクロサービス用に私が開発したテストフレームワークを導入することが多いです。
3.と4.は実際には繰り返し行っていきます。まず、3.でAPI呼び出しがエラーになることが期待されるテストコードを書きます。そして、期待されるエラーが返ってこない(実際には実装部分には単純に
エラーの実装が終わったら、正常ケースのテストコードを書きます。この時点でも該当する実装部分には、
すべてのテストの作成とその実装が完了したら、コードを見直して、リファクタリングです(5.)。そして、最後にPRのレビューをTech Leadへ依頼することになります。
私自身がテストファーストで開発している主な理由は、短い勤務時間で担当する開発を着実に間違いなく行うためです。私自身は、テストファースト開発を最近始めたのではなく、昔から行っています。しかし、今は強く意識して行っています。
テスト駆動開発とテストファースト開発には、ある程度の規律を必要とします。たとえば、不具合を修正する場合には、原因を調査後に、「再現テストを書いてから実装を修正する」ことが求められます(これも一種のテストファーストです)。本来、そのような規律は、ペアプログラミングなどを通して強制して習慣化させる必要があります。しかし、PRを最後にレビューするという開発スタイルの開発組織では、難しいものがあります。
スポンサーリンク
一年以上、メルペイでウェブサービスのbackendのマイクロサービスを開発していますが、組み込み系のソフトウェア開発と異なり、短期間に新たな機能を開発してリリースすることが求められます。2週間のスプリント単位でリリースしていますが、一つのスプリントで数個の機能を開発することも普通になっています。現在は、ウェブブラウザのフロントにAPIを提供しているあるマイクロサービスを担当しているため、機能の追加は、既存のAPIの仕様変更だったり、新たなAPIの追加だったりします。
開発順序
現在担当しているマイクロサービスは、その開発の当初から私自身が関わっていたものでないため、既存のコードを調査して理解する必要がある場合が多く、開発はおおまかに次の順序となります。- 既存のAPIの仕様の記述の変更、もしくは、新たなAPIの仕様の記述
- 既存のAPIの実装の調査(新たなAPIの場合には似たAPIの実装の調査)
- テストコードの作成
- 機能の実装
- リファクタリング
2.では、既存の実装の作り(構造)とテストコードを調べることになります。新たな機能をどのように作ればよいか、理解できるまで調査します。理解できたと判断したら、3.へ移ります。
3.の開始に際して、修正を行うマイクロサービスの既存のテストのフレームワークでは、私が書きたいテストが書けない場合があります。その場合には、新たなテストフレームワークの構築を行います。実際、メルペイで最初に担当したマイクロサービス用に私が開発したテストフレームワークを導入することが多いです。
3.と4.は実際には繰り返し行っていきます。まず、3.でAPI呼び出しがエラーになることが期待されるテストコードを書きます。そして、期待されるエラーが返ってこない(実際には実装部分には単純に
panic("Not Implemeted Yet")
と書いてあるだけ)のを確認して、4.としてその部分の実装を行います。エラーの実装が終わったら、正常ケースのテストコードを書きます。この時点でも該当する実装部分には、
panic("Not Implemeted Yet")
と書いてあるだけなので、テストが合格しないのを確認して、実装を行います。すべてのテストの作成とその実装が完了したら、コードを見直して、リファクタリングです(5.)。そして、最後にPRのレビューをTech Leadへ依頼することになります。
テストファースト開発について
上記の開発順序は、私個人の開発順序です。実際に、最後のPRのレビュー依頼を行った時点では、テストコードと実装の両方が揃っていますので、どのような順序で開発しているかは分かりにくいです。私自身がテストファーストで開発している主な理由は、短い勤務時間で担当する開発を着実に間違いなく行うためです。私自身は、テストファースト開発を最近始めたのではなく、昔から行っています。しかし、今は強く意識して行っています。
課題
ペアプログラミングがほとんど行われてない職場では、各人がどのような順序で開発しているのかが分かりにくいという問題があります。テスト駆動開発とテストファースト開発には、ある程度の規律を必要とします。たとえば、不具合を修正する場合には、原因を調査後に、「再現テストを書いてから実装を修正する」ことが求められます(これも一種のテストファーストです)。本来、そのような規律は、ペアプログラミングなどを通して強制して習慣化させる必要があります。しかし、PRを最後にレビューするという開発スタイルの開発組織では、難しいものがあります。
お勧め本
僕たちの厳密さの一つの例が、自動化したユニットテストをテスト対象のコードより先に書くというルールだ。たいていのプログラマーはすぐにコードを書きたがる。書き上がれば出来映えに自己満足して、そのコードのために自動テストを書こうという気にはなかなかならないものだ。こういった習慣をやめてしまうのは簡単だろうが、僕たちがコードに期待する品質には極めて重大なものなのだ。テストコードを対象コードの前に書くという規律により、常に守れるようになるわけだ。
リチャード・シェリダン著『Joy, Inc.』(日本語版、p.212)
スポンサーリンク
2019-10-18 08:07
コメント(0)
複業を20年 [プログラマー現役続行]
振り返ってみると私自身がまだ40歳であった2000年の初めからほぼ20年間複業をしてきました。1984年に社会人になって、1999年までは会社での開発業務という単一の仕事をしていたのですが、2000年からは主に次の三つです。
社会人となってから、実際に自分でコードをほとんど書いていないかったのは、日本オラクル、ジャストシステム、富士ゼロックス情報システム(FXIS)での最初の5年、リコーでの8年です。プログラミングしていないといっても、FXISやリコーではさまざな技術レビューは行っていました。
おそらく、会社の仕事だけをずっとしていたとしたら、今も実際にプログラミングしながらソフトウェア開発をしていなかったかもしれません。マネージャとして管理職業務を行いながら、ソフトウェア開発を続けるには、複業を行っていたことが大きな要因かもしれません。
2017年9月からは、週4日勤務で働き、金曜日に個人として技術教育を行っています。ソラミツでは雇用契約そのものを週4日にしてもらって働いていました。メルペイではそのような雇用形態は(現在は)なく、正社員として働いています。しかし、金曜日は原則欠勤しています。もちろん、欠勤すれば不足労働時間に対する勤怠控除が行われ給与が減額されます。
地方での講演の依頼に対しては、多くは手弁当で、妻と旅行を兼ねて行くことが多いです。函館、鹿児島、岡山、高松、長野、徳島、仙台、新潟、名古屋などがそうです。
技術書の翻訳も、継続して続けており、翻訳を通して技術を学習したり、自分の知識を再整理したりしますし、著者と多くのメールのやり取りをすることも多いです。現在は、私にとって18冊目になる技術書の翻訳を行っています。
何歳まで続けられるか分からないですが、まだまだソフトウェア開発を続けていきたいと思っていますし、複業も続けていきたいと思っています。
- 会社での開発業務(マネジメントや社内コンサルティングも含む)
- 技術教育や講演
- 技術書の執筆(雑誌の記事を含む)や技術書の翻訳
1. 会社での開発業務
1984年4月に富士ゼロックスに就職してから、6回の転職を経て現在はメルペイで働いています。社会人となってからは、自分で実際にソフトウェア開発をしている時期もあれば、開発のマネージャをやっていることもありますが、現在は、毎日Go言語でbackendのサービス開発をしています。社会人となってから、実際に自分でコードをほとんど書いていないかったのは、日本オラクル、ジャストシステム、富士ゼロックス情報システム(FXIS)での最初の5年、リコーでの8年です。プログラミングしていないといっても、FXISやリコーではさまざな技術レビューは行っていました。
おそらく、会社の仕事だけをずっとしていたとしたら、今も実際にプログラミングしながらソフトウェア開発をしていなかったかもしれません。マネージャとして管理職業務を行いながら、ソフトウェア開発を続けるには、複業を行っていたことが大きな要因かもしれません。
2. 技術教育や講演
2000年から2017年8月までは主にグループ会社向けの技術教育が中心でした。最も長く続けているのはJava研修ですが、それ以外にもさまざな技術教育をグループ会社向けに行っていました。技術教育によっては会社が売り上げを上げるものはありましたが、私自身は、社員として業務の一部として行っていましたので、技術教育で別途私に収入があるわけではありませんでした。2017年9月からは、週4日勤務で働き、金曜日に個人として技術教育を行っています。ソラミツでは雇用契約そのものを週4日にしてもらって働いていました。メルペイではそのような雇用形態は(現在は)なく、正社員として働いています。しかし、金曜日は原則欠勤しています。もちろん、欠勤すれば不足労働時間に対する勤怠控除が行われ給与が減額されます。
地方での講演の依頼に対しては、多くは手弁当で、妻と旅行を兼ねて行くことが多いです。函館、鹿児島、岡山、高松、長野、徳島、仙台、新潟、名古屋などがそうです。
3. 技術書の翻訳など
2000年から技術書の翻訳を私的な時間に始めたのですが、同時に技術雑誌に記事を書くようにもなりました。雑誌の記事は2007年まで続いており、記事をまとめて単行本にしたのが『プログラマー現役続行』、『ソフトウェア開発の名著を読む』、それに『Java 2 Standard Edition 5.0: Tiger』です。技術書の翻訳も、継続して続けており、翻訳を通して技術を学習したり、自分の知識を再整理したりしますし、著者と多くのメールのやり取りをすることも多いです。現在は、私にとって18冊目になる技術書の翻訳を行っています。
振り返ってみて
60歳を目前にしてプログラミングしながらソフトウェア開発を続けられているのは、複業をこの20年間を行ってきたからではないかと思います。それぞれの活動が、いろいろな側面で相互に影響してきたと思います。何歳まで続けられるか分からないですが、まだまだソフトウェア開発を続けていきたいと思っていますし、複業も続けていきたいと思っています。
2019-10-11 07:19
コメント(0)
JaSST'19 Tokaiで話しました [プログラマー現役続行]
10月4日(金)に愛知県刈谷市で開催された「ソフトウェアテストシンポジウム 2019 東海」で「私が経験したソフトウェアテスト 〜 ワークステーション、組み込みシステム、ウェブサービス 〜」と題して話しました。JaSSTでの講演は、JaSST'16 Niigataが初めてでしたので、今回で3回目となります。JaSSTの翌日の土曜日は、トヨタ産業技術館、名古屋城、徳川園、徳川美術館と観光して、日曜に横浜に戻ってきました。
今回のJaSSTでは、昨年のJaSST'18 Tokyoでの講演内容を修正して、メルペイでの経験も追加した内容を話しました。
私の講演は午後2時からでしたので、講演後はkyon_mmさんの「アジャイル井戸端会議」のセッションに参加し、その後は情報交換会ということで、参加者といろいろと話しをすることができました。
3年前の新潟のときもそうですが、多くのソフトウェア開発組織でまだまだテスト駆動開発や継続的インテグレーションが普及していないというのを痛感しました。「継続的インテグレーションは強みでなくなった」という記事を書いたのが7年前ですが、なかなか当たり前にならないようです。
現在、私自身はメルペイでbackendのサービスの開発をしていますが、短い勤務時間※に担当する新たな機能や機能修正を確実に開発するために、テストファースト開発に日々努めています。
※ 単に、私自身の勤務時間が短いだけです。
今回のJaSSTでは、昨年のJaSST'18 Tokyoでの講演内容を修正して、メルペイでの経験も追加した内容を話しました。
私の講演は午後2時からでしたので、講演後はkyon_mmさんの「アジャイル井戸端会議」のセッションに参加し、その後は情報交換会ということで、参加者といろいろと話しをすることができました。
3年前の新潟のときもそうですが、多くのソフトウェア開発組織でまだまだテスト駆動開発や継続的インテグレーションが普及していないというのを痛感しました。「継続的インテグレーションは強みでなくなった」という記事を書いたのが7年前ですが、なかなか当たり前にならないようです。
現在、私自身はメルペイでbackendのサービスの開発をしていますが、短い勤務時間※に担当する新たな機能や機能修正を確実に開発するために、テストファースト開発に日々努めています。
※ 単に、私自身の勤務時間が短いだけです。
2019-10-08 07:01
コメント(1)