test.it-ネストおよび詳細な出力を使用してJavaScriptまたは自転車をテストする

注意! この記事には、リリース(v1.0.0より前)バージョンのライブラリの作業例が含まれています。

別の記事が近日公開されます。 これは参照専用です。 ライブラリを使用するために必要なすべての情報は、READMEとコード内のコメントで取得できます。



注目を集める画像:

test.it habrahabr

私は初心者のWeb開発者です。 そして、少し前まで、私は本物のプログラマーがするように働く方法を学びたかった。

これにより、3つの主要な要素を理解しました。

  1. バージョン管理システムを使用します。
  2. 有能なコードのコメント。
  3. TDDまたは少なくともコードの単純な単体テスト。


最初は、 gitの基本を学び、 githubに最初のリポジトリを作成する必要がありました。 2つ目はJsDocを選択しました 。そのため、 ノートパッド++から崇高なテキスト切り替える必要がありました(対応するプラグインのみがありました)。

しかし、私にとっては予想外の3番目の問題で、深刻な困難が生じました。





私は本当にjQueryを尊重しているため(ちなみに、jqのプラグインを作成する最初のリポジトリを開いたため)、ユニットテスト用のフレームワークの選択はQunitで決まり、致命的なエラーでした。 そして、次のことに直面しました:



私はこれが本当に好きではありませんでしたが、大きなおじやおばさんがそのように働いているという認識はあきらめませんでした。 プラグインの開発が終わったら、テスト中に対処しなければならなかったすべての神聖な意味を発見することを望んでいました。 一週間、私は刺し、泣いていましたが、私はサボテンを食べ続けました 、私は病気の深刻な形で戦った、 私は方法を知っています 。 しかし、私の神経は鉄ではなく、結局、 小さな女の子があきらめて自転車を書いたとき、私は泣き出しました。



そして今、彼についてもっと



test.itは、JavaScriptコードをテストするためのフレームワークです。

テキストに興味がない人のために-githubのリポジトリへのリンク: test.it

主な機能:

私が最後にQunitを見たのは、もちろん彼らはよくやった。



現在実装されているテスト:





簡単なスタート



フレームワークを接続するには-行を追加するだけです
<script src='path/to/testit.js'></script>
      
      



<body>タグの最後の任意の場所



そして、明らかに最初のテストを使い始めることができます:

 test.it('first test');
      
      





テスト -条件の充足をチェックする関数テストオブジェクトのメソッド)

