このブログの技術的なところの暫定まとめ

 Dockerやら自動テスト、継続的デプロイなどなどを個人的に試すプロジェクトとなっているこのブログ。ここ最近施したことと考えを書いておく。

デイリービルドならぬウィークリービルド
=================================
 このブログのバックエンドは.NET CoreのC#で、ビルドされたDLLをDockerコンテナにつっこんだもの。ビルドが必要。.NET Coreはまだ出てきてそれほど間がないので、バージョンアップが活発。
 まだまだまだDockerでやることはあるので、このブログの開発は続行していく。ただ単におもしろいという理由もあるが。だから.NET Coreのバージョンアップは積極的に追う。そうすると、デイリービルドをしておけばどのバージョンで問題が出たかわかって、それがわかればバージョンの変更点をチェックすることで修正箇所の把握が簡単になる。
 デイリービルド、まあちょいとした都合で頻度をウィークリーに落として行ってる。TravisCIで。ビルドということでDockerイメージのビルドまで行ってバージョン番号をタグにつけてDockerHubにプッシュしている。デイリービルドにするとDockerHubで容量を浪費しそうなのでウィークリービルドにしている。

コントローラからOAuthの処理を切り出した、モデルではない何かに
=====================================================
https://github.com/hMatoba/tetsujin/commit/3bbdddc9413b785a601069e401b035d1342beb41
 OAuthの処理は状態がいらんと思っている。OAuthでユーザ情報を持って帰ってきたら、あとはすでに実装してあったUserモデルなりSessionモデルに任せる。OAuthでやるのは、ユーザ情報を持ってくること。そういうわけで、それをやってくれる処理をコントローラから外に出し、モデルとは別のオブジェクトに入れて、コントローラにDependency Injectionで渡した。
comment: 0

テスト勉強 ”初めての自動テスト" メモ2


引き続き↑の本を読んだメモ。


ブラウザ上のユニットテスト
==========================
・ここまでUIテストといったら統合テスト以上に高コストとしていたが、ブラウザ上でのみ完結するユニットテストなUIテストもある。
・UIのユニットテストはJasmineとか。
・テストコードにHTMLを含めるやり方も、外部から読み込むやり方もある。含めた場合はそのテストの可読性が上がる。外部から読み込む場合は、実HTMLを使うであろうからテストとの乖離が起きない。
・要はサーバとの通信をしないクライアントサイドのみで動作するJSのテストという話。


テストの順番(8章)
============
・もちユニットテストから始めて、統合テスト、UIテストへと進んでいく。
・UIテストはUIのデザインが落ち着いてから。それまでは統合テストで十分。UIテストが一件もなくても気にするな。
・不安定なテストは捨てろ。別の方法でカバーすることを考えろ。


プログラミング初級講座(9章)
============================
・スペース(インデント)、命名、重複排除。リファクタリングしような


適切なテストの書き方(10章)
===========================
・テストのクラスとか適切に分離しような(Piexifのテスト、分離できてねーや…)

モック
======
・モックによってアンテスタブルなデータをテスタブルに置き換える。
・モックはテストダブルの一種。
・テストダブルとは…
・モックにするようなオブジェクトはDIで入れる仕組みにするのがよさげ?
・スタブはハードコードなデータ。モックは状態を持ち、テストの監視対象にもなる。
・モックを使ったテストは書き過ぎない。オブジェクトのパブリックAPIで十分。でないとモックの泥沼に沈む。そもそもモックはあくまでモックで実データではないということ。
・ブラックボックス寄りのアプローチでテストをする。メリットは下記。
 ・本物のオブジェクトを扱える
 ・結合度が下がる。
 ・変更がしやすい
 ・カバレッジが高い
 ・オーバーヘッドが減って高効率


TDD
===
・TDDでいくと、複雑な機能の絡み合いも積み重ねられたテストが請け負ってくれる。
・TDDやるならリファクタリングもやりやすい
・前述もしたがUIのTDDは非推奨。
・「さあ、次はケントベックの"テスト駆動開発入門"を読むんだ。



