読者です 読者をやめる 読者になる 読者になる

「第二回 システムテスト自動化 標準ガイド 読書会」に参加してきた

ソフトウェアテスト

前回に引き続き参加してきました。

第二回 システムテスト自動化 標準ガイド 読書会
今回は3、4章がテーマ。

3章

http://www.slideshare.net/dnoguchi/3-20150523-48477354

保守性の高いテストスクリプトを書くために、というお話。

  • テストスクリプトとプログラミングは似ている
  • 良いスクリプトと悪いスクリプト
    • 良いスクリプトについて書かれていることは、良いプログラミングと同じ事
    • 「どういうのが良いスクリプトか」の内容については、そりゃそうだよねという感想
  • スクリプトにはきちんとしたドキュメントを残そうという話
    • バージョン管理(Git)やWebDriver/Gebを使えば基本いらないように感じた
  • スクリプトの種類(上から下に向かうにつれて、よりよいスクリプト)
  • スクリプト前処理
    • メンテしやすいようにフォーマットとか定数とか気をつけましょうという話
    • 発表者の方も仰っていたけど当然だよねという話
      • 3章全体がそんな感じではある
      • この本は「基本を書いている」らしいので、そういうレベルのこともあるのかな
      • もしくは当時はこれが当然と思われてはいなかったのか
  • 会場でのディスカッションにて
    • テストスクリプトは完全にDRYにすると読みにくくなる
      • 同感。最近は自分もそう感じるようになっているのでそこまでDRYを心がけていない
    • どのスクリプト手法でもPros/Consがある
      • ただしデータ駆動についてはConsが少なかった

4章

実行結果と期待値の比較について。

  • 「何を」「どのくらいの粒度で」比較するかを検討するのが大事
    • 強く同感
  • 比較の種類
    • 動的比較、実行後比較(静的比較?)
    • 定義及び何のために分けているのかイマイチ不明
    • 質問を投げてみたが、みなさんも定義がもやっとしている様子
      • 実行後比較については刊行当時のツールの制約があるのかもしれないとのこと
  • 単純な比較と複雑な比較
    • 単純な比較: 素直に比較を取る
    • 複雑な比較: 条件付きで比較を取る
      • 例: IDはアカウントによって異なるので差分に含めない
  • テストツールとテストハーネスの関係についての図(P142)
  • 1つの欠陥につき1つのテストケースが失敗するのが理想
  • センシティブかロバスト
    • 基本的なところはセンシティブ、詳細なところはロバストがおすすめ戦略
  • 実行結果と期待値を等価的に扱うためにフィルタを用いる
    • 日付はハイフンに統一するとか
    • 例:HTML全部を比較するようなセンシティブなテストで、IDとか日付とかを固定文字列に置換する
    • 例:画面のエラーメッセージの順番が定まっていないときにsortする
  • 現場の状況(プロジェクトや製品の性質、メンバースキルなど)を理解して方法を選択する
    • これは比較に限らずって感じ

感想

前回に引き続き有意義でした。
今回は懇親会にも参加し、色々とお話が聞けたのも良かったです。

  • 動的比較と実行後比較はやっぱり分かり辛いよね
    • (本編でも議論されていましたが)テスト実行後に出来たファイルを目視確認するとかが実行後比較? -> いやそれは動的じゃない?とか
  • データ駆動とキーワード駆動について
    • 本ではキーワード駆動が最上位という感じだけど、データ駆動とキーワード駆動については一長一短なのでは
    • テスターとプログラマーが分かれているなどの大規模案件だとキーワード駆動の効果は大きそう
    • プログラマーがテストも行うような小規模だとデータ駆動が丁度良いのではないか
  • 画面テストではやはりIEは対象外にするのが平和である
  • テスト以外の話題も(むしろそっちの方が多かったかも)
    • 採用について
    • マネジメントについて
    • モチベーションについて

参加された方々のポジションも様々で、品質/プロダクティビティエンジニア/人事などなど。
プロダクティビティエンジニアという呼び方は知りませんでした。
分野的にはエンジニアリングプロダクティビティと呼ぶのだとか。噛みそう。

あとお店の食べ物が美味しかった。

