Jasmine - The JavaScript BDD Testing

C43978727926bed201399816f7efb45d?s=47 Joseph Chiang
September 06, 2013

Jasmine - The JavaScript BDD Testing

C43978727926bed201399816f7efb45d?s=128

Joseph Chiang

September 06, 2013
Tweet

Transcript

  1. JASMINE JavaScript Testing with Jasmine josephj@Faria Study Group

  2. WHY?

  3. WHY?

  4. WHY? ၹ㬪∉⅂ޓഒĆ

  5. WHY?

  6. WHY? ὕ㢻Ά܄ඳࣼФˀ၂˛Ć

  7. WHY? ὕ㢻Ά܄ඳࣼФˀ၂˛Ć 不可質疑你的測試!

  8. ݤἒӑἱ֥ᇶⅳ

  9. • What is Software Testing? • Jasmine • Writing Good

    Tests • Matchers in depth • More Jasmine Features • Spies • Using Jasmine with Other tools • What’s it like? ݤἒӑἱ֥ᇶⅳ
  10. • What is Software Testing? • Jasmine • Writing Good

    Tests • Matchers in depth • More Jasmine Features • Spies • Using Jasmine with Other tools • What’s it like? ݤἒӑἱ֥ᇶⅳ ⦁೮ਔđ∉൞ିᾣ؟ഒĤ
  11. ằႵུᇶⅳႄఏ໡֥⇙౿ℭ

  12. OK, what next? ằႵུᇶⅳႄఏ໡֥⇙౿ℭ

  13. OK, what next? ằႵུᇶⅳႄఏ໡֥⇙౿ℭ ପἠᇶⅳࣼۡ၂؍ઋਔ

  14. ಯಖ൞၂ЧݺℼĆ Practical > Theoretical

  15. cBad -Ớ5%%#%%֥ࢺℚaೂޅለ⇔ݺ֥ 5FTU׻٤ӈֹᾏ੻b ಯಖ൞၂ЧݺℼĆ Practical > Theoretical

  16. cBad -Ớ5%%#%%֥ࢺℚaೂޅለ⇔ݺ֥ 5FTU׻٤ӈֹᾏ੻b cGood - ⃸ồᆀޓॹỚ+BTNJOFഈ൭ğ ಯಖ൞၂ЧݺℼĆ Practical > Theoretical

  17. cBad -Ớ5%%#%%֥ࢺℚaೂޅለ⇔ݺ֥ 5FTU׻٤ӈֹᾏ੻b cGood - ⃸ồᆀޓॹỚ+BTNJOFഈ൭ğ c.BUDIFS∻4QJFT׻ᾣ֤⃔↾ၞ׭b ಯಖ൞၂ЧݺℼĆ Practical >

    Theoretical
  18. cBad -Ớ5%%#%%֥ࢺℚaೂޅለ⇔ݺ֥ 5FTU׻٤ӈֹᾏ੻b cGood - ⃸ồᆀޓॹỚ+BTNJOFഈ൭ğ c.BUDIFS∻4QJFT׻ᾣ֤⃔↾ၞ׭b cႵଧུ+BTNJOF۽ऎॖၛႨb ಯಖ൞၂ЧݺℼĆ Practical

    > Theoretical
  19. cBad -Ớ5%%#%%֥ࢺℚaೂޅለ⇔ݺ֥ 5FTU׻٤ӈֹᾏ੻b cGood - ⃸ồᆀޓॹỚ+BTNJOFഈ൭ğ c.BUDIFS∻4QJFT׻ᾣ֤⃔↾ၞ׭b cႵଧུ+BTNJOF۽ऎॖၛႨb ಯಖ൞၂ЧݺℼĆ Practical

    > Theoretical ၩຓ൬♽ğၹ㬪ޓ؟ၐ↜đሱّ࠭طᅳ֞۷؟⊷ਘa⇥֞ޓ؟b
  20. None
  21. Jasmine is a behavior-driven development framework for testing JavaScript code.

  22. Jasmine is a behavior-driven development framework for testing JavaScript code.

    What is BDD?
  23. Jasmine is a behavior-driven development framework for testing JavaScript code.

    What is BDD? Ṧ൐Ⴈᆀwྛ㬪xĤ۵5%%ཌྷّĤ
  24. Jasmine is a behavior-driven development framework for testing JavaScript code.

    What is BDD? Ṧ൐Ⴈᆀwྛ㬪xĤ۵5%%ཌྷّĤ
  25. What is BDD? http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/

  26. What is BDD? Automation Testing ೘҆౷ http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/

  27. What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ Automation Testing ೘҆౷ http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/

  28. What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ Automation Testing ೘҆౷ 檢查 trim('

    hello') 的回傳值是否為 'hello' http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/
  29. What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ ၂∄༵⇔4QFDᄜℯቔđ֌࢘؇∻∽م҂๝ č္⇝൞4ZTUFN"OBMZ[FS֥࢘؇Ĥ Automation Testing ೘҆౷

    檢查 trim(' hello') 的回傳值是否為 'hello' http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/
  30. What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ ၂∄༵⇔4QFDᄜℯቔđ֌࢘؇∻∽م҂๝ č္⇝൞4ZTUFN"OBMZ[FS֥࢘؇Ĥ Automation Testing ೘҆౷

    檢查 trim(' hello') 的回傳值是否為 'hello' trim ⽅方法應該刪除左側的空⽩白 http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/
  31. What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ ၂∄༵⇔4QFDᄜℯቔđ֌࢘؇∻∽م҂๝ č္⇝൞4ZTUFN"OBMZ[FS֥࢘؇Ĥ Automation Testing ೘҆౷

    5%%∻#%%ᄝެ֥൞ӱൔ⁣ὰᆞ⃷ "5%%≣൞ᄝެ㸗௖ℯቔᆞ⃷ 檢查 trim(' hello') 的回傳值是否為 'hello' trim ⽅方法應該刪除左側的空⽩白 http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/
  32. What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ ၂∄༵⇔4QFDᄜℯቔđ֌࢘؇∻∽م҂๝ č္⇝൞4ZTUFN"OBMZ[FS֥࢘؇Ĥ Automation Testing ೘҆౷

    5%%∻#%%ᄝެ֥൞ӱൔ⁣ὰᆞ⃷ "5%%≣൞ᄝެ㸗௖ℯቔᆞ⃷ 檢查 trim(' hello') 的回傳值是否為 'hello' trim ⽅方法應該刪除左側的空⽩白 使⽤用者輸⼊入的密碼不應該以空⽩白開頭 http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/
  33. What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ ၂∄༵⇔4QFDᄜℯቔđ֌࢘؇∻∽م҂๝ č္⇝൞4ZTUFN"OBMZ[FS֥࢘؇Ĥ Automation Testing ೘҆౷

    5%%∻#%%ᄝެ֥൞ӱൔ⁣ὰᆞ⃷ "5%%≣൞ᄝެ㸗௖ℯቔᆞ⃷ ҉Ṧğ"5%%∣ἐ္൞༵Ⴕ4QFD 檢查 trim(' hello') 的回傳值是否為 'hello' trim ⽅方法應該刪除左側的空⽩白 使⽤用者輸⼊入的密碼不應該以空⽩白開頭 http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/
  34. #%%ᆺ൞Ṧℷ֥⇔ቔἀ۬

  35. #%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ *Unit-Style

  36. #%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ *Unit-Style BDD-Style

  37. #%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ suite = new Y.TestSuite('String Functions Tests') suite.add new Y.Test.Case

    name: 'trim() Tests', testTrimWithLeadingWhiteSpace: -> result = trim(' Hello World') Y.Assert.areEqual('Hello World', result) testTrimWithLeadingWhiteSpace: -> result = trim('Hello World ') Y.Assert.areEqual('Hello World', result) *Unit-Style BDD-Style
  38. #%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ suite = new Y.TestSuite('String Functions Tests') suite.add new Y.Test.Case

    name: 'trim() Tests', testTrimWithLeadingWhiteSpace: -> result = trim(' Hello World') Y.Assert.areEqual('Hello World', result) testTrimWithLeadingWhiteSpace: -> result = trim('Hello World ') Y.Assert.areEqual('Hello World', result) describe 'Trim' it 'should trim the leading whitespace', -> result = trim(' Hello World') expect(result).toEqual('Hello World') it 'should trim the trailing whitespace', -> result = trim('Hello World ') expect(result).toEqual('Hello World') *Unit-Style BDD-Style
  39. #%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ suite = new Y.TestSuite('String Functions Tests') suite.add new Y.Test.Case

    name: 'trim() Tests', testTrimWithLeadingWhiteSpace: -> result = trim(' Hello World') Y.Assert.areEqual('Hello World', result) testTrimWithLeadingWhiteSpace: -> result = trim('Hello World ') Y.Assert.areEqual('Hello World', result) describe 'Trim' it 'should trim the leading whitespace', -> result = trim(' Hello World') expect(result).toEqual('Hello World') it 'should trim the trailing whitespace', -> result = trim('Hello World ') expect(result).toEqual('Hello World') *Unit-Style BDD-Style ڿ೿Ἶ֥aಸၞ倛ồaạ5FTUṉӮ4QFD
  40. ݺ࢝⇥đ҂ồĤ

  41. ݺ࢝⇥đ҂ồĤ http://www.slideshare.net/ihower/bdd-style-unit-testing

  42. ݺ࢝⇥đ҂ồĤ http://www.slideshare.net/ihower/bdd-style-unit-testing නॉٚൔ۵∽࿽൞༏༏ཌྷἬ֥

  43. Getting to Know +BTNJOF֥ӈᾖႨم

  44. Getting to Know +BTNJOF֥ӈᾖႨم • Syntax ࠎẒ∽م

  45. Getting to Know +BTNJOF֥ӈᾖႨم • Syntax ࠎẒ∽م • Matchers ᾋҰ≁௹᾵ݔ

  46. Getting to Know +BTNJOF֥ӈᾖႨم • Syntax ࠎẒ∽م • Matchers ᾋҰ≁௹᾵ݔ

    • DOM Support? ∻)5.-ἦ๙
  47. Getting to Know +BTNJOF֥ӈᾖႨم • Syntax ࠎẒ∽م • Matchers ᾋҰ≁௹᾵ݔ

    • DOM Support? ∻)5.-ἦ๙ • loadFixture
  48. Getting to Know +BTNJOF֥ӈᾖႨم • Syntax ࠎẒ∽م • Matchers ᾋҰ≁௹᾵ݔ

    • DOM Support? ∻)5.-ἦ๙ • loadFixture • Spies ڿṉࠇᾄℶ࠻Ⴕٚمࠇ໾ࡱ
  49. Getting to Know +BTNJOF֥ӈᾖႨم • Syntax ࠎẒ∽م • Matchers ᾋҰ≁௹᾵ݔ

    • DOM Support? ∻)5.-ἦ๙ • loadFixture • Spies ڿṉࠇᾄℶ࠻Ⴕٚمࠇ໾ࡱ • Async ٤๝҄ẕ৘
  50. Syntax

  51. Syntax describe 'Trim' ჭࡱ଀Ẁaॖ/FTUFE

  52. Syntax describe 'Trim' ჭࡱ଀Ẁaॖ/FTUFE str = null beforeEach -> str

    = ' Hello World' afterEach -> str = null ૄἠ4QFD⊋ྛభᗥ֥ọቔ
  53. Syntax describe 'Trim' it 'should trim the leading whitespace', ->

    ჭࡱ଀Ẁaॖ/FTUFE ἲ۬䪌ૼ str = null beforeEach -> str = ' Hello World' afterEach -> str = null ૄἠ4QFD⊋ྛభᗥ֥ọቔ
  54. Syntax result = trim(' Hello World') expect(result).toEqual('Hello World') describe 'Trim'

    it 'should trim the leading whitespace', -> ჭࡱ଀Ẁaॖ/FTUFE ἲ۬䪌ૼ .BUDIFS⃷⃾⊷ਘᆞ⃷∻ڎ str = null beforeEach -> str = ' Hello World' afterEach -> str = null ૄἠ4QFD⊋ྛభᗥ֥ọቔ
  55. Syntax result = trim(' Hello World') expect(result).toEqual('Hello World') describe 'Trim'

    it 'should trim the leading whitespace', -> ჭࡱ଀Ẁaॖ/FTUFE ἲ۬䪌ૼ .BUDIFS⃷⃾⊷ਘᆞ⃷∻ڎ ॖႨ xdescribe ࠣ xit ੻Ἶ str = null beforeEach -> str = ' Hello World' afterEach -> str = null ૄἠ4QFD⊋ྛభᗥ֥ọቔ
  56. Matchers ⇼⊈߭ẖᆴ൞ڎᆞ⃷↥↪

  57. Matchers • toEqual • toBe • toBeTruthy • toBeFalsy •

    toContain • toBeDefined • toBeUndefined • toBeNull • toBeNaN • toBeGreaterThan • toBeLessThan • toBeCloseTo • toMatch • toThrow ⇼⊈߭ẖᆴ൞ڎᆞ⃷↥↪
  58. Matchers • toEqual • toBe • toBeTruthy • toBeFalsy •

    toContain • toBeDefined • toBeUndefined • toBeNull • toBeNaN • toBeGreaterThan • toBeLessThan • toBeCloseTo • toMatch • toThrow 可與 not ձ஥൐Ⴈđ২ೂ expect(‘xxx’).not.toContain(‘y’) ⇼⊈߭ẖᆴ൞ڎᆞ⃷↥↪
  59. Matchers DOM Support?

  60. Matchers DOM Support? +BTNJOFᆺ⊦ᇿṦℷ+BWB4DSJQUaỚᧄ%0.❣↥಩ޅᆦჱb

  61. Matchers DOM Support? +BTNJOFᆺ⊦ᇿṦℷ+BWB4DSJQUaỚᧄ%0.❣↥಩ޅᆦჱb ೂݔ໡ⁿ႗൞ေṦℷa২ೂ$MBTT/BNFğ

  62. Matchers DOM Support? it 'should have .btn-save class', -> html

    = '<button class="btn btn-save">Save with Changes</button>' el = document.createElement('div') el.innerHTML = html expect(el.hasClassName('btn-save')).toBeTruthy() +BTNJOFᆺ⊦ᇿṦℷ+BWB4DSJQUaỚᧄ%0.❣↥಩ޅᆦჱb ೂݔ໡ⁿ႗൞ေṦℷa২ೂ$MBTT/BNFğ
  63. Matchers DOM Support? it 'should have .btn-save class', -> html

    = '<button class="btn btn-save">Save with Changes</button>' el = document.createElement('div') el.innerHTML = html expect(el.hasClassName('btn-save')).toBeTruthy() ӑάઐỮĆط౏IBT$MBTT/BNFὕႵ⏟´ఖཌྷಸྟ↜ⅳ +BTNJOFᆺ⊦ᇿṦℷ+BWB4DSJQUaỚᧄ%0.❣↥಩ޅᆦჱb ೂݔ໡ⁿ႗൞ေṦℷa২ೂ$MBTT/BNFğ
  64. Matchers https://github.com/velesin/jasmine-jquery jasmine-jquery

  65. Matchers https://github.com/velesin/jasmine-jquery jasmine-jquery భ؊Ṧℷն؟὜⃌ട֞%0.֥Ҡቔđ≾สࡱ⃸Ṧℷ⃦⅌؟ਔĆ

  66. it 'should have .btn-save class', -> html = '<button class="btn

    btn-save">Save with Changes</button>' el = document.createElement('div') el.innerHTML = html expect(el.hasClassName('btn-save')).toBeTruthy() Matchers Before: https://github.com/velesin/jasmine-jquery jasmine-jquery భ؊Ṧℷն؟὜⃌ട֞%0.֥Ҡቔđ≾สࡱ⃸Ṧℷ⃦⅌؟ਔĆ
  67. it 'should have .btn-save class', -> html = '<button class="btn

    btn-save">Save with Changes</button>' el = document.createElement('div') el.innerHTML = html expect(el.hasClassName('btn-save')).toBeTruthy() it 'should have .btn-save class', -> btn = $(<button class="btn btn-primary btn-save">Save with Changes</button>') expect(btn).toHaveClass('btn-save') Matchers Before: https://github.com/velesin/jasmine-jquery jasmine-jquery భ؊Ṧℷն؟὜⃌ട֞%0.֥Ҡቔđ≾สࡱ⃸Ṧℷ⃦⅌؟ਔĆ After:
  68. it 'should have .btn-save class', -> html = '<button class="btn

    btn-save">Save with Changes</button>' el = document.createElement('div') el.innerHTML = html expect(el.hasClassName('btn-save')).toBeTruthy() it 'should have .btn-save class', -> btn = $(<button class="btn btn-primary btn-save">Save with Changes</button>') expect(btn).toHaveClass('btn-save') Matchers Before: https://github.com/velesin/jasmine-jquery ิ܂ӑ؟ݺႨ֥%0.ཌྷἬ.BUDIFSTၛࠣ'JYUVSFTᆦჱ jasmine-jquery భ؊Ṧℷն؟὜⃌ട֞%0.֥Ҡቔđ≾สࡱ⃸Ṧℷ⃦⅌؟ਔĆ After:
  69. Matchers loadFixture (in jasmine-jquery)

  70. Matchers loadFixture (in jasmine-jquery) ॖϜ෮ླ֥)5.-ቓӮỒ৫֥'JYUVSFẵσđေႨℭᄜၛՎٚم≘ೆ

  71. it 'should have .btn-save class', -> loadFixture('button') expect($('.btn')).toHaveClass('btn-save') Matchers loadFixture

    (in jasmine-jquery) ॖϜ෮ླ֥)5.-ቓӮỒ৫֥'JYUVSFẵσđေႨℭᄜၛՎٚم≘ೆ
  72. it 'should have .btn-save class', -> loadFixture('button') expect($('.btn')).toHaveClass('btn-save') Matchers loadFixture

    (in jasmine-jquery) ॖϜ෮ླ֥)5.-ቓӮỒ৫֥'JYUVSFẵσđေႨℭᄜၛՎٚم≘ೆ ὜ಀ≘ೆGJYUVSFTCVUUPOIUNM ॖ܂Ṧℷaቋᾏၞ֥)5.-
  73. it 'should have .btn-save class', -> loadFixture('button') expect($('.btn')).toHaveClass('btn-save') Matchers loadFixture

    (in jasmine-jquery) ॖϜ෮ླ֥)5.-ቓӮỒ৫֥'JYUVSFẵσđေႨℭᄜၛՎٚم≘ೆ ὜ಀ≘ೆGJYUVSFTCVUUPOIUNM ॖ܂Ṧℷaቋᾏၞ֥)5.- ೏CVUUPOIUNMᇏႵՎDMBTT ࣼॖᆰࢤᄝՎ౼֤Ć
  74. it 'should have .btn-save class', -> loadFixture('button') expect($('.btn')).toHaveClass('btn-save') Matchers loadFixture

    (in jasmine-jquery) ॖϜ෮ླ֥)5.-ቓӮỒ৫֥'JYUVSFẵσđေႨℭᄜၛՎٚم≘ೆ ὜ಀ≘ೆGJYUVSFTCVUUPOIUNM ॖ܂Ṧℷaቋᾏၞ֥)5.- ೏CVUUPOIUNMᇏႵՎDMBTT ࣼॖᆰࢤᄝՎ౼֤Ć ၛభ׻҂ᆩ֡≾ἠỌỌQ ᆇ֥ῒ֤'JYUVSFỚభ؊Ṧℷޓᇗေğॖၛٳ ❣ᇗ♶০Ⴈ)5.-᾵ἧ
  75. Spies ᾄ॥ଖἠٚم൞ڎФ⊋ྛ

  76. Spies ᾄ॥ଖἠٚم൞ڎФ⊋ྛ

  77. Spies ᾄ॥ଖἠٚم൞ڎФ⊋ྛ foo = getMsg: (name = 'World') -> "Hello

    #{name}!" say: -> msg = @.getMsg('Spy') alert msg ೂޅ⃷⃾TBZႵ⊋ྛHFU.TH
  78. Spies ᾄ॥ଖἠٚم൞ڎФ⊋ྛ foo = getMsg: (name = 'World') -> "Hello

    #{name}!" say: -> msg = @.getMsg('Spy') alert msg ೂޅ⃷⃾TBZႵ⊋ྛHFU.TH spyOn(foo, 'getMsg') foo.say() expect(foo.getMsg).toHaveBeenCalled() TQZ0O UP)BWF#FFO$BMMFE
  79. Spies

  80. Spies Ấڿ߭ẖᆴ BOE3FUVSO

  81. Spies Ấڿ߭ẖᆴ BOE3FUVSO

  82. Spies Ấڿ߭ẖᆴ spyOn(Camera, 'checkRecording').andReturn(null) BOE3FUVSO

  83. Spies Ấڿ߭ẖᆴ spyOn(Camera, 'checkRecording').andReturn(null) BOE3FUVSO ૼૼႵ὎૫a֌႗൞ေڿ㬪㢻὎૫

  84. Spies Ấڿ߭ẖᆴ spyOn(Camera, 'checkRecording').andReturn(null) BOE3FUVSO Useful for Buggy API ૼૼႵ὎૫a֌႗൞ေڿ㬪㢻὎૫

    ằṦℷᇏႵႨ֞Ⴕ↜ⅳֻ֥೘ٚӱൔa ֌୆Ⴛ҂མቓ.PDLđ≾ӑݺႨ
  85. Spies Ấڿ߭ẖᆴ spyOn(Camera, 'checkRecording').andReturn(null) BOE3FUVSO Useful for Buggy API ૼૼႵ὎૫a֌႗൞ေڿ㬪㢻὎૫

    ằṦℷᇏႵႨ֞Ⴕ↜ⅳֻ֥೘ٚӱൔa ֌୆Ⴛ҂མቓ.PDLđ≾ӑݺႨ
  86. Spies Ấڿ߭ẖᆴ spyOn(Camera, 'checkRecording').andReturn(null) BOE3FUVSO Useful for Buggy API ૼૼႵ὎૫a֌႗൞ေڿ㬪㢻὎૫

    ằṦℷᇏႵႨ֞Ⴕ↜ⅳֻ֥೘ٚӱൔa ֌୆Ⴛ҂མቓ.PDLđ≾ӑݺႨ ὕႵBOE$BMM'BLF KBTNJOFDSFBUF4QZ KBTNJOFDSFBU4QZ'VODUJPO 
  87. Async waitFor, run

  88. Async waitFor, run +BWB4DSJQUႵ⇝؟٤๝֥҄౦㣐ླẕ৘đ২ೂğ൙ࡱaọ὎a≘ೆa⊷ਘẖ℻

  89. Async waitFor, run +BWB4DSJQUႵ⇝؟٤๝֥҄౦㣐ླẕ৘đ২ೂğ൙ࡱaọ὎a≘ೆa⊷ਘẖ℻ # 預設 flag 為 false finished

    = false # 綁定完成後的事件 $form.on('ajax:success') -> finished = true # 製造使⽤用者輸⼊入 $form.find('[name=number]').val('4242424242424242') # 採⽤用 UJS (Rails 的 AJAX) 送出 $form.submit() # 會持續檢查 finished 是否變成 true waitsFor -> finished # 通過 waitFor 才會執⾏行 runs 中的區塊 runs -> expect($form.find('[name=token]').val()).not.toBeFalsy()
  90. Async waitFor, run +BWB4DSJQUႵ⇝؟٤๝֥҄౦㣐ླẕ৘đ২ೂğ൙ࡱaọ὎a≘ೆa⊷ਘẖ℻ # 預設 flag 為 false finished

    = false # 綁定完成後的事件 $form.on('ajax:success') -> finished = true # 製造使⽤用者輸⼊入 $form.find('[name=number]').val('4242424242424242') # 採⽤用 UJS (Rails 的 AJAX) 送出 $form.submit() # 會持續檢查 finished 是否變成 true waitsFor -> finished # 通過 waitFor 才會執⾏行 runs 中的區塊 runs -> expect($form.find('[name=token]').val()).not.toBeFalsy()
  91. Async waitFor, run +BWB4DSJQUႵ⇝؟٤๝֥҄౦㣐ླẕ৘đ২ೂğ൙ࡱaọ὎a≘ೆa⊷ਘẖ℻ # 預設 flag 為 false finished

    = false # 綁定完成後的事件 $form.on('ajax:success') -> finished = true # 製造使⽤用者輸⼊入 $form.find('[name=number]').val('4242424242424242') # 採⽤用 UJS (Rails 的 AJAX) 送出 $form.submit() # 會持續檢查 finished 是否變成 true waitsFor -> finished # 通過 waitFor 才會執⾏行 runs 中的區塊 runs -> expect($form.find('[name=token]').val()).not.toBeFalsy() ∽مЌӻႮഈط༯đὕ⁶4ZOUBY4ZOD֥
  92. Integrating Jasmine with Rails and RequireJS Make it Happen

  93. jasminerice All In One Package for Rails! https://github.com/bradphelan/jasminerice

  94. jasminerice All In One Package for Rails! 3BJMTῘứᆀ㢻Ⴕ๦῾֥ࢶ१đ၂ἠ(FNյປ൬۽Ć https://github.com/bradphelan/jasminerice

  95. jasminerice All In One Package for Rails! ෼Ἵཐ૜ 3BJMTῘứᆀ㢻Ⴕ๦῾֥ࢶ१đ၂ἠ(FNյປ൬۽Ć https://github.com/bradphelan/jasminerice

  96. jasminerice All In One Package for Rails! ෼Ἵཐ૜ Integrate Asset

    Pipeline + jasmine-jquery 3BJMTῘứᆀ㢻Ⴕ๦῾֥ࢶ१đ၂ἠ(FNյປ൬۽Ć https://github.com/bradphelan/jasminerice
  97. /spec/javascripts

  98. ٢ᄝՎଢ仛ָ༯֥4QFD׻὜Ф⊋ྛ֞ /spec/javascripts

  99. ٢ᄝՎଢ仛ָ༯֥4QFD׻὜Ф⊋ྛ֞ /spec/javascripts

  100. ٢ᄝՎଢ仛ָ༯֥4QFD׻὜Ф⊋ྛ֞ /spec/javascripts

  101. http://*.kb.dev/jasmine

  102. http://*.kb.dev/jasmine )5.-3VOOFSğᆰࢤῘ⏟´ఖ஝5FTU$BTF

  103. http://*.kb.dev/jasmine )5.-3VOOFSğᆰࢤῘ⏟´ఖ஝5FTU$BTF

  104. http://*.kb.dev/jasmine )5.-3VOOFSğᆰࢤῘ⏟´ఖ஝5FTU$BTF

  105. $ guard-jasmine

  106. $ guard-jasmine ⃸$-*a↥ࢺ૫֥w1IBOUPN+4⏟´ఖxῲΆྛṦℷ

  107. $ guard-jasmine ⃸$-*a↥ࢺ૫֥w1IBOUPN+4⏟´ఖxῲΆྛṦℷ

  108. $ guard-jasmine ⃸$-*a↥ࢺ૫֥w1IBOUPN+4⏟´ఖxῲΆྛṦℷ

  109. $ guard

  110. $ guard ӻ⇟ᾄ॥đٚь5%%Ῐứ

  111. $ guard ӻ⇟ᾄ॥đٚь5%%Ῐứ

  112. $ guard ӻ⇟ᾄ॥đٚь5%%Ῐứ ಯႵἠ4QFDໃℯቔ

  113. $ guard ӻ⇟ᾄ॥đٚь5%%Ῐứ ಯႵἠ4QFDໃℯቔ ℯቔປṂ

  114. $ guard ӻ⇟ᾄ॥đٚь5%%Ῐứ ಯႵἠ4QFDໃℯቔ ℯቔປṂ $ guard init jasmine

  115. codeship.io

  116. codeship.io ӻ⇟ᆜކğHJUQVTIᗥሱọ஝Ṧℷ

  117. codeship.io ӻ⇟ᆜކğHJUQVTIᗥሱọ஝Ṧℷ

  118. codeship.io ӻ⇟ᆜކğHJUQVTIᗥሱọ஝Ṧℷ ὕ㢻⁛֞+BTNJOFԛṳࣼФCMPDLਔđ((

  119. Jasmine w/ Require.JS

  120. Jasmine w/ Require.JS ೏൞3FRVJSF+4֥ଆ⊾đླၛ"TZOD֥ٚൔ༵≘ೆݦൔῠҌିῘ൓Ṧℷ

  121. Jasmine w/ Require.JS ೏൞3FRVJSF+4֥ଆ⊾đླၛ"TZOD֥ٚൔ༵≘ೆݦൔῠҌିῘ൓Ṧℷ

  122. RESOURCES • [PDF] JavaScript Testing with Jasmine http://it-ebooks.info/book/2085/ • [RailsCasts]

    Testing JavaScript with Jasmine (Revised) http://railscasts.com/episodes/261-testing-javascript-with- jasmine-revised • [Slideshare] How BDD style Unit Testing help you write better test code. http://www.slideshare.net/ihower/bdd-style-unit-testing • [Blog] What is TDD, BDD & ATDD ? | Assert Selenium http://assertselenium.com/2012/11/05/difference-between- tdd-bdd-atdd/
  123. None
  124. Stop Hacking and Start Engineering! from LetsCodeJavascript.com