114 


私は開発者がLiskノードとやりとりし、コマンドラインで他のLisk関連の機能を実行するために構築しているコマンドラインインターフェイスであるLiskyのプロジェクトリーダーです。私たちは最近、(からLiskyでユニットテストにBDDスタイルのアプローチを採用しましたv0.3.0以降)、そしてこのブログ記事は、それがどのように機能するかに興味がある人のためにある、特にLiskyコードベースに貢献に興味がある人-  プルリクエストは歓迎

私たちがこの記事でカバーする内容:

  1. BDDとは何ですか?
  2. このアプローチを使用して独自のテストを作成するチュートリアルスタイルのステップバイステップガイドです。
  3. メリットは何ですか?メリットとは何ですか?

BDDとは何ですか?

BDDは行動主導の開発の略です。自動テストのアプローチを定義する場合、ソースは幅広く異なる可能性がありますが、ここで理解されるように、BDDはドメイン駆動型設計(DDD)からテスト駆動型開発(TDD)プロセスへのアイデアを取り入れています。

これらのコンセプトについては他にもたくさん書かれているので、ここではあまり深くは触れません。これらの用語のどれかが新しい場合は、それを心配しないでください。アプローチの仕組みを理解する最も簡単な方法は、下のチュートリアルの例を使って作業することです。

要点:TDDは、開発者が最初に目的の動作を定義するテストを作成し、テストに合格するコードを書き込むソフトウェア開発のアプローチです。DDDは、一貫性のある、実装に中立なドメイン言語を強調するアプローチです。したがって、採用しているBDDの形式には、次の3つのステップがあります。

  1. 実装中立ドメイン言語で記述された一連のステップからなる実行可能な仕様を記述する
  2. そのような各ステップを原子的に実装するテストコードを書く
  3. テスト合格する(したがって仕様に準拠する)ソースコードを書くことは、

エンドツーエンドテストで最も頻繁に使用されるGherkin言語と同様に、仕様を

  • 与えられた(テストコンテキストを設定するために)
  • (テスト中のコードの実行時に)、
  • それから(アサーションを作るための)ステップ。

チュートリアル

さて、名前と言語をとり、選択した言語でその人に誕生日の誕生日を希望する関数のテストを作成してみましょう。このブログポストで説明されているすべてのコードは、いつでも失われる可能性があるため、コンパニオンレポがあります。コミット履歴は、ここで概説したプログレッションと一致するので、必要なポイントまで正確に戻ることができます。

セットアップ

ノードとNPMがインストールされており、コマンドラインを使って快適であると仮定します。私はノードv8.9.0とNPM v5.5.1を使用しています。そのため、これらの正確なバージョンが役立つかどうかチェックする際には、以下の問題が発生した場合はチェックしてください。以下のコードはES6で書かれているので、私はあなたがすでにそれに慣れていると仮定しています。

ディレクトリを作成し、その内部をナビゲートします。

テストを実行するには、Mochaがインストールされている必要があります:

使用する必要はありません--save--save-devのオプションを、一度インストール我々は、使用して直接モカを実行することができNPXを

最後に、コードを保存するためにいくつかのファイルが必要です。

下のコードブロックでは、編集中のファイルの名前をコメントの先頭に置き、// ...コメントを含むコードをいつ削除するかを示します。

幸せな道

私たちは、最初に幸せな道を考えて、外からのアプローチを使用します。「Outside-in」とは、最初に実際に作業したいコードを記述し、後で作業するために必要なコードを書き、強制的に使用するコードを書き込むことを意味します。これは、後で必要となるコードを予測しようとする「インサイドアウト」と対照的です。そのコードを書くときには、すでに依存しているすべてのコードがあります。もちろん、インサイドアウトのアプローチがあなたに適しているかもしれませんが、インサイドアウトはBDDで特にうまくいきます。

幸いな道に取り組むために、すべてが計画どおりに進んだら、何が起こるべきかを明記する。

仕様上のMochaを実行すると、then.itShouldReturn定義されていないため、保留中のテストが表示されます。

ステップの定義が必要です!

ここで何が起こっていますか?

  1. 私たちはthen.js仕様から参照する関数をエクスポートしています。
  2. この関数は、戻り値が期待値に等しいことを宣言します(単に関数名が意味するものを実行する)。
  3. 戻り値はテストコンテキスト外で破棄されます(これはMochaの単なる機能です)。
  4. 期待値は、正規表現を使用してテストタイトルから抽出されます。

ここでの最後のポイントは、仕様で特定の値の具体例を紹介し、テストで直接使用することができるため、仕様が現実的な値で動作しているかどうかを簡単に確認できます。冗長定義は互いに同期される。また、このステップは、異なる文字列値を持つ別のテストで再利用できる状態になっていることを意味します。

今我々は失敗したテストを持っている:

もちろんreturnValue、まだ定義されていないので、未定義です。つなににつなつなうま습ま습ま습ま습ま습ま습ま습ま습ま습ま습ま습ま습ま습ま습ま습

そして対応するステップ定義:

ここでは、戻り値をテストコンテキストに格納して、Thenステップで後でそれにアクセスできるようにします。テストは失敗します:TypeError: wishHappyBirthday is not a functionnameそしてlanguage、明らかにいくつかの点で扱われるために持っているが、今、私たちは、ソースコードの機能が必要になります!

私たちのテストは合格です:

しかし、この関数はひどく、名前や言語にかかわらず同じ出力を提供します。より豊かな仕様が必要です。