私はこの日体調が悪く、前半は普通に喋れていたのですが後半は体調が悪化して口数が減ってしまいました。
前述した「ドキュメントはどの粒度で書くべきか」という話もしたかったのですが体力尽きていた。次回は体調を万全にしておきたい。

直近でのテスト関係のイベントをいくつか教えて頂きました。

「第一回 システムテスト自動化 標準ガイド 読書会」に参加してきた

ソフトウェアテスト

第一回 システムテスト自動化 標準ガイド 読書会に参加してきました。
今回は1、2章がテーマ。

1章

http://www.slideshare.net/fujisawa_y/20150418-46648838

  • テスト管理
  • テスト設計
    • モデルベースドテスト
      • 開発に使ったモデルからテストを作るのでなく、テストのためのモデルを再設計する?
      • まだリンク先の資料を読んでいない
    • PictMasterやCEGTestなどのツールがある
  • ブラウザテスト
    • メンテコストが高いと感じているがどうだろう
      • やっぱメンテコスト高いねという話
      • xpathとかを扱っていると死にやすい
        • classやidを振っているとまだ変更に対応しやすい
    • Gebがいいよって話
    • WebDriverの本がそのうち出るらしい(別々の方から2冊)
  • 負荷テストはJMeterよりGatlingが良いらしい
  • 要件や設計のテストって、レビューとは違う?
    • シーケンス図や業務フロー図を書いてみることがテストの一つに該当する
    • CEGTest使うと漏れが見える
      • ただ手法が難しいらしい

2章

スライドはどこかに上がっているのでしょうか?

  • ソフトウェア設計自体が、テスティングの自動化自体の成功を左右する
    • 最初からテストを意識して設計すると良いよね
      • 前述のブラウザテストで例えると、idやclassを最初から振っておくとか
  • テスターとテストオートメーターが分かれている経験ある人?
    • テスターは派遣とか外注、オートメーターは自社というパターンがあるみたい
  • テスターとテストオートメーターの分業について
    • 賛成/反対に分かれて参加者で意見出し
  • 2章の話は原著当時の背景が強く影響している?
    • MSのWindowsテスト?(うろ覚え)
  • テストスクリプトが複雑になる = メンテコストが高くなる
    • あるある
  • アドホックテストの自動化は無意味。自動化の前にテスト手法/設計を見直すべき
  • テスト自動化をプロジェクトで導入するには
    • 実際に見せる。画面テストを100ケースとか
    • QAの世界では4つのコスト(予防、評価、外部失敗、内部失敗)という考えがある
    • 気合い

感想

  • 興味が湧いたツール
  • 興味が湧いた考え方
    • モデルベーステスト
    • コストモデル
  • カバレッジは補助として使う
    • 品質保証としては使っていない(一例)
    • 自分たちのテストがどこを通っているのか = 次はどこをテストをすべきかの参考にする
  • 行って良かった

Gitで'fatal: object {hash} is corrupted'になった際の復旧手順

git

Macがフリーズする現象がたまにあって、そうなるとgitの状態が壊れることがある。
その時の修復手順を記録として残しておく。

現象

git操作を行おうとするとfatal: object <hash> is corrupted が出る。

/home/kanno/repository% git status
fatal: object 43a1c7ca8e29251954a806714bd1db24ddcf1905 is corrupted

復旧手順

念のためバックアップを取っておく

/home/kanno/repository% cp -rp .git git-old

表示されたhashのオブジェクトファイルを消す

/home/kanno/repository% rm .git/objects/04/313fa358eabb459b0c9ea1f48709f1cbb88118

git操作でfatal: bad object HEADが出るまでオブジェクトファイルを消すのを繰り返す

/home/kanno/repository% git status
fatal: bad object HEAD

該当ブランチのrefs/headsの中身を見る
(.git/logs/refs/heads/20432-hoge-branchのところは見たいブランチを指定)