感想
 テスト自動化の潮流がある。もしテスト自動化を推進するならプロダクトコードはテスタブルである必要があり、そうなるとテストを熟知した人が開発メンバにいたほうがよさそう。あるいはレビュアーとかあたりに。
 あと本書では出てきていないけど、UIテストはPageObjectデザインパターンがいいよ。
Seleniumで行っていたテストをPageObjectデザインパターンに書き換えてみる
https://github.com/SeleniumHQ/selenium/wiki/PageObjects
comment: 0

続テスト勉強 ”初めての自動テスト" メモ1

 さいきんやっと私生活の余裕が出てきた。以前に行っていたテスト勉強を、書籍"ソフトウェアテストの教科書"に引き続き、"”初めての自動テスト"を読んで再開した。


テストの種類と特徴
==================
・テストは三つある。UIテスト、結合テスト、単体テスト
・右にいくほどテストコストが軽い
 単体テストは基本的に一つの関数をテストするもの
 結合テストは関数が連動してうまく動いて機能を成すかをテストするもの
 UIテストは一連の機能が、UIをとおして正しく入出力をされるかをテストするもの
 となると、結合テストは単体テストを包括しうる、UIテストは結合テストを包括しうると言える


UIテストのやり方
================
・UIテストは要素にIDをつけてやったほうが楽よ
 →逆の意見
*個人的にはnameでやっている。form要素にはclassやnameはつけても、IDはつけないことがあるので。ただし、IDと違ってnameは一つのHTMLドキュメント内で重複がありうるということは覚えておかないといけない。



*脱線
 「GETはアップロードなどの大容量データを扱う送信には不向き」というような記述があった。GETとPOSTの使い分けの基本的なところとして以前どこかで腑に落ちる説明を読んだ。
 GETはなにか情報が欲しい時に使う。だからGoogle検索とかは基本的にGET。検索結果という情報をサーバに要求する。ブラウザバックしてもクエリに情報があるのでページを見直せる。POSTは情報を一方的に送りたいときに使う。画像アップロードや登録フォームは基本的にPOST。ブラウザバックでPOSTレスポンスのページへ戻ろうとすると「もう一度情報を送信しますか?」といったようなメッセージが出るのは、そもそも情報送信を行った上でレスポンスをするという想定のアクションであるため。


Webアプリの統合テスト
=====================
*ヘッドレスブラウザを使っていた経験から、個人的にUIテストのことを統合テストと呼んでいた。違うのね。RESTfulなリクエストを使ってやるというのを見てなるほどと。RailsはまさにWebアプリ特化だから、ここらもこなれたものがありそうな様子だった。PythonでRESTfulなテストをするとなったらrequestとBeautifulSoupあたりを組み合わせてやるのかな。


単体テスト
==========
・命名としては、「どう」テストしているかより「なにを」テストしているかで命名したほうが意図が掴みやすい。
・ネットワーク接続する機能のテストは避け、モックを使う。
comment: 0

テスト勉強 "ソフトウェアテストの教科書" メモ2

デシジョンテーブル
==================

 ソフトウェアが動作する条件の中でどのようなケースがあるかを把握、そのケースへの対応を確認するためにデシジョンテーブルというのが使える。

 たとえばある映画館で通常1800円、五歳以下無料、65歳以上は半額、毎月一日は1000円とし、複数条件がかぶる場合は安い割引のサービスが適用されるとする。その場合↓の表のようなデシジョンテーブルが作れる(以上、以下の英語表現の細かい部分は抜きで)。上三行が条件、下四行が適用されるアクション(映画鑑賞代)である。
+-------+-------+-------+-------+-------+-------+-------+-------+-------+

|  | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|under 5| Y | N | Y | N | Y | N | Y | N |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|over 65| Y | Y | N | N | Y | Y | N | N |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|1st day| Y | Y | Y | Y | N | N | N | N |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| | | | | | | | | |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | Y | | Y | | Y | | Y | |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 900 | | Y | | | | Y | | |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 1000 | | | | Y | | | | |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 1800 | | | | | | | | Y |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+


