test.it-再びではなく、再び

こんにちは、Habr。
test.itに関する私の記事の後、 永遠の週が過ぎました そして、私はこの期間を少なくとも1か月延長するつもりはなかったので、新しい出版の時が来ました。
注目を集める画像:

それ以来、ライブラリ(Habrachiansのおかげで大部分)は新しい機能を獲得しました。
また、前の記事で示した構文は現在のバージョンでは完全に機能しないため、この記事をさらに3週間延期する権利はありません。

たくさんの言葉が嫌いな人-動作中のコードを見ることができるサイトGitHubWiki

チェーンコールがありました
test.it(some) .comment('comment to test') .callback(function(){alert('test has been passed')}) .arguments(); // -> [some] test.group('group', function(){ ... }) .comment('comment to group') .result(); // -> true/false 

および新しいネスト機構
 test.group('first group',function(){ ... test.group('second group', function(){ ... }); ... }); test.group('first group').group('second group',function(){ ... }); 

エラーを表示する新しい方法
エラー

また、2つの追加メソッドはtest.typeof()およびtest.trace()です。

また、3つのWikiページもあります。

そして今、これらすべてについてさらに詳しく説明します。


など。 wikiの例を見てみましょう:

テストを開始する前に、 test.typeof()メソッドを使用します。
 console.log( test.typeof(1) ,test.typeof("text") ,test.typeof([1,2,3]) ,test.typeof({a:1,b:2}) ,test.typeof() ,test.typeof(document) ,test.typeof(document.getElementsByTagName("body")) ,test.typeof(window) ,test.typeof(/yes it is RegExp/) // and many many more ... ); 
test.typeof() -渡される値のタイプを決定します。

ArrayBooleanDateErrorEvalErrorRangeErrorReferenceErrorSyntaxErrorTypeErrorUriError )、 FunctionNaNおよびNumberObjectRegExpStringWindowHTMLNodeListを区別できます 。 彼はまた、空の変数を「未定義」定義していますが、標準のtypeofとは異なり、宣言されていない変数を引数として受け取ることはできません。 「未定義」は、宣言された空でないオブジェクトの存在しないプロパティに対して応答します。 しかし、これは言語の特異性です。

ページを更新すると、コンソールに次の行が表示されます。
タイプ

次にtest.trace()メソッドを見てみましょう。
 (function firstFunction() { (function secondFunction() { (function lastFunction() { console.log(test.trace()); })(); })(); })(); 
test.trace() -このメソッドを呼び出すために実行されたコードのリスト(「\ n」で区切られた行にアセンブルされた)行を返します。

実際、これは実際のトレース() ではありません(残念ながらJavaScriptでは使用できません) 。これは、ライブラリ内の呼び出しへのすべての参照が切り取られているためです。

コンソールへの出力が追加されました。
トレース
以降、スクリーンショットのコンソール出力の重要でない部分は、画像のサイズを無意味に大きくしないように省略されます。

テストに取りかかりましょう。


最初に、テスト用のオブジェクト、整数値と空の変数を持つ変数を作成します。
 var Family = { name: "Desiderio", pet: { type: "dog", name: "google" }, members: [ { name: "Titulus", age: 23 }, { name: "Dude", age: Infinity } ] } var myIQ = 100; var Nothing; 
このコードに関する質問は発生しないはずです。

さらに進みましょう。

次のステップは最初のテストです。

非偽造テスト。


すべてが以前と同じです。
 test.it("hello world"); test.done(); 
test.it(値) -新しいテストを作成し、 が偽でないことを確認します
test.done() -テストを完了し、コンソールに結果を表示します。
さらに、 test.done()がコードの最終行であると想定されます。 例では省略します。

コンソールには以下が表示されます。
根
どこで:

このグループを展開すると、テスト/グループのリストが表示されます。
ルート展開
唯一のテストを分解する前に、それを明らかにしましょう。
テスト拡張
など:

連鎖メカニズムを使用してみましょう。


最も基本的なケースはコメントを追加することです:
 test.it(2+2==5) .comment("i badly taught algebra at school"); 
.comment(テキスト) -チェーンが呼び出されたテスト/グループにコメントを追加します 。 同時にチェーンを続けますが、それについては後で詳しく説明します。

