Slide 1

Slide 1 text

ֵአ Jest 蝱ᤈ Front-End Unit Test Patrick Wang (patw) 2016/09/26

Slide 2

Slide 2 text

य़姛

Slide 3

Slide 3 text

• Frameworks • Jest च๜戔ਧ • Enzyme • 承ဩ膏憒㳷 • ݱ蟂獤 Test ᯿讨膏ොဩ • ٌ犢ੜದૣ • Coverage

Slide 4

Slide 4 text

Frameworks

Slide 5

Slide 5 text

Frameworks • Unit Test • Jasmine • Mocha, Chai, Sinon • Jest • AVA

Slide 6

Slide 6 text

Assertion Libraries http://reactmad-testing.surge.sh/#/4

Slide 7

Slide 7 text

Frameworks • E2E Test • Casper.js • Protractor • Nightwatch.js • CodeceptJS http://reactmad-testing.surge.sh/#/5

Slide 8

Slide 8 text

Jest च๜戔ਧ

Slide 9

Slide 9 text

ਞ蕕 & 戔ਧ jest & enable babel .babelrc

Slide 10

Slide 10 text

npm scripts package.json 瞱媲緳፡ 叨ኞ coverage 奾ຎ ᪒介手

Slide 11

Slide 11 text

jest configuration package.json import ᪠䕩 ࣁ᪒介手ԏ獮ጱ絑ह伛猋戔ਧ 懯獈 coverage ጱፓ袅 stub scss 䲆礯 介手脻๜ጱ䲆ݷ pattern

Slide 12

Slide 12 text

jest configuration jest/setupTests.js 蝡螲ฎ傶ԧ mock ധ localStorage

Slide 13

Slide 13 text

jest configuration jest/styleStub.js If you want to test classname (CSS Modules)… e.g., styles.foobar === 'foobar' Notice that Proxy is enabled in Node.js v6.* by default; if you are not on Node v6.* yet, make sure you invoke Jest using node --harmony_proxies node_modules/.bin/jest.

Slide 14

Slide 14 text

Enzyme

Slide 15

Slide 15 text

Enzyme • by Airbnb • ੗蕕ԧ React ጱਥො介手ૡٍ牧䢐磪觊犲 jQuery ጱ 螡䢔瑊 API牧介手砰䌃Ӥๅො׎

Slide 16

Slide 16 text

Enzyme - find • ֵአ React TestUtils 螡玲粬ਧፓ秂ጱ API物
 TestUtils.findRenderedDOMComponentWithXXXX • ֵአ Enzyme ݝᥝ component.find(selector) ܨݢ物

Slide 17

Slide 17 text

Enzyme • shallow • render • mount

Slide 18

Slide 18 text

Enzyme - shallow • ੗蕕ਥොጱ shallow rendering • ݝ჉礕ᒫӞ䍅牧犋჉礕ৼزկ • 蝧ଶ盠 • 犋ᓕ child component ጱᤈ傶牧介手᯿讨ݝฎ component ๜蛪

Slide 19

Slide 19 text

Enzyme - render • 觊犲 shallow牧ֵ֕አ Cheerio ୚砻 • 犋ݝ჉礕Ӟ䍅 • API 蚤 shallow च๜ӤӞ膌

Slide 20

Slide 20 text

Enzyme - mount • Full rendering • ፥䋿ጱ DOM ℄讨 • మᥝ介手膏 DOM ጱ԰㵕膏盅媲叨ኞጱ虋玕ҁই Click 盅㳫ᴻԧӞ㮆 list ጱ殻ፓ҂ • మᥝ介手ਠ碉ጱኞ޸蝰๗

Slide 21

Slide 21 text

承ဩ膏憒㳷

Slide 22

Slide 22 text