基本的には上の表のようになるが、見やすくするために消していいものがある。
・矛盾した条件(五歳以下かつ65歳以上など
・今回の条件では五歳以下ならもうほかの条件に関わらずに鑑賞代が決まる。五歳以下がYの条件を一つにまとめてしまえる(…だが、テストケースとしては一つにまとめずに、条件重複がどう処理されるかという検証を入れておいたほうがよさそう)


状態遷移図
==========

 言わずもがな。たとえばフォームの遷移を表すときは、例外処理まできっちり作っておきましょう。そういった通常動作の外まで動作の洗い出しをするのに有効。


組み合わせテスト
===============

 複数条件を組み合わせて網羅する。テストコストを考えて、すべてのケースを列挙するのではなく二因子網羅などを使うというのが手法。二因子間網羅でのバグ検出率は70-90%ほどという知見がある。これを三因子間などに上げればやはりバグ検出率は上がるが、それはテストコストとのトレードオフ。
 二因子間網羅の表を作るのは手間があるが、それをやってくれるツールがある。
comment: 0

テスト勉強 "ソフトウェアテストの教科書" メモ1

 テストについて改めて体系的に学ぶことにした。そういうわけでソフトバンク出版の「ソフトウェアテストの教科書」とオライリーの「初めての自動テスト」を買ったので読み進めている。まず"ソフトウェアテストの教科書"を読んでいてそのメモ。

ホワイトボックステスト
===================

 ソフトウェアの中身の動作を把握して行うテスト。処理のフローチャートを用意して、そのフローチャートの分岐を網羅するようにテストしたり。

ブラックボックステスト
===================

 中の細かい動作を意識せずに、入力とその結果を見る。たとえばこのブログは、TravisCI上でSeleniumを使って管理メニューへのログインの成功と失敗を試すテストがある。これはブラックボックステストに該当するだろう。

境界値
=====

 たとえば65歳以上の人には割引を適用する販売システムを作ったとする。そうすうと、65歳未満の人には割引がない。この場合、65歳の人に割引を適用し、64歳の人には割引が適用されないことを確認すべきだろう。

同値クラス
========

 上述のシステムの場合、68歳の人や70歳の人には同じ割引が適用される。この同じ結果を返す条件に入るもの同士が、同値クラスと呼ばれる。たとえば60歳の人と50歳の人という条件があったらこれらも同値クラス。


***************
 さいきんどこかのTDDの話題で、「コンパイルに時間がかからない言語だと、TDDって向いてるよね」ってコメントを見た気がする。これはスクリプト言語とかいわれてるあれらのことだろうか。そして裏には「いちいちコンパイルに時間がかかるような言語ではTDDは向いていない」というのがあったりするんだろうか。
 ぼくは会社で唐突に炎上中のVB.NETの案件に入れられることになった。VB.NETなんて書いたことなかったし。TDDもやったことはなかった。ただ自分のOSSでCI/CDは導入していたので、自動テストは書いた経験があった。ぼくはそのVB.NETプロジェクトをTDDで進めて成功した。
 TDDのテストはもちろんコンパイルのあとに行われる。ではTDDではない場合、テストはいつ行うんだ?コンパイル後だろう?どうせテストするならもう自動テストにしておけばいいじゃないか。まさかテストしないでなんてことがあるだろうのか?まあそのまさかがあるのはうわさで聞いている。
 よっぽどコンパイルに時間がかかるような状況なら場合に応じた対応を考えるべきだ。それをコンパイルが必要な言語、不必要な言語でスッパリ分けてしまうのには疑問を感じる。ちょっとぐらい時間がかかろうが、何度も繰り返し手で行うようなことは自動化しておきたい。プログラマは健康のために一時間ごとに席を立って軽く歩いたりストレッチをするべきだと考えている。そのあいだにコンパイルから自動テストまでを走らせておけばいいじゃないかと考えている。
comment: 0