このコードは次のように書くことができます。
 test.it(2+2==5).comment("i badly taught algebra at school"); 
ただし、チェーンが長い場合は、列への書き込みがより便利で視覚的です。

これで、 ルート (失敗したテストが含まれているために自動的に開かれます)は次のようになります。
2つのテスト
最初の行のカウンターでは、2番目の数値が0から1に増加していることがわかります。これは、失敗したテスト/グループの数が増加したことを意味します。

デフォルトで開かれたテストに注意を向けましょう(合格しなかったため)
これは、 失敗ステータス、およびテストで失敗したこと、および「学校で代数をひどく教えた」というコメントのみが前のものと異なります。

明らかに、 test.it(値)では、文字列だけでなく、変数、式、関数呼び出しなども渡すことができます。 原則として、合格したものは何でも、最初にそれが完了し、結果が取得され、この結果はすでにテストに送られます。 それがJavaScriptです。

今言ったことを確認します。 式をテストします。
 test.it(Infinity>Infinity-1) .comment("philosophically is not it?"); 
あなたはこの表現をコップ一杯のコーヒーで考えることができます、私たちは別のもののためにここにいます。 テスト結果は前の結果のように見えますが、これは明らかです。
無限大

チェーンコールのジャングルに向けて出発し、 間違いなく出発するまで 、別のtest.it()テストバリアントを見てください。

同等性テスト


以前に宣言した変数を別の値と比較しましょう。
 test.it(myIQ,"genious") .comment("is I'm genious?"); test.it(myIQ,(1+10)*12 - 34 + 5*5*5 - 123) .comment("check my IQ to be a normal"); 
test.it(value1、value2) -渡された2つの値の等価性をチェックします。

コンソールでは、これらの2つのテストは次のようになります。
IQ
異常はありませんが、最初の(失敗した)テストの説明に注意を払う必要があります。 「 引数のタイプが異なる 」-このテキストには、テストが失敗した理由を説明するヒントが含まれています-渡される引数のタイプは異なります。

次に、より複雑なチェーンを試してみましょう。
テストの結果に応じて、いくつかのアクションを実行しましょう。
 if (test.it(Family) .comment("Is Family exist? Is it not empty?") .result()) { console.info("by if: ","Yep! Here it is!"); } else { console.warn("by if: ","ALARM! there are no Family"); } 
.result() -チェーンを終了し、テスト結果を返します。

このコードでは、 Familyに誤りがないかどうかを確認し、結果に応じてコンソールに異なるフレーズを出力します。
コンソール出力は次のようになります。
ならば

確かに、このタスクは別のチェーンコールを使用して実行することをお勧めします。
 test.it(Nothing) .comment("Is Nothing exist? Is it not empty?") .callback( function(){console.info("by callback: ","Yep! Here it is!");} ,function(){console.warn("by callback: ","ALARM! there are no Nothing");}); 
.callback(function(){/ * funcIfpass * /} [、function(){/ * funcIffail * /} [、function(){/ * funcIferror * /}]]) -次の3つの機能のいずれかを実行しますテストまたはグループに合格した結果。 チェーンを続けながら。
その結果、コンソールには次のように表示されます。
コールバックで
この設計は、チェーンを終了させないため、望ましいです。

グループ


次に、最初のグループを作成します。
 test.group("Empty group",function(){}); 
test.group(name、function(){...}) -新しいグループを作成するか、既存のグループを参照し 、2番目の引数で渡された関数内にあるテストでそれを埋めます。

しかし、テストに合格したため、グループは空で作成されますが、 合格ステータスで-単一の失敗したテストがないためです。
空のグループ
スクリーンショットを撮る前に、グループを開きました。これは、矢印を下に向けることで確認できます。2つの灰色のピクセルは、その終わりを示しています。 しかし、グループは空なので、ほとんど閉じているように見えます。

じゃあ より意味のあるアクションに進みます。 内部に2つのテストとコメントを含むグループを作成します。
 test.group('Family tests',function(){ test.it(Family.name,"Zukerberg") .comment("Are we test Zukerberg's family?"); test.it(Family.name,"Desiderio") .comment("Or Desiderio's?"); }).comment("unite!"); 