/home/kanno/repository% tail -n 2 .git/logs/refs/heads/20432-hoge-branch
dcba72adc7078cfcced387a69246f0b29ea589b6 74e8aa0c09550804b40024ab33a98321627e1b4a kannokanno <...> 1429095527 +0900   commit: [#20432] WIP
74e8aa0c09550804b40024ab33a98321627e1b4a 43a1c7ca8e29251954a806714bd1db24ddcf1905 kannokanno <...> 1429096095 +0900   commit: [#20432] WIP

2行目の左のhash値を使ってHEADを戻す

/home/kanno/repository% git update-ref HEAD 74e8aa0c09550804b40024ab33a98321627e1b4a

git操作が出来るようになっているのでcommitしなおしておく

参考: how to fix GIT error: object file is empty?

MySQLでSQLの実行時間のみを調べる

MySQL

SQL設計やチューニングで実行時間を計測する際に以下のような状況がよく出てくる。

  • SQLの実行時間が知りたい
  • 実行結果はいらない

方法1 mysql -vvvを使う

/home/kanno% cat sample.sql | mysql -vvv hoge_db | tail -n 3
1 row in set (3.62 sec)

Bye
  • 対象のSQLを書いたsample.sql(ファイル名は何でも)を用意
    • 単純なSQLならecho "select ..." | mysql ...で十分
  • mysqlコマンドの標準入力に渡す
    • -vvvオプションで実行時間を出すようにする
  • tailで実行時間以降の行だけ表示させる
    • Byeとかも邪魔ならheadで更に絞る
    • cat sample.sql | mysql -vvv hoge_db | tail -n 3 | head -n 1

方法2 timeコマンドを使う

/home/kanno% time (cat sample.sql | mysql hoge_db > /dev/null)
real    0m12.526s
user    0m0.079s
sys     0m0.009s

プログラミングにおける設計の難しさについて考える

設計

前提

この記事における設計は主に以下の4点をイメージして書いています。
(具体的にどうこう、という話は出てきません)

  • REST設計
  • レイヤー設計
    • MVCとかDDDにおけるレイヤーみたいなやつ
  • クラス/インターフェース設計
    • どういう処理/データを持たせるのが適切かとか
  • コード設計
    • for文で書くかeach使うかとかそういう細かい話

目的

  • 設計に悩んだり微妙な設計をすることがあって改善したい
  • 設計に関する本を読んでいる中で、私にとってなぜ設計が難しいのか見えてきたので勢いで書き出す
  • あくまで現時点での私が思う難しさなので、1年後は別の原因で難しさを感じてるかもしれない

設計の何が難しいか

以下の要素により明確な正解がないからではないかと感じています。

  • 選択肢がいくつもある
  • 選択肢が浮かばない
  • 判断基準がいくつもある
  • 捨てる決断が必要なことがある
  • 技術的負債を恐れる

難しい要因1: 選択肢がいくつもある

プログラミング覚え立ての頃は数少ない方法でコードを書きます。

  • (Javaから入ったので)繰り返しといえばfor文を回すだけ
    • whileは無限ループ怖いので理由がない限り書かない
  • 再代入バリバリ
  • メソッド/クラスを分けない
  • クラスの責務を分けない
  • 変数名/メソッド名/クラス名が適当

他人が見れば汚いコードですが、少なくとも書いている本人は設計で迷うことは少なかったはずです。
設計していなかったので。
迷うのはアルゴリズムというか手続き的なところで、単純に「どう書けば仕様を満たすのか」という点でした。

それが経験や学習を経て、色々な方法を学んでいきます。

  • map/filter/reduceなどを覚える
  • 変数は不変を保つ。再代入とか辞めてほしい
    • ifが文ではなく式である言語に喜びを覚える
  • 「このクラス/メソッドの責務って何だ」を考え始める
    • 名前を考えるのに時間を費やす

携わる仕事は大概ありがちなCRUDなので難しいコードを書く事は少ないです。
ただ昔と違い色々な手法を知ってしまったため設計に時間がかかるようになっています。
ちなみにコード寄りの例を出しましたが、コードに限らず設計全般です。

たぶん中途半端に色々知っている状態のため判断に迷っているのだと思います。

難しい要因2: 選択肢が浮かばない

ざくっとした言い方ですが。

  • 経験として何か良くないのは分かる
    • いわゆるコードの臭いとか
    • コードじゃなくても、何となくこの設計イケてないよなあ感
  • けどどうしたら良いかが分からない

これは単純に経験に知識が追いついていないのでしょうね。

難しい要因3: 判断基準がいくつもある

※以下に出している例は例であって、今の現場がそうだということではありません

  • 現メンバーのスキル
    • OOPを知らない/好まないチームでOOPで書くべきか
      • 教える/議論するコストもあるし
  • 今後保守するかもしれない人のスキル
    • xx言語が向いているけど、書ける人が少ないのにxx言語で社内ツール作るべきか
  • 既存コード(アーキテクチャ)との調和
    • xxの方が良い設計なんだけど、そうすると既存の他の部分と統一性がなくなるとか
    • 統一性を重視してそっちに合わせるか、ゼロベースでの最善を取って良い設計にするか
  • 予算
    • カスタマイズしやすいようにオンプレがいいけど予算がとか
  • 人的リソース
    • 単純に人が足りない
  • 時間リソース
    • 単純に時間が足りない
  • タスクの優先度(重要度)
    • 急ぎでやるべきなものは「とりあえず」でやりがち
      • 「あとでやる」はまずやらない
      • やらなくて困らないならそもそも不要だったのではという考えもある
  • 難易度
    • 簡単なものほど飛びつきやすい

難しい要因4: 捨てる決断が必要

上記判断基準と併せて。
多くの場合において捨てる決断が求められます。
上記と重複する部分がありますが、捨てる理由としては主に以下の3つが浮かんでいます。

  • 人が足りない
    • 増やせばいいってものではないですが
  • 時間が足りない
    • さっさとリリースしたいねんという圧力
    • 緊急時の対応
  • 知識/経験が足りない
    • xxがいい気がするけどやったことないから怖いね
      • もしくは時間がかかるね
    • xxという簡単な解決策(手法、ソフトウェア、サービスなど)があるのに知らない

難しい要因5: 技術的負債を恐れる

苦悩の末に決断をしてそれがその時の最適解だったとしても、
時が経ったり新しく入ってきた人からするとそれは技術的負債になり得ます。
自分が関わった部分を指して「これはひどい」とか言われたくなくて、
見えない未来に思いを巡らせてあれこれ悩むのかもしれません。

プロとしてのありかた

こういった難しい要素に対して、私のプロ像はどう振る舞うだろうかというのを考えてみます。

色々なケースで最適解を出す

正解はない(と思う)けど、最適解は必ずある(と思う)。
その場その場で、色々なコストを考慮して最適解を出せる人がプロ。
幅広い知識と多くの経験と理路整然とした思考が必要。

責任を持つ

理想を語るのは簡単です。
理想を振りかざして既存のコードをけなすのは簡単ですし、
自分が高尚に感じるし、責任から逃れられているような感覚になります。
(参画した時点で自分もコードの責任者だと思う)

ですがきっとプロはグチグチ言わない。その方がモテるから。
プロはアウトプットで語る。
変えられるなら変えていくだろうし、
それが出来ないなら「これが今出来る最高の状態」と決断に誇りを持つ。

設計の難しさにどう立ち向かうか

  • チームとしての立ち向かい方
  • 個人としての立ち向かい方

チームとしての立ち向かい方

  • レビューを挟む
    • 自分が見えていない観点で指摘してくれるかもしれない
    • 人に説明することで抜け漏れに気付きやすいかも
  • 議論は前提の認識を明確にしておく
    • お互いが見ているもの、目指しているものが違うと議論もすれ違う
    • 「こっちの方が開発が早い」と「こっちの方が保守性が高い」みたいなことを言い合っても平行線
    • 「急ぎでやる必要あるの?」「一度しか使わない機能で保守性とか必要?」みたいなところから認識合わせるとか

難しい要因のほとんどはチーム内レビューとか相談で解決する気がします。
そのためにチームでもありますし。

ですが、出来ることなら自分一人でも最適解を出せるようにはなりたい。
「最適解の判断に迷う」という相談ではなくて、
「こういう理由でこれが最適解だと判断したのだけどどう思う?」という相談にしたい。

個人としての立ち向かい方

  • 知識を増やす
    • 悩まないという点では知識は少ない方がいいかもしれない
    • でも最適解を出すには知識は必要
  • 経験を増やす
    • 「知っている」と「やったことがある」では全然違う
  • 常に考える
    • 本やネットの知識を鵜呑みにして受け売り野郎にならない
    • 手法やサービスなどについて何がいいのか、何故いいのかを自分の言葉で説明できるようにする

感想

何が難しいと感じているかは分かった気がして書き出してみたけど、
個人については結局勉強しろという当たり前かつ抽象的な結論しか出ていなかった。