
シェア:
ヨナタンは、C/C++からMatlab、PHP、javascriptまで、アカデミーや業界で素晴らしいプロジェクトに携わってきた。元Webiks社CTO、WalkMe社ソフトウェアアーキテクト。現在はVonageのソフトウェア・アーキテクトであり、eggheadのインストラクターでもある。
ソフトウェアテストはコミュニケーションにどう貢献できるか
所要時間:1 分
ソフトウェアテストはコミュニケーションを改善し、時間(とフラストレーション)を節約することができる。悪いテストは、その逆を行う可能性がある。この記事では、悪いテストがどのように有害で、良いテストがどのように正しい情報を伝えるかについて、実際の例から探ります。
タイトルにまつわる物語
で ヴィヴィッドでは ボタン.ボタンにタイトルがなかったわけではありません。Vivid はウェブ・コンポーネント・ベースのライブラリで、私たちの button 要素の中には、Shadow DOM の下に隠れたネイティブ・ボタンがあります。
このネイティブボタンは、親のタイトルを取得していない。 a11y規格に基づく)。
つまり...タスクはとてもシンプルだった。ホスト(カスタム要素)からタイトルを取得し、内部ボタンに反映させる。ただそれだけ:

この例を使い、そのコミットパスをたどることで、単純なテストのミスを避ける方法を理解し、学んでいく。
教訓1:インターフェイスの変更は赤信号
このPull Requestの最初のコミットはインターフェイスに干渉した。これがテストでの変更点だ:

これによりテストは失敗した。テストが toBeFalsyから「空文字列に等しい」に変わっているのがわかる。これのどこが悪いのか?
このケースには3つの誤りがある:
toBeFalsyにはいろいろなものがある(空文字列、null,undefined,NaN0、そしてfalse)であるが、空文字列とは異なり、オープンエンドではない。というのも、インターフェイスが十分に文書化されていなかったからだ。
toBeFalsyが広すぎるからだ。テストではなぜかインターフェイスが''に変わっていた。その理由は何ですか?壊れるような変更なのだろうか?
ここで筋書きが濃くなる。この2つのミスは、24時間の展開の損失に対する前菜にすぎない。メインディッシュを食べよう。
悪いテストが悪いコードを生む
不合格になったテストの整理を手伝おうとしていたとき、私は休暇から戻る途中だった。
携帯電話を使ってテストコードを見てみると、文書化されたインターフェースでは、タイトルの値は空文字列になることになっていた。
「もちろん失敗する!初期値は空文字列ではありません。空文字列にすればうまくいくよ。"
変更はとても簡単だった。コンストラクタで値を設定するだけで、テストはパスする:

この修正によって、最初の失敗で見られた問題が悪化した。ドキュメントを変えただけでなく、実際のインターフェースも変えてしまったのだ。確かにテストはパスしたが、それは正しいテストだったのだろうか?そして、こんな単純なことで24時間もの作業時間を費やしてしまったのだろうか?2つ目のミスに取り掛かろう。
間違いその2:(正しい理由で)合格してはならない
インターフェイスの変更は最初のステップに過ぎない。実際に実装すべきロジックがあったよね?これが次の実装のテストだ:

最初に出てくるのはテストの説明文だ。誤字(notの後にsetがない)が最も目立つエラーだが、他にもある。
記述は否定形で書かれている。科学では、何かが存在しないことを証明することはできない。ソフトウェアはコンピュータ・サイエンスに属するので、同じように見ることができる。ソフトが何をすべきでないかではなく、何をすべきか教えてほしい。
説明よりもさらに悪いことが2つ、テストコード自体にある。それらを見つけられるかどうか、少し時間を取ってみてほしい。
...
...
分経過しました。あと1つか2つ、エラーを見つけましたか?
間違った理由その1:間違ったものをテストする
冒頭で、我々のミッションは内部ボタンにタイトルを設定することだと述べた。このテストでは、そのシナリオを説明していない。
このテストは、内部ボタンではなく、要素に対して行われていることがわかりますか?このテストを読んだとき、作者はタイトルが要素に表示されることを望んでいるのだと思いました。それがドキュメントです。そして、それはコンポーネントがすることを私が期待していることです。
間違った理由その2:期待と説明が一致しない
もうひとつは、このテストで期待されているのは、タイトルの文字列が空であることだ。私たちが達成したいことはまったく違うことで、このような場合にはtitle属性を削除したいのです。
12時間が過ぎ、私は休暇から家に戻り、与えられた仕様に準拠するためにコードをどのように実装するかを考えていた。
いくつかのSlackのメッセージで、私の疑念は確信に変わった-タイトルが虚偽である場合、title属性は削除されるべきである。私は、タイトルが要素に設定されるべきではないと、少しも疑わなかった。
私たちが正しい道を歩んでいることを確認するために、テストを少し変更した:
t
今、期待されているのは、実際にその属性を取り除くことだ。
これをパスするためには、コンポーネントのテンプレートとクラスを少し変更する必要があった。Classでは、title属性をオーバーライドする必要がありました。 Classは別の基本要素 Class).また、テンプレートでは値が不正な場合はnullに設定し、ビュー自体から変更された場合は文字列のままにするコンバータを設定する必要がありました:

すべてが期待通りに動いた。広報担当者から、私がいかに彼女の窮地を救ったかについて賞賛されることを期待していた。それとも...違う?
コミュニケーションが鍵
数時間後、期待通りのSlackメッセージが届いた。しかし、メッセージ自体はあまり期待されていなかった:

待ってくれ!
こうしてまたSlackでのやり取りが始まった。短いものだったが、結局、これが私の考えだった:

内部ボタンに問題があったことが明らかになったときはショックだった。
予想通り、修正は最小限だった。エレメントと内部ボタン(私たちはこのようなエレメントを「コントロール・エレメント」と呼んでいる)の両方でテストをしなければならなかった:

テストができたので、初期値がより具体的で、HTMLの仕様(null)に従っていることも確認できた:

この単純な修正に24時間かかった(そう、その半分の時間は休暇中だったことは知っているが、言い訳は弱い者のすることだ😉)。もっといいテストができたか、あるいは私のコミュニケーション能力が高ければ助かったかもしれない。
結論
良いテストを書く
テストは、コードが想定したとおりに動かなかったときに失敗するものだ。テストはまた、あなたのコードがどのように動作するかを端的に説明するものでもあります。もしテストが要素にタイトルを付けるべきだと言うのであれば、それは実装者への指示です。
インターフェイスはテストによっても守られる。もしテストがインターフェイスを正しく、あるいは十分に厳重にガードしていなければ(例えば toBeFalsyの代わりに toBeNullの例のように)、インターフェイスの開発者や消費者として何を期待すればいいのかがよくわからなくなってしまいます。インターフェイステストの重要性については、私の投稿を参照してほしい、 実装と詳細の物語.
伝えるためにテストを書く
優れたコミュニケーション能力は重要だ。誰もがそれを持っているわけではない。特にリモートワークの環境では。もし私たちが直接一緒にコーディングしていたら、こんなに時間はかからなかったかもしれない。私たちのチームはリモートで仕事をしていて(国際的なチーム)、コミュニケーションはたいてい "非同期 "だ。
テストを正しく記述し、明確な説明と、物事がどうあるべきかを説明するロジックを持つことは、チーム内のこのようなコミュニケーションエラーを軽減するのに役立つ。
私たちの VonageコミュニティSlackまたは X(旧Twitter.