わかりました-複雑なことはありません!
テスト付きグループ
ここで、私たちが団結して追加したコメントに注意を払うだけの価値があります! -グループヘッダー内。

では、耳でフェイントを確認し、すでに作成されているグループにいくつかのテストを追加しましょう。 そして、テストだけでなく、結果に応じて新しいテストを開始するテスト。
次のコードを追加します。
 test.group("Family tests",function(){ test.it(Family.pet) .comment("Do we have a pet?") .callback(function(){ // I add test in your test, so you can test while you testing test.it(Family.pet,{type:"dog", name:"google"}) .comment("Is it right pet?"); }); test.it(Family.house) .comment("Do we have a House?") .callback(function(){ // next test will not be executed test.it(Family.pet,{type:"Huge", color:"green"}) .comment("Is it right House?"); }); }); 
このグループの最後の2つのテストと今説明した4つのテストを考慮すると、合計5つのテストがあります(原文)! 電卓で確認できます。
追加テスト
タイトルが見えますか? 3合格、2失敗-5のみ

新しいテスト


いくつかの異常なテストを見てみましょう。 まず、 「奇妙なテストがやってくる」グループで 、次の2つのテストを作成します。
 test.them([Family.pet, Family.members]) .comment("There must be memebers with pet, to call it a 'Family'"); test.types([Family.pet.name, Family.name],"string") .comment("Is names are string type"); 
test.them(values) -test.it(value)の類似物で、配列を最初の引数としてのみ使用します。この引数では、既に要素の非偽性をチェックします。
test.types(値[、type]) - test.them(値)のように、最初の引数で渡された配列の要素をチェックします。 ただし、それらが型と一致することを確認し、2番目の引数が渡された場合、この型をサンプルとして使用します。
このテストには単純化されたアナログがありますが、それについては少し後で説明します。

コンソールでの表示は次のとおりです。
それらとタイプ
明確にするために引数の配列とともにテストを開きましたが、何かのように思えますが、この明確さは低下しました。

そして、もう一つのチェーンマジックがあります:
 var numberOfMembers = test.type(Family.members,"Array") .comment("Is it a several members, nor a single member?") .arguments()[0].length; test.it(numberOfMembers>5) .comment("Is it big family?"); 
.arguments() -呼び出しチェーンを終了し、テスト( グループではなく! )に渡された引数を返します。
引数
説明しましょう-最初のテストでは、 Family.membersの値が偽造されていないことを確認しました。 これは2つの要素の配列であるため、テストに合格します。
arguments()[0] == Family.members 。 したがって、 numberOfMembers変数にはFamily.members配列の要素数、つまり2が含まれます。2が5以下であるため、2番目のテストは失敗します。

ネスティング


私たちが「 ここに奇妙なテストがやってくる 」グループにいることをまだ覚えていますか?
ここに別のグループを追加し、すぐにforコンストラクトを使用し 、同じタイプの複数のテストを作成します。
 test.group("Members age",function(){ for (i=0;i<numberOfMembers;i++) { test.it(Family.members[i].age>25) .comment("Is "+Family.members[i].name+" older then 25?"); } }); 
メンバーの年齢
現在、この新しいグループ「 Members age 」は古い「 here here strange test 」にあります。

間違い


同じグループ「 Members age 」に別のテストを追加します。
 test.it() .comment("yep, here is error"); 
test.it()は1〜2個の引数を受け取ることを想定しているため、このようなコードではエラーが発生します。
エラー
エラーヘッダー:

次に、 test.trace()の結果が来て、コード内で簡単に見つけられるようにします。 また、エラーオブジェクト自体(この場合はRangeError )は、誰かがより深く掘り下げたい場合です。

グループリンク


ルートレベルに戻りましょう。
念のため、「 ここに奇妙なテストがやってくる 」グループが次のようになったことを思い出させてください。
大グループ
その中に別のグループ「 Members age 」があります。 ここでテストを追加します。
 test.group("here comes strange tests").group("Members age",function(){ test.it("bye") .comment("good"); }); 
test.group(name) -グループへのリンクを返します。リンクはその後、チェーンの始まりとして使用でき、テストの新しいグループを追加したり、既存のサブグループにテストを追加したりできます。
これが最後にしたことです。 コンソールに次のように表示されます。
さようなら

最後に、上記のすべてを統合します。
すべてのコンソール出力を含む完全なリスト
 console.log( // look how do test.typeof() work test.typeof(1) ,test.typeof("text") ,test.typeof([1,2,3]) ,test.typeof({a:1,b:2}) ,test.typeof() ,test.typeof(document) ,test.typeof(document.getElementsByTagName("body")) ,test.typeof(window) ,test.typeof(/yes it is RegExp/)); (function firstFunction() { // look how do test.trace() work (function secondFunction() { (function lastFunction() { console.log(test.trace()); })(); })(); })(); var Family = { // Here some complex object name: "Desiderio", pet: { type: "dog", name: "google" }, members: [ { name: "Titulus", age: 23 }, { name: "Dude", age: Infinity } ] } var myIQ = 100; // and value var Nothing; // and empty value test.it("hello world"); // Let"s add some simple tests test.it(2+2==5).comment("i badly taught algebra at school"); // with comment test.it(Infinity>Infinity-1).comment("philosophically is not it?"); // with expression // check equalence test.it(myIQ,"genious").comment("is I'm genious?"); test.it(myIQ,(1+10)*12 - 34 + 5*5*5 - 123).comment("check my IQ to be a normal"); // try some chain staff if (test.it(Family).comment("Is Family exist? Is it not empty?").result()) { console.info("by if: ","Yep! Here it is!"); } else { console.warn("by if: ","ALARM! there are no Family"); } // do it again in better way test.it(Nothing).comment("Is Nothing exist? Is it not empty?").callback( function(){console.info("by callback: ","Yep! Here it is!");} ,function(){console.warn("by callback: ","ALARM! there are no Nothing");}); test.group("Empty group",function(){}); // try to make a group test.group('Family tests',function(){ // let's unite it! test.it(Family.name,"Zukerberg").comment("Are we test Zukerberg's family?"); test.it(Family.name,"Desiderio").comment("Or Desiderio's?"); }).comment("unite!"); test.group("Family tests",function(){ // and add some test after test.it(Family.pet).comment("Do we have a pet?") .callback(function(){ // I add test in your test, so you can test while you testing test.it(Family.pet,{type:"dog", name:"google"}).comment("Is it right pet?"); }); test.it(Family.house).comment("Do we have a House?") .callback(function(){ // next test will not be executed test.it(Family.pet,{type:"Huge", color:"green"}).comment("Is it right House?"); }); }); test.group("here comes strange tests",function(){ // test existance of most important Family properties test.them([Family.pet, Family.members]) .comment("There must be memebers with pet, to call it a 'Family'"); // test types of names test.types([Family.pet.name, Family.name],"string") .comment("Is names are string type"); // here some magic var numberOfMembers = test.type(Family.members,"Array") .comment("Is it a several members, nor a single member?") .arguments()[0].length; test.it(numberOfMembers>5).comment("Is it big family?"); // So if we know how many members there, lets check their age test.group("Members age",function(){ for (i=0;i<numberOfMembers;i++) { test.it(Family.members[i].age>25) .comment("Is "+Family.members[i].name+" older then 25?"); } test.it().comment("yep, here is error"); // add some error to see the trace }); }); // add final test deep in group test.group("here comes strange tests").group("Members age",function(){ test.it("bye").comment("good"); }); test.done(); 

一杯



そうそう。 test.rootはまだ存在しています。 結果を表示するための新しいオプションを作成するためにも使用できます。 それはわずかに簡素化されました(グループの場合、カウンターはグループとテストの分離を停止しました)。
空のルートは次のようになります。
 { "type": "group", "name": "root", "time": 0, "result": { "pass": 0, "fail": 0, "error": 0, "total": 0 }, "stack": [] } 


おわりに


感謝したい:


前回の記事で説明した欠点はまだあります。 しかし、その解決方法についてはすでに非常に興味深い考えがあります。

上記のすべてのコードの動作を確認できるサイトGitHubWiki

Source: https://habr.com/ru/post/J189216/


All Articles