describe & it 介手脻๜愊ᶎ䛑扗۱ೡӞ㮆౲ग़㮆describe璸牧ྯ㮆describe璸䛑 扗۱ೡӞ㮆౲ग़㮆it璸牐 describe璸圸傶"介手ॺկ"ҁtest suite҂牧蔭纈Ӟ奲ፘ橕ጱ介手牐 ਙฎӞ㮆獢碍牧ᒫӞ㮆㷢碍ฎ介手ॺկጱݷ圸ҁ"ےဩ獢碍ጱ介手 "҂牧ᒫԫ㮆㷢碍ฎӞ㮆䋿褬䁆ᤈጱ獢碍牐 it璸圸傶"介手አֺ"ҁtest case҂牧蔭纈Ӟ㮆㻌加ጱ介手牧ฎ介手ጱ 磧ੜ㻌֖牐ਙ犖ฎӞ㮆獢碍牧ᒫӞ㮆㷢碍ฎ介手አֺጱݷ圸ҁ"1 ے 1 䛑扗缛ෝ 2"҂牧ᒫԫ㮆㷢碍ฎӞ㮆䋿褬䁆ᤈጱ獢碍牐 http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

Slide 23

Slide 23 text

describe & it http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html import add from './add'; import { expect } from 'chai'; describe('ےဩ獢碍ጱ介手', function () { it('1 ے 1 䛑扗缛ෝ 2', function () { expect(add(1, 1)).to.be.equal(2); }); });

Slide 24

Slide 24 text

expect ಅ蘎"䥁᥺"牧疰ฎڣ䥁რ嘨ጱ䋿褬䁆ᤈ奾ຎ膏毆๗奾ຎ ฎ玽Ӟ膌牧ইຎ犋Ӟ膌疰瞦ڊӞ㮆梊藮牐 http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html expect(add(1, 1)).to.be.equal(2);

Slide 25

Slide 25 text

Jest ൉׀ጱ API • describe, it • xdescribe, xit - 䧙碻᪡螂介手碻ֵአ • fit - 㰍᪒種ྦྷ介手 • beforeEach - ࣁྯ㮆介手ԏ獮᮷䁆ᤈ • afterEach - ࣁྯ㮆介手ԏ盅᮷䁆ᤈ http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

Slide 26

Slide 26 text

Jest ൉׀ጱ API • expect • .toBe(value) • .not • .toBeTruthy(), .toBeFalsy() • .toEqual(value) • .toBeCalled() • .toBeCalledWith(arg1, arg2, …) http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

Slide 27

Slide 27 text

䌕礯ֵአጱ介手䲆礯޸ݷ憒㳷 (1/2) • ཿ介手ጱ source ݶ䍅樄Ӟ㮆 __tests__ ፓ袅 • 䲆ݷ物{source 䲆ݷ}.test.js • ݚक़牧ࢩፓ獮ֵአ Ducks: Redux Reducer Bundles ጱ憒塅砰 䌃 redux牧硲 reducers 膏 actions ጱ޸ݷ憒塅ইӥ物 • Actions: {source 䲆ݷ}.actions.test.js • Reducers: {source 䲆ݷ}.reducers.test.js

Slide 28

Slide 28 text

䌕礯ֵአጱ介手䲆礯޸ݷ憒㳷 (2/2) • 舙襑ਧ嬝盄裾ጱ fake data牧ୌ捍ݚक़ୌӞඪ䲆礯硯ᗝ牧㪔 硯ᗝࣁݶӞ䍅牐ٚෝ介手䲆礯Ӿ import 蝱㬵ֵአ牐 • 犥 reselect ጱ newsByCat 傶ֺ牧׎ୌ缏ԧ物 • newsByCat-newsByIdItemData.js物
 newsById 奾䯤ጱ؃虻碘 • newsByCat-makeState.js物
 蜍獈 newsByCat-newsByIdItemData.js ጱ؃虻碘盅牧叨 ڊӞ犩؃ state ׀扗 reselect 介手ֵአ

Slide 29

Slide 29 text

ݱ蟂獤 Test ᯿讨膏ොဩ