対応するステップ定義:

ここでは、getFirstQuotedString前に見た関数を再利用してテストタイトルから名前/言語を取得し、後でアクセスできるようにテストコンテキストに格納します。これらの関数はbeforeEachフックで実行されるため、テスト自体ではなく、テストのからのタイトルを使用する必要があることに注意してください(これらの関数は、必要に応じてutilsファイルに格納できます)。

我々は両方の言語(2x2シナリオ)で両方の名前をカバーするために仕様の一部を入れ子にしました。また、さまざまな変数を使用して6つの全く新しいステップを仕様に追加したにもかかわらず、2つのステップ定義関数を記述するだけでした。今私はドライと呼んでいます!

次の行に3つの失敗があります。

私たちはソースコードを改善する以外に選択肢はありません:

私たちのテストは合格です!

不幸な道

幸せな道のりのために、私たちがまだ扱っていない言語を使って関数を呼び出すなど、何がうまくいかないのはどうですか?最初に仕様を更新しましょう:

次に、ステップ定義:

テストでは言語がわかっているかどうかは気にしないので、すでに書いgiven.anUnknownLanguagegiven.aLanguageステップ定義に別名を付けることができます。when.wishHappyBirthdayIsCalledWithTheNameAndTheLanguageただし、エラーがスローされた場合は、後でアクセスするためにテストコンテキストに格納されるように、ステップ定義を更新する必要があります。

テストが失敗するのはTypeError: Cannot read property 'message' of undefined、私たちの関数が正しいメッセージを持つものだけでなく、エラーをまったく投げないからです。ソースコードを更新する時間:

そしてすべてが通り過ぎています:

明らかに、この関数(名前の不足、名前のタイプが間違っているなど)の検証に関してもっと多くのことができますが、ここではこのチュートリアルを終了します。

メリットは何ですか?

  1. このアプローチでは、テストに一貫した構造/スタイルが強制されます。仕様は信頼性の高いルック・アンド・フィールを持ち、ステップ定義機能は短く自己完結しています。もうスパゲッティのテストはありません!
  2. デフォルトで原子テストが行​​われるため、テストスイートは脆弱ではありません。
  3. テスト実装から抽象化された言語で仕様を記述することで、その機能をどのようにテストするかについての考えに気を取られることなく、必要な正確な機能について考えることができます。これにより、より強固でより意味のあるテストが奨励され、最終的にはより堅牢なソースコードになるはずです。
  4. いくつかのテストにどのようなステップが必要かを正しく考えたら、実際のテストコードを書くのは簡単です。
  5. また、コードベースの新規ユーザーは、あなたが書いたテストを理解することも簡単です。テストの意味を実装から推測させるのではなく、簡単に消化可能なチャンクで起こっていることを説明する英語のような文章を読むだけです。テスト記述が冗長で明示的であるという事実によって、それらは助けになります。スペック・ファイルの反復度が高いほど、明瞭さのために支払われるコストです。
  6. 各ステップは1つの場所に定義されているため、このアプローチは既存のステップの再利用を促し、DRYコードベースを増やします。Liskyの以前のテスト手法から切り替えるときに、数百行のテストコードを削除しました。
  7. リファクタリングでは、テストで問題が発生することがあります。多くの箇所で更新が必要な場合や、気づかないうちに意味を失う可能性がある最も狡猾なケースでは、改ざんが発生する可能性があります。このアプローチにより、リファクタリング・テスト・コードはずっと簡単になります。関連するステップ定義を変更するだけで、そのステップを含むすべてのテストが更新を反映します。

欠点は何ですか?

  1. 良い仕様を書くのは難しいです。実際、これは他のテスト方法にも当てはまりますが、BDDを実行しているときにはすぐに明らかになります。
  2. 時には、新しいテストで使用しているステップをすでに定義したことを知らせるのが難しい場合があります。これは、ステップ定義をモジュールに分割することで軽減できます。新しい定義を作成する前に、適用可能なステップ定義の候補リストを簡単に参照できます。
  3. 少し慣れていないので、このアプローチに新しい開発者はしばらく慣れているかもしれません。

結論

このBDDのテストへのアプローチは比較的新しいものであり、私たちはまだそれに取り組んでいます。より快適になるにつれて、より多くのパターン、コードベース管理テクニック、およびステップを作成するためのより良い方法を発見しています。しかし、我々はすでに明確なテストとより簡潔なテストコードベースの面で利点を見てきました。

私は、このアプローチを採用していない他のプロジェクトでテストを書くことになると、怠惰なテストを書いているかのように、不満を覚えています。

あなたがリスキーに貢献することに興味があるなら、あなたから聞いてみたい!我々はいくつか持って貢献ガイドラインを、私たちは(このブログの記事で説明したBDDスタイルを使用して)完全なテストカバレッジを含めるようにプルリクエストをお願いします。ただし、このチュートリアルで使用されているコードとは異なる点があります。

参考URL:https://blog.lisk.io/bdd-style-unit-testing-with-mocha-704137e429d5 

●無料でLINE@で有益情報を随時流しています。
https://line.me/R/ti/p/%40gtu0961z 
興味ある方は登録してください。


■yobit net

https://yobit.net/en/

●XRPブログ作者に募金

アドレス:
rE86FEdaEXsKJ6GVvNJHwKdAq757nuJdom

●アマゾン商品がビットコインを使って15%off!
●NEMが1時間に1回最大100XEM貰える!


人気ブログランキング