ポジティブなテスト体験のための8つの自動テストのベストプラクティス
公開: 2022-03-11多くの開発者がテストを時間とエネルギーを浪費する必要な悪と見なしているのも不思議ではありません。テストは退屈で非生産的で、完全に複雑すぎる可能性があります。
私の最初のテスト経験はひどいものでした。 私は、厳密なコードカバレッジ要件を持つチームで作業しました。 ワークフローは次のとおりです。機能を実装し、デバッグし、テストを記述して、完全なコードカバレッジを確認します。 チームには統合テストはなく、手動で初期化されたモックを大量に使用する単体テストのみがあり、ほとんどの単体テストでは、ライブラリを使用して自動マッピングを実行しながら、簡単な手動マッピングをテストしました。 すべてのテストで利用可能なすべてのプロパティをアサートしようとしたため、すべての変更で数十のテストが失敗しました。
テストは時間のかかる負担として認識されていたため、私はテストでの作業が嫌いでした。 しかし、私はあきらめませんでした。 信頼性テストが提供し、小さな変更が行われるたびにチェックが自動化されることに興味をそそられました。 私は読んで練習し始めました、そして、テストが正しく行われるとき、役に立つと楽しい両方であるかもしれないことを学びました。
この記事では、最初から知っていればよかった8つの自動テストのベストプラクティスを紹介します。
自動テスト戦略が必要な理由
自動テストは多くの場合将来に焦点を当てていますが、正しく実装するとすぐにメリットがあります。 仕事をより良くするのに役立つツールを使用すると、時間を節約し、仕事をより楽しくすることができます。
会社のERPから発注書を取得し、それらの発注書をベンダーに発注するシステムを開発していると想像してください。 以前に注文したアイテムの価格がERPにありますが、現在の価格は異なる場合があります。 低価格と高価格のどちらで注文するかを制御する必要があります。 ユーザー設定が保存されており、価格変動を処理するコードを記述しています。
コードが期待どおりに機能することをどのように確認しますか? あなたはおそらく:
- ERPの開発者インスタンスにダミーオーダーを作成します(事前に設定していることを前提としています)。
- アプリを実行します。
- その注文を選択し、注文を出すプロセスを開始します。
- ERPのデータベースからデータを収集します。
- ベンダーのAPIから現在の価格をリクエストします。
- 特定の条件を作成するには、コードの価格を上書きします。
ブレークポイントで停止し、1つのシナリオで何が起こるかを段階的に確認できますが、考えられるシナリオは多数あります。
| 環境設定 | ERP価格 | ベンダー価格 | 注文する必要がありますか? | |
|---|---|---|---|---|
| より高い価格を許可する | 低価格を許可する | |||
| false | false | 10 | 10 | true |
| (ここでは、さらに3つの優先順位の組み合わせがありますが、価格は同じであるため、結果は同じです。) | ||||
| true | false | 10 | 11 | true |
| true | false | 10 | 9 | false |
| false | true | 10 | 11 | false |
| false | true | 10 | 9 | true |
| true | true | 10 | 11 | true |
| true | true | 10 | 9 | true |
バグが発生した場合、会社は金銭を失うか、評判を傷つけるか、またはその両方を行う可能性があります。 複数のシナリオをチェックし、チェックループを数回繰り返す必要があります。 手動で行うのは面倒です。 しかし、テストは役に立ちます!
テストでは、不安定なAPIを呼び出さずにコンテキストを作成できます。 これらは、レガシーERPシステムではあまりにも一般的である古くて遅いインターフェースを繰り返しクリックする必要をなくします。 ユニットまたはサブシステムのコンテキストを定義するだけで、デバッグ、トラブルシューティング、またはシナリオの探索が即座に実行されます。テストを実行すると、コードに戻ります。 私の好みは、以前のテスト実行を繰り返すキーバインディングをIDEに設定し、変更を加えるとすぐに自動フィードバックを提供することです。
1.正しい態度を維持する
手動のデバッグやセルフテストと比較すると、自動テストは、テストコードがコミットされる前であっても、最初から生産性が高くなります。 コードが期待どおりに動作することを確認した後(手動でテストするか、より複雑なモジュールの場合は、テスト中にデバッガーを使用してコードをステップ実行することにより)、アサーションを使用して、入力パラメーターの任意の組み合わせに期待するものを定義できます。
テストに合格すると、コミットする準備がほぼ整いますが、完全ではありません。 通常、最初に機能するバージョンはエレガントではないため、コードをリファクタリングする準備をしてください。 テストなしでそのリファクタリングを実行しますか? すべての手動手順を再度完了する必要があり、熱意が低下する可能性があるため、これは疑わしいことです。
将来はどうですか? リファクタリング、最適化、または機能の追加を実行している間、テストは、モジュールを変更した後もモジュールが期待どおりに動作することを確認するのに役立ちます。これにより、永続的な自信が植え付けられ、開発者は今後の作業に取り組む準備が整います。
テストを、コードレビューアやリードだけを喜ばせる負担や何かと考えるのは逆効果です。 テストは、開発者として私たちが恩恵を受けるツールです。 私たちはコードが機能するのが好きで、繰り返しのアクションやバグに対処するためのコードの修正に時間を費やすのは好きではありません。
最近、コードベースでリファクタリングに取り組み、IDEにディレクティブを使用して未usingのクリーンアップを依頼しました。 驚いたことに、テストでは、電子メールレポートシステムにいくつかの障害が見られました。 ただし、これは有効な失敗でした。クリーンアッププロセスにより、電子メールテンプレートのRazor(HTML + C#)コードの一部のusingディレクティブが削除され、その結果、テンプレートエンジンは有効なHTMLを構築できませんでした。 このような小さな操作でメールの報告が途切れるだろうとは思っていませんでした。 テストのおかげで、すべてが機能すると思っていたときに、リリース直前にアプリ全体でバグを見つけるのに何時間も費やす必要がなくなりました。
もちろん、あなたは道具の使い方を知っている必要があり、ことわざの指を切ってはいけません。 コンテキストを定義するのは面倒で、アプリを実行するよりも難しい場合があるように思われるかもしれません。テストは、古くて役に立たなくなるのを避けるために、あまりにも多くのメンテナンスを必要とします。 これらは有効なポイントであり、対処します。
2.適切なタイプのテストを選択します
開発者は、コードによって呼び出されているかどうかを確認するためだけに12の依存関係をモックしようとしているため、自動テストを嫌うようになることがよくあります。 または、開発者は高レベルのテストに遭遇し、すべてのアプリケーションの状態を再現して、小さなモジュールのすべてのバリエーションをチェックしようとします。 これらのパターンは非生産的で退屈ですが、意図したとおりにさまざまなテストタイプを活用することで回避できます。 (結局のところ、テストは実用的で楽しいものでなければなりません!)
読者は、単体テストとは何か、それらの記述方法を理解し、統合テストに精通している必要があります。そうでない場合は、ここで一時停止して速度を上げる価値があります。
数十のテストタイプがありますが、これらの5つの一般的なタイプは非常に効果的な組み合わせになります。
- 単体テストは、メソッドを直接呼び出すことにより、分離されたモジュールをテストするために使用されます。 依存関係はテストされていないため、モックされています。
- 統合テストは、サブシステムをテストするために使用されます。 モジュール自体のメソッドへの直接呼び出しを引き続き使用しますが、ここでは依存関係を考慮しているため、モックされた依存関係は使用せず、実際の(本番)依存モジュールのみを使用してください。 これらはインフラストラクチャのモックであるため、インメモリデータベースまたはモックWebサーバーを引き続き使用できます。
- 機能テストは、アプリケーション全体のテストであり、エンドツーエンド(E2E)テストとも呼ばれます。 直接呼び出しは使用しません。 代わりに、すべての対話はAPIまたはユーザーインターフェイスを介して行われます。これらはエンドユーザーの観点からのテストです。 ただし、インフラストラクチャはまだモックされています。
- カナリアテストは機能テストに似ていますが、本番インフラストラクチャと少数のアクションセットを使用します。 これらは、新しくデプロイされたアプリケーションが確実に機能するようにするために使用されます。
- 負荷テストはカナリアテストに似ていますが、実際のステージングインフラストラクチャと、何度も繰り返されるさらに小さな一連のアクションを使用します。
最初から5つのテストタイプすべてで作業する必要は必ずしもありません。 ほとんどの場合、最初の3つのテストで大いに役立つことができます。
各タイプのユースケースを簡単に調べて、ニーズに合ったユースケースを選択できるようにします。
ユニットテスト
価格と取り扱いの好みが異なる例を思い出してください。 モジュール内で何が起こっているかだけを気にし、その結果はビジネスに重要な影響を与えるため、単体テストの候補として適しています。
モジュールには入力パラメーターのさまざまな組み合わせがあり、有効な引数のすべての組み合わせに対して有効な戻り値を取得する必要があります。 単体テストは、関数またはメソッドの入力パラメーターに直接アクセスでき、すべての組み合わせをカバーするために数十のテストメソッドを作成する必要がないため、妥当性を保証するのに適しています。 多くの言語では、コードと期待される結果に必要な引数を受け入れるメソッドを定義することで、テストメソッドの重複を回避できます。 次に、テストツールを使用して、そのパラメーター化されたメソッドにさまざまな値のセットと期待値を提供できます。
統合テスト
統合テストは、モジュールがその依存関係、他のモジュール、またはインフラストラクチャとどのように相互作用するかに関心がある場合に適しています。 引き続き直接メソッド呼び出しを使用しますが、サブモジュールにアクセスできないため、すべてのサブモジュールのすべての入力メソッドについてすべてのシナリオをテストすることは実用的ではありません。
通常、モジュールごとに1つの成功シナリオと1つの失敗シナリオが必要です。
統合テストを使用して、依存性注入コンテナーが正常に構築されているかどうか、処理または計算パイプラインが期待される結果を返すかどうか、または複雑なデータがデータベースまたはサードパーティAPIから正しく読み取られて変換されたかどうかを確認するのが好きです。
機能テストまたはE2Eテスト
これらのテストは、アプリが少なくともランタイムエラーなしで起動できることを確認するため、アプリが機能することを最も確信できます。 クラスに直接アクセスせずにコードのテストを開始するのは少し手間がかかりますが、最初のいくつかのテストを理解して記述すれば、それほど難しくないことがわかります。
必要に応じて、コマンドライン引数を使用してプロセスを開始することでアプリケーションを実行し、APIエンドポイントを呼び出すか、ボタンを押すことで、見込み顧客と同じようにアプリケーションを使用します。 UIテストの場合でも、これは難しくありません。各主要プラットフォームには、UI内の視覚要素を見つけるためのツールがあります。
カナリアテスト
機能テストでは、アプリがテスト環境で動作するかどうかがわかりますが、本番環境ではどうでしょうか。 いくつかのサードパーティAPIを使用していて、それらの状態のダッシュボードが必要な場合、またはアプリケーションが着信リクエストをどのように処理するかを確認したい場合を考えてみます。 これらはカナリアテストの一般的な使用例です。
これらは、サードパーティのシステムに副作用を引き起こすことなく、動作中のシステムに短時間作用することによって動作します。 たとえば、注文せずに新しいユーザーを登録したり、製品の在庫状況を確認したりできます。
カナリアテストの目的は、すべての主要コンポーネントが実稼働環境で連携して動作していることを確認することであり、たとえば、資格情報の問題が原因で失敗することはありません。
負荷テスト
負荷テストは、多数の人がアプリケーションを使い始めたときに、アプリケーションが引き続き機能するかどうかを明らかにします。 これらはカナリアおよび機能テストに似ていますが、ローカル環境または実稼働環境では実行されません。 通常、本番環境と同様の特別なステージング環境が使用されます。
これらのテストは実際のサードパーティサービスを使用していないことに注意することが重要です。これは、本番サービスの外部負荷テストに不満があり、結果として追加料金が発生する可能性があります。
3.テストタイプを分離しておく
自動テスト計画を立てるときは、独立して実行できるように、各タイプのテストを分離する必要があります。 これには追加の編成が必要ですが、テストを混合すると問題が発生する可能性があるため、価値があります。
これらのテストは異なります。
- 意図と基本的な概念(したがって、それらを分離することは、「将来のあなた」を含む、コードを見る次の人にとって良い前例となります)。
- 実行時間(したがって、最初に単体テストを実行すると、テストが失敗したときにテストサイクルを短縮できます)。
- 依存関係(したがって、テストタイプ内で必要なものだけをロードする方が効率的です)。
- 必要なインフラストラクチャ。
- プログラミング言語(特定の場合)。
- 継続的インテグレーション(CI)パイプライン内またはパイプライン外の位置。
ほとんどの言語と技術スタックでは、たとえば、すべての単体テストを、機能モジュールにちなんで名付けられたサブフォルダーと一緒にグループ化できることに注意することが重要です。 これは便利で、新しい機能モジュールを作成する際の摩擦を減らし、自動ビルドが容易になり、混乱が少なくなり、テストを簡素化するもう1つの方法です。
4.テストを自動的に実行します
いくつかのテストを作成したが、数週間後にレポをプルした後、それらのテストが合格しなくなったことに気付く状況を想像してみてください。
これは、テストがコードであり、他のコードと同様に、テストを維持する必要があることを思い出させるものです。 このための最適なタイミングは、作業が終了し、すべてが意図したとおりに動作するかどうかを確認したい瞬間の直前です。 必要なすべてのコンテキストがあり、別のサブシステムで作業している同僚よりも簡単にコードを修正したり、失敗したテストを変更したりできます。 ただし、この瞬間は頭の中にしか存在しないため、テストを実行する最も一般的な方法は、開発ブランチにプッシュした後、またはプルリクエストを作成した後に自動的に行われます。

このようにして、メインブランチは常に有効な状態になります。または、少なくとも、その状態を明確に示すことができます。 自動化された構築およびテストパイプライン(またはCIパイプライン)は、次のことを支援します。
- コードがビルド可能であることを確認します。
- 「自分のマシンで動作する」という潜在的な問題を排除します。
- 開発環境を準備する方法について実行可能な指示を提供します。
このパイプラインの構成には時間がかかりますが、パイプラインは、あなたが唯一の開発者であっても、ユーザーやクライアントに到達する前にさまざまな問題を明らかにする可能性があります。
CIを実行すると、スコープが拡大する前に新しい問題も明らかになります。 そのため、最初のテストを作成した直後に設定することを好みます。 GitHubのプライベートリポジトリでコードをホストし、GitHubアクションを設定できます。 リポジトリが公開されている場合は、GitHubアクションよりもさらに多くのオプションがあります。 たとえば、私の自動テストプランは、データベースと3種類のテストを備えたプロジェクトに対してAppVeyorで実行されます。
私は、本番プロジェクトのパイプラインを次のように構成することを好みます。
- コンパイルまたはトランスパイル
- 単体テスト:高速で、依存関係を必要としません
- データベースまたはその他のサービスのセットアップと初期化
- 統合テスト:コードの外部に依存関係がありますが、機能テストよりも高速です
- 機能テスト:他の手順が正常に完了したら、アプリ全体を実行します
カナリアテストや負荷テストはありません。 それらの詳細と要件のため、手動で開始する必要があります。
5.必要なテストのみを書く
すべてのコードの単体テストを作成することは一般的な戦略ですが、これは時間とエネルギーを浪費し、自信を与えない場合があります。 「ピラミッドのテスト」の概念に精通している場合は、すべてのコードを単体テストでカバーする必要があり、サブセットのみを他の高レベルのテストでカバーする必要があると考えるかもしれません。
いくつかのモックされた依存関係が希望の順序で呼び出されることを確認する単体テストを作成する必要はないと思います。 これを行うには、いくつかのモックを設定し、すべての呼び出しを検証する必要がありますが、それでもモジュールが機能しているという確信は得られません。 通常、私は実際の依存関係を使用し、結果のみをチェックする統合テストのみを作成します。 これにより、テストされたモジュールのパイプラインが正しく機能しているという確信が得られます。
一般的に、私は機能を実装して後でサポートしながら、自分の生活を楽にするテストを作成します。
ほとんどのアプリケーションでは、100%のコードカバレッジを目指すと、多くの面倒な作業が追加され、一般的なテストやプログラミングで作業する喜びがなくなります。 マーティンファウラーのテストカバレッジがそれを置くように:
テストカバレッジは、コードベースのテストされていない部分を見つけるための便利なツールです。 テストカバレッジは、テストがどれだけ優れているかを示す数値ステートメントとしてはほとんど役に立ちません。
したがって、いくつかのテストを作成した後、カバレッジアナライザーをインストールして実行することをお勧めします。 コードの行が強調表示されたレポートは、実行パスをよりよく理解し、カバーする必要のあるカバーされていない場所を見つけるのに役立ちます。 また、ゲッター、セッター、ファサードを見ると、100%のカバレッジが面白くない理由がわかります。
6.レゴをプレイする
「プライベートメソッドをテストするにはどうすればよいですか?」などの質問が時々表示されます。 あなたはしません。 あなたがその質問をした場合、何かがすでに間違っています。 通常、これは、単一責任の原則に違反しており、モジュールが適切に処理を行わないことを意味します。
このモジュールをリファクタリングし、重要と思われるロジックを別のモジュールにプルします。 ファイルの数を増やしても問題はありません。これにより、レゴブロックとして構造化されたコードが作成されます。非常に読みやすく、保守しやすく、置き換え可能で、テスト可能です。
コードを適切に構造化することは、口で言うほど簡単ではありません。 ここに2つの提案があります:
関数型プログラミング
関数型プログラミングの原理とアイデアについて学ぶ価値があります。 C、C ++、C#、Java、アセンブリ、JavaScript、Pythonなどのほとんどの主流言語では、マシン用のプログラムを作成する必要があります。 関数型プログラミングは人間の脳により適しています。
これは最初は直感に反するように思えるかもしれませんが、次のことを考慮してください。すべてのコードを1つのメソッドに入れ、共有メモリチャンクを使用して一時値を格納し、かなりの量のジャンプ命令を使用すれば、コンピューターは問題ありません。 さらに、最適化段階のコンパイラーがこれを行うことがあります。 ただし、人間の脳はこのアプローチを簡単に処理できません。
関数型プログラミングでは、副作用のない純粋関数を、強い型を使って表現力豊かに書く必要があります。 そうすれば、関数が生成するのはその戻り値だけなので、関数について推論するのははるかに簡単です。 プログラミングスローダウンポッドキャストエピソードアダムゴードンベルによる関数型プログラミングは、基本的な理解を得るのに役立ち、フィリップワドラーによる神のプログラミング言語とバルトスミレフスキーによる圏論のコアカーシブエピソードを続けることができます。 最後の2つは、プログラミングに対する私の認識を大いに豊かにしました。
テスト駆動開発
TDDをマスターすることをお勧めします。 学ぶための最良の方法は練習することです。 文字列計算機カタは、コードカタを練習するのに最適な方法です。 カタを習得するには時間がかかりますが、最終的にはTDDのアイデアを完全に吸収できるようになります。これにより、作業が楽しく、テストも可能な、適切に構造化されたコードを作成できます。
注意点:TDDの純粋主義者が、TDDが唯一の正しいプログラミング方法であると主張しているのを目にすることがあります。 私の意見では、これはツールボックスのもう1つの便利なツールであり、それ以上のものではありません。
場合によっては、モジュールとプロセスを相互に関連させて調整する方法を確認する必要があり、使用するデータと署名がわからないことがあります。 このような場合は、コンパイルされるまでコードを記述してから、機能のトラブルシューティングとデバッグを行うためのテストを記述します。
また、必要な入力と出力はわかっていても、ロジックが複雑なため、実装を適切に作成する方法がわからない場合もあります。 このような場合、完璧な実装について考えるよりも、TDDの手順に従って、コードを段階的に構築する方が簡単です。
7.テストをシンプルかつ集中的に保つ
不必要な気を散らすことなく、きちんと整理されたコード環境で作業することは喜びです。 そのため、SOLID、KISS、およびDRYの原則をテストに適用し、必要に応じてリファクタリングを利用することが重要です。
「頻繁にテストされたコードベースで作業するのは嫌いです。変更するたびに数十のテストを修正する必要があるからです。」というコメントを時々耳にします。 これは、焦点が絞られておらず、テストしすぎているテストが原因で発生する、メンテナンスの多い問題です。 「1つのことをうまく行う」の原則は、テストにも当てはまります。「1つのことをうまくテストする」。 各テストは比較的短く、1つの概念のみをテストする必要があります。 「1つのことをうまくテストする」とは、テストごとに1つのアサーションに制限する必要があるという意味ではありません。重要で重要なデータマッピングをテストする場合は、数十を使用できます。
この焦点は、1つの特定のテストまたはテストのタイプに限定されません。 ERPシステムから構造へのデータのマッピングなど、単体テストを使用してテストした複雑なロジックを処理することを想像してみてください。統合テストでは、模擬ERPAPIにアクセスして結果を返します。 その場合、統合テストでマッピングを再度テストしないように、単体テストがすでにカバーしている内容を覚えておくことが重要です。 通常、結果に正しい識別フィールドがあることを確認するだけで十分です。
レゴブロックのように構造化されたコードと焦点を絞ったテストにより、ビジネスロジックの変更は苦痛ではありません。 変更が根本的な場合は、ファイルとそれに関連するテストを削除し、新しいテストで新しい実装を作成するだけです。 小さな変更の場合は、通常、新しい要件を満たし、ロジックに変更を加えるために1つから3つのテストを変更します。 テストを変更するのは問題ありません。 この慣行は複式簿記と考えることができます。
シンプルさを実現する他の方法は次のとおりです。
- テストファイルの構造化、テストコンテンツの構造化(通常はArrange-Act-Assert構造)、およびテストの命名に関する規則を考え出します。 次に、最も重要なのは、これらのルールに一貫して従うことです。
- 「リクエストの準備」などのメソッドに大きなコードブロックを抽出し、繰り返されるアクションのヘルパー関数を作成します。
- テストデータ構成にビルダーパターンを適用します。
- (統合テストで)メインアプリで使用するのと同じDIコンテナーを使用するため、依存関係を手動で作成しなくても、すべてのインスタンス化は
TestServices.Get()と同じくらい簡単になります。 そうすれば、すでに便利なヘルパーが用意されているので、新しいテストの読み取り、保守、および作成が簡単になります。
テストが複雑になりすぎていると感じた場合は、ただ立ち止まって考えてください。 モジュールまたはテストのいずれかをリファクタリングする必要があります。
8.ツールを使用して生活を楽にします
テスト中は、多くの面倒な作業に直面します。 たとえば、テスト環境またはデータオブジェクトの設定、依存関係のスタブとモックの構成などです。 幸いなことに、すべての成熟した技術スタックには、これらのタスクをはるかに面倒なものにするためのいくつかのツールが含まれています。
最初の100個のテストをまだ作成していない場合は作成してから、時間をかけて反復的なタスクを特定し、技術スタックのテスト関連のツールについて学習することをお勧めします。
インスピレーションを得るために、使用できるツールをいくつか紹介します。
- テストランナー。 簡潔な構文と使いやすさを探してください。 私の経験から、.NETの場合はxUnitをお勧めします(ただし、NUnitも確実な選択です)。 JavaScriptまたはTypeScriptの場合、私はJestを使用します。 ツールと課題は進化するため、タスクと考え方に最適なものを見つけてください。
- ライブラリをあざける。 インターフェイスなどのコード依存関係の低レベルのモックが存在する可能性がありますが、WebAPIまたはデータベースの高レベルのモックも存在します。 JavaScriptとTypeScriptの場合、Jestに含まれている低レベルのモックは問題ありません。 .NETの場合。 私はMoqを使用していますが、NSubstituteも素晴らしいです。 Web APIモックに関しては、WireMock.NETの使用を楽しんでいます。 APIの代わりに使用して、応答処理のトラブルシューティングとデバッグを行うことができます。 また、自動テストでも非常に信頼性が高く、高速です。 データベースは、対応するメモリ内を使用してモックすることができます。 .NETのEfCoreはそのようなオプションを提供します。
- データ生成ライブラリ。 これらのユーティリティは、データオブジェクトをランダムデータで埋めます。 これらは、たとえば、ビッグデータ転送オブジェクトのいくつかのフィールドのみを気にする場合に役立ちます(その場合、マッピングの正確さをテストするだけの場合もあります)。 これらをテストに使用したり、フォームに表示したりデータベースに入力したりするためのランダムデータとして使用することもできます。 テストの目的で、.NETでAutoFixtureを使用しています。
- UIオートメーションライブラリ。 これらは自動テストの自動ユーザーです。アプリの実行、フォームへの入力、ボタンのクリック、ラベルの読み取りなどを行うことができます。 アプリのすべての要素をナビゲートするために、座標や画像認識によるクリックを処理する必要はありません。 主要なプラットフォームには、タイプ、識別子、またはデータごとに必要な要素を見つけるためのツールがあるため、再設計のたびにテストを変更する必要はありません。 それらは堅牢であるため、CIとCIで機能させると(場合によっては、自分のマシンでのみ機能することがわかります)、機能し続けます。 私はFlaUIfor.NETとCypressforJavaScriptとTypeScriptの使用を楽しんでいます。
- アサーションライブラリ。 ほとんどのテストランナーにはアサーションツールが含まれていますが、Fluent Assertions for .NETのように、独立したツールを使用すると、よりクリーンで読みやすい構文を使用して複雑なアサーションを作成できる場合があります。 私は特に、アイテムの順序やメモリ内のアドレスに関係なく、コレクションが等しいことを表明する関数が好きです。
流れがあなたと共にありますように
幸福は、「フロー:最適な体験の心理学」という本で詳細に説明されている、いわゆる「フロー」体験と密接に関連しています。 そのフロー体験を達成するには、明確な目標を設定した活動に従事し、進捗状況を確認できる必要があります。 タスクは即座にフィードバックをもたらすはずであり、自動テストが理想的です。 また、課題とスキルのバランスをとる必要があります。これはすべての個人の責任です。 テストは、特にTDDでアプローチする場合、あなたを導き、自信を植え付けるのに役立ちます。 これらは、特定の目標を設定するのに役立ちます。合格した各テストは、進捗状況の指標になります。
テストへの正しいアプローチはあなたをより幸せでより生産的にすることができ、テストは燃え尽き症候群の可能性を減らします。 重要なのは、テストを、コードの将来を保証するための面倒なステップとしてではなく、日常の開発ルーチンで役立つツール(またはツールセット)と見なすことです。
テストはプログラミングの必要な部分であり、ソフトウェアエンジニアが作業方法を改善し、最良の結果を提供し、時間を最適に使用できるようにします。 おそらくさらに重要なことは、テストは開発者が仕事をより楽しむのに役立ち、それによって彼らの士気とモチベーションを高めることができるということです。