Slide 30

Slide 30 text

Component 介手᯿讨 1. Snapshot 介手 (Jest v14.0 ڊ匍) • 穉䌘叨ኞ HTML ጱ奾ຎฎ玽膏Ӥ稞盠ᆙፘᒧ • 犖磪Ոአࣁ reducer • https://facebook.github.io/jest/blog/2016/07/27/jest-14.html/ 2. Simulate ᤈ傶介手 ࢩ種盠ᆙ犖ᥝ蝱 git

Slide 31

Slide 31 text

Component - snapshot snapshot

Slide 32

Slide 32 text

Component - simulate (with mount)

Slide 33

Slide 33 text

Container 介手᯿讨 1. Container 膏ٌ Component ᮷磪ᤩ render ڊ㬵 • 襑አ ۱蚏㬵 2. ᤩ Mock ጱ Component 磪ᤩ call Ӟ稞

Slide 34

Slide 34 text

Container 伛猋؃虻碘牏አ Provider ۱蚏㬵牏㯽獈 context

Slide 35

Slide 35 text

Container ᛔ૩ mock createStore

Slide 36

Slide 36 text

Container Component 磪ᤩ call Ӟ稞 磪 render 奾ຎ

Slide 37

Slide 37 text

Reducer 介手᯿讨 1. 蜍獈 initial state 膏 action 盅牧蜴ࢧ毆๗ጱ state 2. 蝫媲蜍獈 state 膏 action 盅牧膏 snapshots ፘᒧ

Slide 38

Slide 38 text

Reducer

Slide 39

Slide 39 text

Reducer - Snapshot test https://twitter.com/villeimmonen/status/772754403187126272

Slide 40

Slide 40 text

snapshot አෝ reducer snapshot

Slide 41

Slide 41 text

Action 介手᯿讨 1. 䁆ᤈ action 盅牧蜴ࢧ毆๗ጱ object (type 膏 payloads) 2. 瞚Ӥ牧֕Ӿ樌妿螂 mock 螂ጱ ajax

Slide 42

Slide 42 text

Action

Slide 43

Slide 43 text

Action - mock ajax (1/4) • nock • mock the HTTP requests
 • redux-mock-store • apply the middleware to a mock store http://redux.js.org/docs/recipes/WritingTests.html#async-action-creators

Slide 44

Slide 44 text

Action - mock ajax (2/4)

Slide 45

Slide 45 text

Action - mock ajax (3/4)

Slide 46

Slide 46 text

Action - mock ajax (4/4) ಩ܻ๜ ajax ጱ蟂犩 mock ധ 犖ݢ犥አ ES7 await/async

Slide 47

Slide 47 text

Reselect 介手᯿讨 1. 懯ᓒ奾ຎ膏毆๗ፘᒧ 2. 蜍獈ፘݶጱ独牧犋䨝᯿碝懯ᓒ (recomputations)

Slide 48

Slide 48 text

Reselect ࣁ beforeEach Ӿ懿஑ jest.resetModules()

Slide 49

Slide 49 text

Router (1/4) 介手᯿讨 1. params / path ፘᒧ 2. property ፘᒧҁই物䢐磪 hideTopAd҂ 3. Component ፘᒧ

Slide 50

Slide 50 text

Router (2/4)

Slide 51

Slide 51 text

Router (3/4)

Slide 52

Slide 52 text

Router (4/4)

Slide 53

Slide 53 text

ٌ犢ੜದૣ

Slide 54

Slide 54 text

jest.mock(module_path, fn) (1/2) • Jest 粬ᜋԏӞ牧虏介手䌕ဳࣁ匍ࣁ介手ጱ秇奲๜蛪牧 import ጱ module mock ധ牧螨ع୽段介手Ӿጱ秇 奲牐 • ֕ Jest v15 蚏牧automocking 毆戔ฎ橕ധጱ牐ҁਥ ො藯ก҂

Slide 55

