別名rspeс、つまり テストの遅延変数

sayingにもあるように、「禁断の果実は甘い」ので、私と一緒です。 RSpecでテストを作成しようとしたことがあるので、各言語で宣言型BDD DSLを使用したいと思います。 たとえば、JavaScriptにはmocha.js、jasmine.jsなどの類似物があります。 しかし、いや、十分ではありません。 説明やit-sだけでなく、遅延変数も欲しいです。subjectとletを意味します。



一見愚か! 内なる声が「なぜ?」と叫び、良心が答えます:「きれいなコードが重要です!」 まあ、簡単なテストは一般的に非常に重要です!」



これがmochajsのライブラリの誕生です。これにより、遅延変数(別名let)と `subject`を作成できます。



私がすでに緊張していることを理解し、喜びに照らされている人のために、 Githubにようこそ。

他の皆、そして特に懐疑論者にとって、私は控えめに見ることを提案します。



なぜこれが重要なのでしょうか?



それが理由です!



さて、今真剣に



彼らは通常、テストで何を書きますか?

describe('Invoice', function() { var invoice, user; beforeEach(function() { user = User.create({ role: 'member' }); invoice = user.invoices.create({ price: 10, currency: 'USD' }); }); it('has status "fraud" if amount does not equal to invoice amount', function() { invoice.paid(1, 'USD'); expect(invoice.status).to.equal('fraud'); }); it('has status "fraud" if currency does not equal to invoice currency', function() { invoice.paid(10, 'ZWD'); expect(invoice.status).to.equal('fraud'); }); ..... })
      
      





すべてがうまくいくようで、アカウントが作成され、ユーザーが作成され、必要以上にお金が支払システムから入らなかった場合、支払いは拒否されます...

注意テスト!
 describe('Invoice', function() { var invoice, user; describe('by default', function() { beforeEach(function() { user = User.create({ role: 'member' }); invoice = user.invoices.create({ price: 10, currency: 'USD' }); }); it('has status "fraud" if amount does not equal to invoice amount', function() { invoice.paid(1, 'USD'); expect(invoice.status).to.equal('fraud'); }); it('has status "fraud" if currency does not equal to invoice currency', function() { invoice.paid(10, 'ZWD'); expect(invoice.status).to.equal('fraud'); }); }); describe('when user is admin', function() { beforeEach(function() { user = User.create({ role: 'admin' }); invoice = user.invoices.create({ price: 10, currency: 'USD' }); }); it('has status "paid" if amount does not equal to invoice amount', function() { invoice.paid(1, 'USD'); expect(invoice.status).to.equal('paid'); }); }); ..... })
      
      







つまり、セットアップを複製し、他のパラメーターとハウリングを渡すだけです! コピー&ペーストを長く生きて...そして、誰が `afterEach`の変数をきれいにするのでしょうか?



私のペーストに対する怠azine!



このライブラリが解決するタスクの1つは、地雷の破壊です! どのくらい正確に? はい、ただ

 describe('Invoice', function() { def('user', function() { return User.create({ role: 'member' }); }); def('invoice', function() { return $user.invoices.create({ price: 10, currency: 'USD' }); }); describe('by default', function() { it('has status "fraud" if amount does not equal to invoice amount', function() { $invoice.paid(1, 'USD'); expect($invoice.status).to.equal('fraud'); }); }); describe('when user is admin', function() { def('user', function() { return User.create({ role: 'admin' }); }); it('has status "paid" if amount does not equal to invoice amount', function() { $invoice.paid(1, 'USD'); expect($invoice.status).to.equal('paid'); }); }); ..... })
      
      





コードが小さくなり、コピー&ペーストが少なくなり、透明度が高くなりました! やった! さらに、変数は各テストの後に独立して削除されるため、「afterEach」ブロックを記述する必要はありません。 便利ですか?



:名前の衝突を避けるために、変数に$記号が追加されています。 そのような変数がすでに存在する場合、例外が発生します。



そして今、それがどのように機能するかについて



遅延変数は、それらにアクセスした時点でのみ作成される遅延変数です。 つまり、最後の `describe`では、` $ invoice`が `it`内に作成され(beforeEach`ではなく)、別のユーザーで作成されます。通常のユーザーの代わりに管理者が作成されます。 そのため、代替が発生し、アカウントは管理者にアタッチされ、何でもできるようになりました。



遅延変数はテストではなくスイートのコンテキストで作成され、テスト内で「def」を記述することは非論理的であることは明らかだと思います(私たちは皆、賢い人だと知っていますが、これを書かなければなりませんでした)。



最後に、出力は何ですか?



  1. 怠azine! これ以上の余分な呼び出しはありません。 テストを遅くしないでください
  2. 変数を構成する機能
  3. コピーペーストの不足
  4. 各「it」の後の変数の慎重なクリーニング
  5. また、 README自由に読むことができるいくつかの小さな機能


1行でテストしますか?



前述のように、ライブラリを使用すると、テストの「対象」を定義できます

件名付きの例
 describe('Invoice', function() { subject(function() { var admin = User.create({ role: 'admin' }); return Invoice.create({ price: 10, currency: 'USD', user: admin }) }); it('has status "pending" by default', function() { expect($subject.status).to.equal('pending'); });
      
      







次に、構文につながります

 describe('Invoice', function() { subject(function() { var admin = User.create({ role: 'admin' }); return Invoice.create({ price: 10, currency: 'USD', user: admin }) }); its('status', () => isExpected.to.equal('pending')); // or even better it(() => isExpected.to.be.pending)
      
      





これはまだではありませんが、スリーブのES6機能とテストで「サブジェクト」を作成する機能を使用するのは非常に簡単です。



更新: 「chai」を使用する場合は、次のように書く方が良いと思います

  its('status', () => is.expected.to.equal('pending'));
      
      







PS :JavaScriptテストで十分な `sharedExamples`を持っていない人のために、私もこの記事を見ることを提案します



PPS :テストでのソリッドは、他のすべての場所でのソリッドよりも重要です。



All Articles