Slide 1

Slide 1 text

JASMINE JavaScript Testing with Jasmine josephj@Faria Study Group

Slide 2

Slide 2 text

WHY?

Slide 3

Slide 3 text

WHY?

Slide 4

Slide 4 text

WHY? ၹ㬪∉⅂ޓഒĆ

Slide 5

Slide 5 text

WHY?

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

ݤἒӑἱ֥ᇶⅳ

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

• What is Software Testing? • Jasmine • Writing Good Tests • Matchers in depth • More Jasmine Features • Spies • Using Jasmine with Other tools • What’s it like? ݤἒӑἱ֥ᇶⅳ ⦁೮ਔđ∉൞ିᾣ؟ഒĤ

Slide 11

Slide 11 text

ằႵུᇶⅳႄఏ໡֥⇙౿ℭ

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

ಯಖ൞၂ЧݺℼĆ Practical > Theoretical

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

cBad -Ớ5%%#%%֥ࢺℚaೂޅለ⇔ݺ֥ 5FTU׻٤ӈֹᾏ੻b cGood - ⃸ồᆀޓॹỚ+BTNJOFഈ൭ğ c.BUDIFS∻4QJFT׻ᾣ֤⃔↾ၞ׭b cႵଧུ+BTNJOF۽ऎॖၛႨb ಯಖ൞၂ЧݺℼĆ Practical > Theoretical ၩຓ൬♽ğၹ㬪ޓ؟ၐ↜đሱّ࠭طᅳ֞۷؟⊷ਘa⇥֞ޓ؟b

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

What is BDD? http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

What is BDD? ༵⇔4QFDᄜℯቔ 3%֥࢘؇ Automation Testing ೘҆౷ 檢查 trim(' hello') 的回傳值是否為 'hello' http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/

Slide 29

Slide 29 text

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/

Slide 30

Slide 30 text

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/

Slide 31

Slide 31 text

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/

Slide 32

Slide 32 text

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/

Slide 33

Slide 33 text

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/

Slide 34

Slide 34 text

#%%ᆺ൞Ṧℷ֥⇔ቔἀ۬

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

#%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ 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

Slide 38

Slide 38 text

#%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ 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

Slide 39

Slide 39 text

#%%ᆺ൞Ṧℷ֥⇔ቔἀ۬ 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

Slide 40

Slide 40 text

ݺ࢝⇥đ҂ồĤ

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

Getting to Know +BTNJOF֥ӈᾖႨم

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

Syntax

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Syntax describe 'Trim' ჭࡱ଀Ẁaॖ/FTUFE str = null beforeEach -> str = ' Hello World' afterEach -> str = null ૄἠ4QFD⊋ྛభᗥ֥ọቔ

Slide 53

Slide 53 text

Syntax describe 'Trim' it 'should trim the leading whitespace', -> ჭࡱ଀Ẁaॖ/FTUFE ἲ۬䪌ૼ str = null beforeEach -> str = ' Hello World' afterEach -> str = null ૄἠ4QFD⊋ྛభᗥ֥ọቔ

Slide 54

Slide 54 text

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⊋ྛభᗥ֥ọቔ

Slide 55

Slide 55 text

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⊋ྛభᗥ֥ọቔ

Slide 56

Slide 56 text

Matchers ⇼⊈߭ẖᆴ൞ڎᆞ⃷↥↪

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

Matchers DOM Support?

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

Matchers https://github.com/velesin/jasmine-jquery jasmine-jquery

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

Matchers loadFixture (in jasmine-jquery)

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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 ࣼॖᆰࢤᄝՎ౼֤Ć

Slide 74

Slide 74 text

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.-᾵ἧ

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

Spies

Slide 80

Slide 80 text

Spies Ấڿ߭ẖᆴ BOE3FUVSO

Slide 81

Slide 81 text

Spies Ấڿ߭ẖᆴ BOE3FUVSO

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

Async waitFor, run

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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()

Slide 90

Slide 90 text

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()

Slide 91

Slide 91 text

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֥

Slide 92

Slide 92 text

Integrating Jasmine with Rails and RequireJS Make it Happen

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

/spec/javascripts

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

http://*.kb.dev/jasmine

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

$ guard-jasmine

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

$ guard

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

codeship.io

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

Jasmine w/ Require.JS

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

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

Slide 122

Slide 122 text

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/

Slide 123

Slide 123 text

No content

Slide 124

Slide 124 text

Stop Hacking and Start Engineering! from LetsCodeJavascript.com