test.it( entity関数は、 エンティティの存在とその値の非偽性をチェックします。

コンソールを開くと(このAPIを最大限にサポートしているFirebugまたはChrome)、次のように表示されます。

空のコンソール

あまりない(:

そして、すべてはtest.done()を呼び出してテストを完了しなかったためです。 やってみましょう。 これで、コードは次のようになります。

 test.it('first test'); test.done();
      
      



そして、それぞれコンソールで:

ルート-パス

つまり、すべてのテストに合格します。



root-ルート要素、またはゼロレベルテストのグループ。 他のグループと同じプロパティがありますが、それらについては後で詳しく説明します。

ルート要素を展開すると、その内部にあるすべてのテストの通過の統計と、実行時間が表示されます。

根

それは明らかです:

統計は、テストとグループに分けられます。 しかし、確かに次のリリースでは簡単になり、この分離はなくなります。



最終行: pass :コメントなし -テスト。 それを拡張して、さらに詳しく見ていきます。

最初のテスト

最初に行うことは、テストに合格したというラベルです。 一般に、それらには3つのタイプがあります。

さらに、 コメントは、まだ設定していないコメントです。 以下では、これを行う方法を検討します。

次の行「argument exist and not false」は、テストに合格するために必要なものの説明です。

そして最後に、受け取った引数の配列。この場合、1つの要素「first test」から



この不快なコメントが表示されないようにするために、テストにコメントを追加します。

 test.it('first test'); test.comment(' '); test.done();
      
      



結果は次のようになります。

簡単なチェック



しかし、私たちが書いたすべては、原則として、特に何もテストしませんでした。 状況を修正して、実際のテストを追加しましょう。

 test.it('first test'); test.comment(' '); var Me = {name:'Titulus',lastName:'Desiderio'}; test.it(Me); test.comment(' ?'); test.done();
      
      



コンソールで:

2つのテスト



2番目のテストをより詳細に検討できます。 それを展開すると、引数の配列内の唯一の引数がオブジェクトになります。

2テスト

ご覧のとおり、テストでは、渡された唯一の引数の値の有無のみをチェックします。 しかし、これは、このオブジェクトを覗くのを妨げないことがあります。これは、送信した内容を再度思い出させ、場合によっては有用な追加情報を受け取るためです。



前のテストは正常に完了しました。タスクをさらに難しく設定しましょう。

 test.it('first test'); test.comment(' '); var Me = {name:'Titulus',lastName:'Desiderio'}; test.it(Me); test.comment(' ?'); test.it(Me.habr); test.comment('?'); test.done();
      
      



失敗する

お気づきのように、失敗したテスト、および対応する失敗したグループ(ルート)はデフォルトで展開されました。

ところで、引数の配列のおかげで、テストが失敗した理由がすぐにわかります-渡された引数は定義されていません。



今では状況を修正するために残っています:

 test.it('first test'); test.comment(' '); var Me = {name:'Titulus',lastName:'Desiderio'}; test.it(Me); test.comment(' ?'); Me.habr = '!'; test.it(Me.habr); test.comment('?'); test.done();
      
      



そして再び古い写真!

ルート-パス



タスクを複雑にしましょう。 存在および偽りをチェックする代わりに、値の正確さをチェックします。

 test.it('first test'); test.comment(' '); var Me = {name:'Titulus',lastName:'Desiderio'}; test.it(Me); test.comment(' ?'); Me.habr = '!'; test.it(Me.habr); test.comment('?'); test.it(Me.habr,'habrahabr.ru'); test.comment(' '); test.done();
      
      



関数test.it( entity1、entity2 -entity1entity2の等価性をチェックします。

コンソールを見てみましょう。

ハブラハブル! != habrahabr.ru

テストは失敗しましたが、これは予想どおりです。 結果を見ると、失敗の理由は明らかです。 修正中

 Me.habr = '!';
      
      



 Me.habr = 'habrahabr.ru';
      
      



私たちは再び得る

ルート-パス



もっと深くする必要がある



上記のグループを理解します。

グループ -



次のコードを検討してください。

 test.it(2>1); test.comment('    ?'); test.group(' ',function(){ test.it(2>1); test.comment(' ?'); }); test.done();
      
      



test.it(2> 1); そして、すべてが明確ですが、 test.groupは何をしますか?

関数test.group( groupnamefun -テスト、他のグループ、および他のコード用の新しいサブグループを作成します。 名前はgroupname引数から取得されますfun関数は実行を試みますが、その中でエラーが発生しても、残りのコードは中断されません。 エラーは、このグループのエラーフィールドに配置されます



ルートを明らかにしましょう:

グループ

ここでは、 最初のグループであるグループが rootと同じ方法でフレーム化されており、名前だけが私たちが尋ねたものです。

それも明らかにします。

最初のグループ

ルートとの特別な違いはなく、そうすべきではありません。

ここでは、 ルートとグループの統計にのみ注意を払う必要があります。

重要なポイント:統計では、特定のレベルの結果のみが表示されます。 2つのテストを記述したが、テストの統計でルートに合格したテストは1つだけだとします。



さらにテストを追加します。

 test.it(2>1); test.comment('    ?'); test.group(' ',function(){ test.it(2>1); test.comment(' ?'); test.it(1, Number(1)); test.comment('    '); test.it(habr); test.comment('      ?'); test.it(2+2,4); test.comment('    '); }); test.it(1<2); test.comment(' ?'); test.done();
      
      



そして見る

間違い

2 + 2 = 4のテストも実行されなかった。これは、 habrを使用した以前のテストがReferenceErrorエラーのために実行されなかったためであり、テスト前に統計の下にきれいに表示された。 しかし同時に、 1 <2の最後のテストは合格です。これは、グループ外でエラーが発生したためです。



エラー処理は、今日自分が設定した優先タスクの1つです。 したがって、次のリリース後にこの例の関連性が失われても驚かないでください。 しかし、プログラムを異常終了させずにエラーをキャッチするという主な考えは残っています。



そして、グループに関する最後の瞬間。 マルチレベルのネスト!

もっと深くする必要がある

 test.group('need',function(){ test.group('to',function(){ test.group('go',function(){ test.group('deeper',function(){ test.it('bye habr'); test.comment('bye bye'); }); }); }); }); test.done();
      
      



マルチレベルのネスト



ボンネットの下



すべてのコードはgithubで利用できるため、それを読んだり、コメントしたり、フォークしたり、プルリクエストを提供したりできます。 MITライセンス 。ただし、 WTFPLへの切り替えを考えています。



ゼロレベルのグループに対応するオブジェクトであるtest.rootについて詳しく説明します。 テストがそれを埋めてから、 _printConsole()がそれを解析し、このすべての美しさをもたらします。

グループを使用した最初の例のtest.root:
 { "type": "group", "name": "root", "status": "pass", "time": 7, "result": { "tests": { "passed": 1, "failed": 0, "error": 0, "total": 1 }, "groups": { "passed": 1, "failed": 0, "error": 0, "total": 1 } }, "stack": [ { "type": "test", "status": "pass", "comment": "    ?", "description": "argument exist and not false", "time": 0, "entity": [ true ] }, { "type": "group", "name": " ", "status": "pass", "time": 1, "result": { "tests": { "passed": 1, "failed": 0, "error": 0, "total": 1 }, "groups": { "passed": 0, "failed": 0, "error": 0, "total": 0 } }, "stack": [ { "type": "test", "status": "pass", "comment": " ?", "description": "argument exist and not false", "time": 0, "entity": [ true ] } ] } ] }
      
      





ところで、はい。 私は非常に恥ずかしいですが、サードパーティのコードの一部があります-deepCompare()関数は外部からアクセスできません。 任意のタイプの2つの引数を比較します。 ここで取っ



また、マルチレベルのネスティングを実装するヒントについて@mkharitonovに感謝します。



コインの裏側



もちろん、欠点もあります。 深刻なものもそうでないものもあります。 オープンソースのコードなので、コミュニティがそれらを最小限に抑えたり、それらを利点に変えたりするのに役立つことを願っています。

キー:





次は?



そして、上記の統計出力の変更があります。

エラー処理と出力の改善。

テスト出力の改善-失敗したテストの番号付けとヒントが追加されます。

新しいテストtest.themtest.typetest.typestest.timeが追加されます。 それらについての詳細はREADMEで読むことができます。

前のセクションで言及した欠陥は修正されます。

そして、もちろん、最適化。



もう一度githubのリポジトリへのリンク: test.it



PSカルマが十分になり次第、投稿はハブ「I PR」に転送されます。



All Articles