Slide 55 text

jest.mock(module_path, fn) (2/2)

Slide 56

Slide 56 text

jest.resetModules() 嘦狒 import/require ጱ module ䷱磪ᤩ࿱礕牐 蝢ଉ硯ࣁ beforeEach() Ӿ物

Slide 57

Slide 57 text

jest.fn() (1/2) ಩ᒫӣො౲㯽獈ጱ function mock 蚏㬵牧ই種㰍ᥝ介手 ᤩ call ጱ稞碍౲ฎᴫ癲㯽獈ጱ㷢碍ฎ玽ྋ嘦ܨݢ牐 ֺ物ࣁ纷ୗ嘨Ӿ޷ݞԧ ga/piwik ጱ纷ୗ嘨牧֕介手碻䷱磪஠ᥝ
 斉獈 ga牧ݝᥝ jest.fn() mock 蚏㬵疰অ牐

Slide 58

Slide 58 text

jest.fn() (2/2) 介手ݢ犥介扗 mock 螂ጱ function ฎ玽ᤩ call牫
 ᤩ call ጱ碻狡ᴫ癲Ջ讕㷢碍牫 ࣁ beforeEach Ӿአ mockFn.mockClear() 嘦狒ྯ稞᮷ ᯿ᗝ制眲ҁ㯽獈㷢碍牏稞碍҂牐

Slide 59

Slide 59 text

timer ፘ橕 mock (1/3) 朼䌘 timer 犖ݢ犥 mock牧jest.useFakeTimers() Instructs Jest to use fake versions of the standard timer functions (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, setImmediate and clearImmediate). https://facebook.github.io/jest/docs/timer-mocks.html#content

Slide 60

Slide 60 text

timer ፘ橕 mock (2/3) https://facebook.github.io/jest/docs/timer-mocks.html#content

Slide 61

Slide 61 text

timer ፘ橕 mock (3/3) https://facebook.github.io/jest/docs/timer-mocks.html#content

Slide 62

Slide 62 text

Async Test Async/Await Error Handling https://facebook.github.io/jest/docs/tutorial-async.html#content

Slide 63

Slide 63 text

Coverage

Slide 64

Slide 64 text

Coverage jest 獉ୌ coverage牐౯㮉犖ࣁ package.json 戔ਧঅ script ԧ牐 䨝礬硁 package.json Ӿ jest.collectCoverageFrom 戔ਧጱፓ袅塅瑻懯ᓒ coverage牐
 叨ኞ蝡䰬ጱ奾ຎ物

Slide 65

Slide 65 text

Coverage 犖䨝ࣁ coverage/ ፓ袅ҁ毆戔҂Ӿ叨ኞ HTML 粚ጱ䁭ޞ物

Slide 66

Slide 66 text

Codecov

Slide 67

Slide 67 text

Codecov

Slide 68

Slide 68 text

㷢ᘍ虻碘

Slide 69

Slide 69 text

㷢ᘍ虻碘 • Give Jest Another Go
 https://medium.com/@jrwebdev/give-jest-another-go-86ca3d00f75 • Unit Test Redux Container Components - Part 1
 http://www.wsbrunson.com/react/redux/test/2016/05/08/testing-redux-containers.html • React.js 101 - React 介手獈槹硽䋊
 https://github.com/kdchang/reactjs101/tree/master/Appendix03 • Testing React Components With Enzyme
 http://codeheaven.io/testing-react-components-with-enzyme/ • 介手໛礍 Mocha 䋿ֺ硽纷
 http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html • Testing Your React (and redux) Applications (Youtube video)
 https://www.youtube.com/watch?v=n49QKIzS_Ik • 獮ᒒ介手ૡٍ墋㻌碉ቘ޾穉斃
 https://github.com/ellisMing/introduction-angular-test#獮ᒒ介手ૡٍ墋㻌碉ቘ޾穉斃

Slide 70

Slide 70 text

Thanks! <(_ _)>