「Nextbeat Tech Bar:第一回ソフトウェアテストについて考える会」レポ
@t_wada
自動テスト実行結果の目的を整理する by
ひとこと要約
自動テストの信頼性とは
自動テストの成功も失敗も信じられること
成功していれば正しい、失敗していれば誤っていると確信できる
しかし自動テストは嘘をつくことが稀によくある
今日は偽陽性と偽陰性の話ではないので詳細は割愛
信頼性が高いなら何をするかが今日の話題
意思決定と行動を促す「情報」としてのテスト結果
テストの実行結果は「情報」である
情報→意思決定と行動を促すもの
テストの実行結果が促す行動:デプロイ、マージ、コードの修正
信頼性が低いテストは判断を鈍らせる
自動テストの出力にはいくつかの役割がある
- 信号機
全件成功した→次の行動に移れる
人間には緑と赤、機械には0と1で表示
- 欠陥の絞り込み
Execution Error: テスト実行中にプロダクトコードから発生する実行時エラー
Assertion Failure: テストコードの中に書いたアサーションの失敗
問題箇所の特定のために区別するとよい
- ドキュメント
動作する詳細設計書、仕様書
- データ
データとして蓄積して将来の意思決定や行動を促すこともできる
テストの不安定さなどの解析に使える
情報量のコントロール
テスト名と構造は基本
問題の絞り込みやすさのためにテストサイズやテストスコープを小さくしたり適切なマッチャを使う
Assertion failureの情報を使うにはきちんと適したマッチャを使わないといけない
テストサイズの概念 cf Googleのソフトウェアエンジニアリング
範囲による分類(単体、結合、E2E)は人によって定義がバラバラになりやすい
テストサイズのSMLによる分類
S テストの実行が1つのプロセスに閉じている
M テストの実行が1つのマシンに閉じている CIに乗せやすい
L 1つのマシンに閉じていない
偽陽性のよくある原因がネットワークアクセス
小さくなるほど安定して決定的な動きをする
テストサイズとテスト範囲でマトリクスができ、マスごとに位置付けが異なる
左下ほどコスパが良い
UnitなんだけどDBにアクセスせざるを得ないこともある
本邦初公開の表
上から順に想定するシーン
手元でさっと回して開発継続を判断するTDDのワンシーン
開発がどのくらい進んでるか、テスト項目の抜け漏れといったレビューのため
PRの分のテストが成功したらメインラインにマージできる
全範囲のテストが成功したら本番環境にデプロイできる
何件のテストがどれくらいの速度で回っていてカバレッジはどれくらいというのを定時で回しておいてレポートにする
@tomohisa
「コンパイル時のユニットテスト」を導入するとユニットテストを書かなくてもいいというのは本当なのか?(リモート発表) by
ひとこと要約
コンパイル時のユニットテストとは、オブジェクトの状態遷移を別の型で表現することにより入力に関する場合分けのテストを減らすこと
どこからきた、どんな概念なのか
Scott Wlaschin "Domain Modeling Made Functional"
各機能は特定のオブジェクトの状態でないと実行できないことにする
メールアドレスを表現する型をVerifiedEmailifiedEmail | UnverifiedEmailifiedEmail
フラグをチェックするのではなく型を分けることでユニットテストが不要になる
これをコンパイル時のユニットテストという
どのような書き方なのか
データの作成
検証済みでも未検証でも使えるオブジェクトを作るのではなく
検証成功した時はVerifiedEmail失敗した時はUnverifiedEmail
検証成功していなければVerifiedEmailという型が生まれない
パスワードリセットメール送信
ResetEmailの入力でVerifiedEmailのみ受け付けるようにすることでフラグチェックが不要になる
テストがどう変わるのか
一般的にはフラグごとにテストケースを書く
コンパイル時のユニットテストではResetEmailの中にUnverifiedEmailを入れようとするとコンパイルエラーになる→入力に関するテストを書く必要がない!
フラグや状態が増えたときにシンプルな書き方が効いてくる
全体としてどう振る舞うかのテストはまだ必要
フラグを持たないことによる型の自己文書化と型が増えることによる複雑化のトレードオフがある
原著者はフラグのチェックやテストの個数を減らすことのメリットを強調していたがこんな声も
Union型があるとパターンマッチングで網羅性、完全性をコンパイルでチェックできるので便利
関数型にすることで色々なところの影響が減って1つ1つの処理に集中できるというところもある
@nihonbuson
BDD(Cucumber)コミュニティが無料提供しているコンテンツの紹介と現在起きている危機 by
"The BDD Book: Discovery"に沿った話
ひとこと要約
CucumberコミュニティはBDDについてたくさんの有益な情報を発信してくれているが、現在ピンチ
cucumberとは
BDDをサポートするツール
プレーンテキストで書かれた仕様を読み取り、実行できる形にする
自然言語で書いているので開発に詳しくない人とも認識を合わせられる
BDDが人々にテストだと誤解されている
コミュニティがBDDについて色々発信している
BDDとは
ユーザーストーリーからコードの自動テストまでの隔たりを埋めるもの
最初はDiscoveryから始める
テスト自動化の改善は下流の成果
発見、定式化、自動化という順番がある
ビジネスチームと協調しない開発アプローチはBDDに従っていない!
cucumber schoolが提供する資料
- 発見
ユーザーストーリー1つに対して様々な側面を見つける
こういう場合はどうなる?こういう処理も必要だよねなど
https://www.youtube.com/watch?v=PR7WIS8JYyY
動画ではスムーズに発見が進んだけど、実際にはなかなか人を集めても意見が出てこないという声も
具体例がうまく思い浮かばない→ユーザーストーリーから営業のチラシやヘルプドキュメントを書こうとしてみる
- 定式化
BRIEFの原則Gherkin記法で書かれたテストシナリオを整理するための原則
テストシナリオが長くなると何を知りたかったのかわからなくなる
@yuuabsoft
画面の表示ロジックへの自動テストで悩んだ話(リモート発表) byコンテンツの表示ロジックが重要なプロダクト
表示ロジックの自動テストを導入したい
APIテストやユーザの操作を元にして実施するテストに比べて
コンテンツが多い
ページ内のロジックの分岐が多い
-
VRT
コンポーネントの部品ではなくページ全体に対して画像として比較することでロジックのテストができないか
導入保守コストが低い
細かい分岐やユーザの操作を伴うようなロジック
検証の粒度が荒くなる
takepepeさんのフロントエンドテスト本の8章9節みたいな話? -
リアーキ
表示ロジックがviewによっているのでmodelに寄せる
コストは小さくなる
model肥大化の懸念
表示ロジックのテストのためだけにリアーキはコスト重い
PJ立ち上げ時からやっておく必要があった -
自動テストしない
グロースハックABテストしている
表示ロジックが高頻度で変わっていく
自動テストを作成しても保守コストが増えるだけでメリットが薄いのでは
他のところで担保する必要がある
保守コスト考えるの大事
技術スタック、アーキテクチャ、ビジネス特性の理解がないとテスト戦略を適切に組めない
@verdy_266
理想のテスト像を業務のコードに適用できずに悩んでいる話 byテストの理想像ができた
全ての単体テストと落ちたらまずいページの統合テストを書く
factoriesはシンプルに
テーブルのレコードはテストのたびに生成する
WETに書く
業務のコードで理想のテストがしづらい
どのページは落ちたら困るのかの合意が取れていない
複雑なtraitが剥がせない
各画面の重要な仕様がどこなのか?
問題になっていないならテストは増やさなくてもいいのかも?
Rubyのバージョンアップの時に全部動作確認するのはつらい
@takapi327
Testcontainersが便利だった by開発中のOSSで使っているMySQLの認証で役立った
認証プラグインが色々使える
キャッシュの有無によるテストが必要
サーバーとクライアントの認証プラグインが違う場合を想定する必要がある
さらにMySQLの2つのバージョンに対応する
それぞれ綺麗な環境を用意したいがdocker-composeでは大変
TestContainersが便利
コンテナの情報を定義してそのコンテナを使った環境でテストできるようになる
設定がテストコードと一緒に管理できる
@boykush315
複雑なドメインを扱うプロダクトの探索フェーズではいつどのようにテストをするのか by
クリーンアーキテクチャ、モジュラモノリスを前提に
探索フェーズのプロジェクト
複雑なドメインの新規コンテキストに参入する場面でのこと
- ドメインモデル仮実装
書いては捨ててだったのでテストは書かない - ユースケース駆動実装
ユースケースが依存するコンポーネント群をIFのみ
テストは書かない - ドメインロジックを書く
がっつり単体テスト - 外部通信層
統合テスト
探索の中でIFの変動が少ない部分なのでここでレッドグリーンの変動を支える
探索中盤で手戻りが発生した場合テストを捨てるのか
ignoreでスキップすることで将来的な再利用のためにおいておける
そもそも探索の手戻りを減らすには
実例マッピングなどをやる
Discussion