JSTQB認定テスト技術者資格Foundation Levelに合格した

JSTQB認定テスト技術者資格Foundation Level第13回 試験結果が今日公開された。僕はこっそり受験していて、結果は無事合格だった。

勉強はシラバスとJSTQB公認テキスト(『ソフトウェアテスト教科書 JSTQB Foundation 第3版』)を読んだ程度で、それでも「まあ受かるだろう」と高をくくっていたのだが、試験問題は意外と難しかった。購入して間もないドラクエ10に気を取られ、勉強に身が入らなかったせいかもしれない。

なお、情報処理技術者試験の秋期は受験を見送ることにした。これははっきりとドラクエ10のせいだ。はぁ…。

GOOS本の手法をWebアプリ開発に活かしたい

実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる』(GOOS本)に刺激を受けた。本書の手法をWebアプリ開発に活かしていきたい。

訳者の一人である和智さんの記事にあるとおり、「GOOS流TDDの核心は受け入れテストとユニットテストにより構成される二重のループ」である。二重のループ自体は2007年の記事「[動画で解説]和田卓人の“テスト駆動開発”講座:第8回 テスト駆動開発の「サイクル」――まず受け入れテストで土台を作る」でも紹介されており、目新しい手法ではない。本書の価値は、オークション入札アプリの開発を例に、二重のループを「実践」している点にある。どのように実践しているかは、本書を読んでのお楽しみ。

本書では、オークション入札アプリをSwingで構築しているが、Webアプリ開発にだって、二重のループを適用できるはずだ。原著者の一人であるSteve Freeman氏のGOOSメーリングリストへの投稿によると、少なくとも受け入れテストのレベルでは、GUIアプリでもWebアプリでもテストの書き方はさほど変わらないだろうとのことだ。実際、いわゆるPet Storeアプリを二重のループで書いたとの投稿もある。アプリのリポジトリをながめると、下記の受け入れテスト部分はたしかに、本書のオークション入札アプリのそれに似ている。

ちなみに僕は、Capybaraで受け入れテストを書くのが面白そうだと思っている。Webアプリのネタが浮かんだら、ぜひ書いてみたい。

CSRF対策のhiddenパラメータとHTTPキャッシュ

CSRF対策として、hiddenパラメータにセッションIDを出力する手法がある。この手法を採用するとき、HTTPレスポンスのキャッシュはどう制御すべきだろうか。

非共有キャッシュは活用したい

まず、一切キャッシュさせない方針がありうる(Cache-Control: no-store)。これで問題ないのであれば、もう何も考える必要はない。今回の記事では、そうではなく、非共有キャッシュを活用する方針を前提としたい(Cache-Control: private)。REST厨だからだ。

ここから先は、キャッシュの有効期限を明示的に指定できるかどうかによって話が変わってくる。

有効期限を明示的に指定できる場合

有効期限を明示的に指定できる場合は、以下のようなレスポンスヘッダを返すのがよいだろう。

Cache-Control: private,max-age=1800
Vary: Cookie

Cache-Controlで、非共有キャッシュへのキャッシュを許可するとともに、有効期限を明示的に指定する。

重要なのは「Vary: Cookie」だ。指定しないと、再ログインによってセッションIDが変わったり、ログアウトによってセッションIDが無効になったりしても、有効期限内であればキャッシュが使われてしまう。

有効期限を明示的に指定できない場合

有効期限を明示的に指定できない場合は、以下のようなレスポンスヘッダを返すのがよいだろう。

Cache-Control: private,must-revalidate
ETag: "hogehoge"
Last-Modified: Thu, 13 Sep 2012 01:23:45 GMT

有効期限を明示的に指定できないのは、常に新鮮なレスポンスを返したいからだ。よって「Cache-Control: must-revalidate」を指定し、キャッシュの常時検証をクライアントに指示するのがよいだろう。

検証条件として、上記の例ではETagとLast-Modifiedを返している。少なくとも一方は返し、If-None-MatchやIf-Modified-Sinceを用いた条件付きGETに対応する必要がある。

「Vary: Cookie」がないのは、セッションIDの変化に応じてETagやLast-Modifiedが変わるのを前提としているためだ。気になるなら返してもよいだろう。

JavaScriptでキャッシュをさらに有効に使う

さらに考えると、セッションIDが変わっただけでキャッシュが無効になるのは、もったいない気がしてくる。hiddenパラメータへのセッションIDのセットをクライアントサイドで処理するのはどうだろうか。文脈は違うが「Kazuho@Cybozu Labs: CSRF 対策 w. JavaScript」や「畑@サイボウズ・ラボ - CSRF対策 with JavaScript」で紹介されている手法である。

メリットとして、レスポンスにプライベートな情報が含まれない場合に、共有キャッシュの使用が可能になる(Cache-Control: public)。

また、セッションIDが変わっただけではキャッシュの検証が不要になる。キャッシュのヒット率が上がるし、サーバ側はリソースの本質的な変化だけを気にすればよいから実装が楽になる。良いことずくめではないだろうか。

プロフィール
2001年からWebエンジニアをやってます
カテゴリ別アーカイブ
記事検索