@ledsun blog

Hのキーがhellで、Sのキーがslaveだ、と彼は思った。そしてYのキーがyouだ。

忍者式テストとは?

「忍者式テストの定義が知りたい」という意見を観測しました。 実践者の一人として、現時点の理解を記録します。

簡単に言うと?

忍者式テストは、手動テスト手法の1つです。 開発者が、日々のテスト実施を通して

  • テスト項目
  • ユーザーとしての視点
  • テスターとしての視点

を育てていく手法です。

どういうときに向いている?

どうやって実施する?

  1. 毎日、全てのテスト手順を最初から最後まで実行する
  2. テストを実施しながら、テスト手順を修正する
    1. 間違っているテスト手順を見つけたら修正する
    2. 足りていないテスト手順を見つけたら追加する

準備

最新のプロダクトをユーザー(の立場)で操作できる環境

  • 本番環境である必要はありませんが、本番と同じ機能が動く必要があります
  • データはダミーでもいいですが、本番と差が少ない方が違和感に気づく効果が大きいです
  • APIしかないプロダクトには向きません

手動テスト項目

  • 最低1つで十分です
  • テスト項目の網羅性や効果は気にしなくて良いです。バグが見つかるテスト項目でなくて構いません
  • テスト実施者が再現できる手順であれば良いです。プロダクトに対する知識のない人が、再現できるテスト項目である必要はありません

毎日の作業時間(数分 〜 1時間)

  • 最初は数分で終わります。物足りない感じすらあります
  • 1時間を越えると、集中力が切れます。おすすめしません

嬉しさ

小さなテスト手順書から始められる

  • 網羅性の高いテスト手順書をつくるには、プロダクトの機能への理解が必要です
  • プロジェクトに参加したてで、プロダクトへの理解が半端な段階から始められます

発見がある

毎日テストを実行すると色々な発見があります。

テスト手順に対して

  • テスト手順の順序の非効率さ
  • テスト手順のわかりにくさ
  • テスト手順と違う操作をしてみたくなる

テスト手順と違う操作をしてバグが見つかったとき、その手順は新しい有効な(バグが見つかる)テスト手順です。 新しいテスト手順として、テスト項目に追加しましょう。

プロダクトに対して

プロダクトに違和感を感じる時があります。

  • 作っている時は気づかない
  • 初めて使った時もわからない
  • シナリオで操作すると、前の画面と今の画面の機能が矛盾していることに気付いたり
  • 違和感は、(仕様の)バグかもしれない

違和感を見つけたら、違和感の原因を考えましょう。 もっと良い機能やインタフェースが見つかるかもしれません。

ユーザーの立場や気持ちへの理解が深まります。 作るのが面倒で使って嬉しい機能を作るモチベーションになります。

新しいバグ

  • Testing vs. Checking « Developsense Blog の話
  • 自動テストでは、違和感を検出できない
  • 明確なassert違反しか発見できない
  • assert違反はテストが壊れているだけで、バグとは限らないかもしれない

assert違反から学べることは、プロダクトコードのミスか、テストコードのミスです。 違和感からはプロダクトを使う背景や、ユーザーの気持ちが学べます。失敗した時の嬉しさは、自動テストより手動テストの方が多いです。

バグを埋め込んでから発見するまでの時間が短い

毎日、テストを実施するとしょうもないバグを翌日に見つけることができます。 昨日の作業は覚えているで、デバッグが簡単です。

一週間後に気付いたときは、一週間前に実装した機能を思い出すのは一苦労です。 脳みそのワーキングメモリが節約できます。

何ではないの?

  • 自動テストではない
  • 完璧なテストハーネスではない
  • テスト項目がをふやす続けると、どこかで減らす必要がある。が、減らす方は扱わない
    • つまらないテストを減らすのがよい
  • しばらく実施していないテストの戻し方は扱わない
    • ラウンドロビン
    • ランダム入れ替え
    • プロダクトコードの変更箇所に応じて選ぶ

忍者式テストだけでは、そんなに長い期間は戦えません。 状況に応じて、工夫を追加していきましょう。

歴史

sho.tdiary.net

歴史上に「忍者式テスト」が出現したのは、2004年です。

その他の参考情報

忍者式テストを最初に初めて名前をつけた、咳の2014年のスライドにも書いてあります。

名前

タケカワユキヒデ氏の英単語の学習方法に、「毎日に最初から覚えたかどうかチェックして、一定時間で到達できた場所で進捗を管理する」な手法があり、それが「忍者式」を冠していて、そこから「忍者式テスト」と名付けたそうです。

いつだったか、咳さんに聞きました。正確な内容は覚えていません。

おまけ

Clojureを学ぶ

RICH HICKEY氏の発言がめちゃくちゃ面白かったので、Clojureを学ぶことにしました。

この資料は、RICH HICKEY氏の発表を解説してくれる勉強会の資料のようです。 clj-nakano.connpass.com 該当会には参加していませんん。

環境を作る

leiningenというものを作ると環境構築が簡単なようです。

MacではHomebrewからインストール可能です。

brew install leiningen
lein --version
Leiningen 2.8.1 on Java 1.8.0_25 Java HotSpot(TM) 64-Bit Server VM

REPL

REPLがあります。 lein replで起動します。

~ lein repl                                                                    ~
nREPL server started on port 58165 on host 127.0.0.1 - nrepl://127.0.0.1:58165
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b17
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> 

Hello Woldしてみます。

user=> (println "hello world")
hello world
nil

1から10までを足す

簡単なお題で練習してみます。

足し算

user=> (+ 1 2 3 4 5 6 7 8 9 10)
55

和の公式で

user=> (/ (* (+ 1 10) 10) 2 )
55

再帰呼び出し

user=> (defn sum
  #_=>   [list]
  #_=>   (if (= (count list) 0)
  #_=>     0
  #_=>     (+ (first list) (sum (rest list)))))
#'user/sum
user=> (sum [1 2 3 4 5 6 7 8 9 10])
55

再帰が深くなる場合は、末尾最適化をしないといけないらしいです。

reduce関数

user=> (reduce + [1 2 3 4 5 6 7 8 9 10])
55