рдЬреИрд╕рд╛ рдХрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ: "рдирд┐рд╖рд┐рджреНрдз рдлрд▓ рдореАрдард╛ рд╣реИ," рдЗрд╕рд▓рд┐рдП рдпрд╣ рдореЗрд░реЗ рд╕рд╛рде рд╣реИред RSpec рдкрд░ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рд╖рд╛ рдореЗрдВ рдШреЛрд╖рдгрд╛рддреНрдордХ BDD DSL рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдПрдирд╛рд▓реЙрдЧреНрд╕ mocha.js, jasmine.js, рдЖрджрд┐ рд╣реИрдВред рд▓реЗрдХрд┐рди рдирд╣реАрдВ, рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рдореИрдВ рди рдХреЗрд╡рд▓ рдХрд┐рд╕реА рд╡рд┐рд╡рд░рдг рдпрд╛ рдЗрд╕реЗ-рдПрд╕, рдмрд▓реНрдХрд┐ рдЖрд▓рд╕реА рдЪрд░ рднреА рдЪрд╛рд╣реВрдВрдЧрд╛, рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡рд┐рд╖рдп рдФрд░ рдЬрд╛рдиреЗ рджреЛред
рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ рдмреЗрд╡рдХреВрдл! рдПрдХ рдЖрдВрддрд░рд┐рдХ рдЖрд╡рд╛рдЬ рдЪрд┐рд▓реНрд▓рд╛рддреА рд╣реИ "рдХреНрдпреЛрдВ?", рдФрд░ рд╡рд┐рд╡реЗрдХ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИ: "рд╕реНрд╡рдЪреНрдЫ рдХреЛрдб рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ!" рд╡реИрд╕реЗ, рд╕рд╛рдзрд╛рд░рдг рдкрд░реАрдХреНрд╖рдг рдЖрдо рддреМрд░ рдкрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛрддреЗ рд╣реИрдВ! "
рдЗрд╕ рддрд░рд╣ рд╕реЗ рдореЛрдЪреЗрдЬ рдХреЗ рд▓рд┐рдП рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЬрдиреНрдо рд╣реБрдЖ, рдЬреЛ рдЖрдкрдХреЛ рдЖрд▓рд╕реА рдЪрд░ (рдЙрд░реНрдл рд▓реЗрдЯ) рдФрд░ `рд╡рд┐рд╖рдп` рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА
рддрдирд╛рд╡ рдореЗрдВ рд╣реВрдВ
рдФрд░ рдЦреБрд╢реА рд╕реЗ рдЭреВрдо рд░рд╣рд╛ рд╣реВрдВ, рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рд╣рд░ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП, рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдВрджреЗрд╣ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдХрдЯреМрддреА рдХреЗ рддрд╣рдд рджреЗрдЦрдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВред
рдпрд╣ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХреНрдпреЛрдВ рд╣реИ?
рдпрд╣реА рдХрд╛рд░рдг рд╣реИ
рдХрд┐! ред
рдЦреИрд░, рдЕрдм рдЧрдВрднреАрд░рддрд╛ рд╕реЗ
рд╡реЗ рдЖрдорддреМрд░ рдкрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдХреНрдпрд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ?
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 'рдореЗрдВ рдЪрд░ рдХреЛ рдХреМрди рд╕рд╛рдл тАЛтАЛрдХрд░реЗрдЧрд╛?
рдЦрджрд╛рди-рдкреЗрд╕реНрдЯ рдХреЗ рдЦрд┐рд▓рд╛рдл рдЖрд▓рд╕реНрдп!
рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдЦрджрд╛рди-рдкреЗрд╕реНрдЯ рдХрд╛ рд╡рд┐рдирд╛рд╢ рд╣реИ! рдмрд┐рд▓реНрдХреБрд▓ рдХреИрд╕реЗ? рд╣рд╛рдБ рдмрд╕
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` рдмреНрд▓реЙрдХ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдХреНрдпрд╛ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ?
рдиреЛрдЯ : рдирд╛рдо рдЯрдХрд░рд╛рд╡реЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░ рдореЗрдВ $ рдЪрд┐рдиреНрд╣ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред рдпрджрд┐ рдРрд╕рд╛ рдХреЛрдИ рдЪрд░ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рд╣реИ, рддреЛ рд╣рдореЗрдВ рдПрдХ рдЕрдкрд╡рд╛рдж рдорд┐рд▓рддрд╛ рд╣реИред
рдФрд░ рдЕрдм рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
рдЖрд▓рд╕реА рдЪрд░ рд╡реЗ рдЖрд▓рд╕реА рд╣реИрдВ рдЬреЛ рдХреЗрд╡рд▓ рдЙрди рддрдХ рдкрд╣реБрдВрдЪ рдХреЗ рд╕рдордп рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣реА рд╣реИ, рдЕрдВрддрд┐рдо 'рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди' рдореЗрдВ, рд╣рдорд╛рд░реЗ '$ рдЗрдирд╡реЙрдЗрд╕' рдХреЛ 'рдЗрдЯ' (рдФрд░ рдиреЙрдЯ рдПрдлрд╝реИрдЪ `) рдХреЗ рдЕрдВрджрд░ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдЕрдиреНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕рд╛рде: рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдмрдЬрд╛рдп, рдПрдХ рдПрдбрдорд┐рди рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╣реБрдЖ рдФрд░ рдЦрд╛рддреЗ рдЕрдм рд╣рдорд╛рд░реЗ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реБрдП рд╣реИрдВ, рдЬреЛ рдХреБрдЫ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрдм рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЖрд▓рд╕реА рдЪрд░реЛрдВ рдХреЛ рд╕реВрдЯ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рди рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЕрдВрджрд░ `рдбрд┐рдл` рд▓рд┐рдЦрдирд╛ рдЕрддрд╛рд░реНрдХрд┐рдХ рд╣реИ (рдореБрдЭреЗ рдкрддрд╛ рд╣реИ, рд╣рдо рд╕рднреА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕реНрдорд╛рд░реНрдЯ рд▓реЛрдЧ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╣ рд▓рд┐рдЦрдирд╛ рдкрдбрд╝рд╛)ред
рдЕрдВрдд рдореЗрдВ, рдЖрдЙрдЯрдкреБрдЯ рдХреНрдпрд╛ рд╣реИ?
- рдЖрд▓рд╕реНрдп! рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЙрд▓ рдирд╣реАрдВред рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдзреАрдорд╛ рди рд╣реЛрдиреЗ рджреЗрдВ
- рдЪрд░ рд░рдЪрдирд╛ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛
- рдХреЙрдкреА рдкреЗрд╕реНрдЯ рдХреА рдХрдореА
- рдкреНрд░рддреНрдпреЗрдХ `it` рдХреЗ рдмрд╛рдж рдЪрд░реЛрдВ рдХреА рд╡рд┐рд╡реЗрдХрдкреВрд░реНрдг рд╕рдлрд╛рдИ
- рдФрд░ рдХреБрдЫ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЖрдк README рдореЗрдВ рдЕрдкрдиреЗ рдЕрд╡рдХрд╛рд╢ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ
рдПрдХ рд▓рд╛рдЗрди рдореЗрдВ рдЯреЗрд╕реНрдЯ?
рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП `рд╡рд┐рд╖рдп` рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ
рд╡рд┐рд╖рдп рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг 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'));
рдпрд╣ рдЕрднреА рддрдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЖрд╕реНрддреАрди рдореЗрдВ ES6 рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдФрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ `рд╡рд┐рд╖рдп` рдмрдирд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред
рдЕрдкрдбреЗрдЯ: рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ `рдЪрд╛рдИ` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреБрдЫ рд▓рд┐рдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ
its('status', () => is.expected.to.equal('pending'));
рдкреБрдирд╢реНрдЪ : рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ `shareExamples` рдирд╣реАрдВ рд╣реИрдВ, рдореИрдВ
рдЗрд╕ рд▓реЗрдЦ рдХреЛ рднреА рджреЗрдЦрдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ
PPS : рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ SOLID рдЕрдиреНрдп рд╕рднреА рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ SOLID рд╕реЗ рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред