Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
一から始めるJavaScriptユニットテスト/js-unit-test-from-scratch
Search
shibayu36
December 03, 2016
Technology
8
33k
一から始めるJavaScriptユニットテスト/js-unit-test-from-scratch
buiderscon tokyo 2016で発表した資料です
shibayu36
December 03, 2016
Tweet
Share
More Decks by shibayu36
See All by shibayu36
今の生産性改善活動で大切にしている考え方
shibayu36
8
8.4k
エンジニアメンター制度の効果的な運用を目指して/improve-mentor-system
shibayu36
27
10k
グレードイメージ具体化のため昇格理由を公開する
shibayu36
8
5.8k
新機能作成時に開発ブランチに細かくmergeしていく戦略/merge-strategy-for-new-feature
shibayu36
6
17k
技術ブログを書くことについて/writing-tech-blog
shibayu36
17
26k
はてなと技術研修
shibayu36
1
6.3k
はてなブログチームの開発フローとGitHub
shibayu36
145
76k
課題をテストで解決する
shibayu36
2
2.3k
Fluentd, mongoDB, Kibanaを利用したはてなブログABテストの事例
shibayu36
30
12k
Other Decks in Technology
See All in Technology
podman_update_2024-12
orimanabu
1
260
ゼロから創る横断SREチーム 挑戦と進化の軌跡
rvirus0817
2
260
社内イベント管理システムを1週間でAKSからACAに移行した話し
shingo_kawahara
0
180
第3回Snowflake女子会_LT登壇資料(合成データ)_Taro_CCCMK
tarotaro0129
0
180
開発生産性向上! 育成を「改善」と捉えるエンジニア育成戦略
shoota
1
230
1等無人航空機操縦士一発試験 合格までの道のり ドローンミートアップ@大阪 2024/12/18
excdinc
0
150
TSKaigi 2024 の登壇から広がったコミュニティ活動について
tsukuha
0
160
NW-JAWS #14 re:Invent 2024(予選落ち含)で 発表された推しアップデートについて
nagisa53
0
250
ハイテク休憩
sat
PRO
2
120
ガバメントクラウドのセキュリティ対策事例について
fujisawaryohei
0
520
CustomCopを使ってMongoidのコーディングルールを整えてみた
jinoketani
0
220
統計データで2024年の クラウド・インフラ動向を眺める
ysknsid25
2
830
Featured
See All Featured
Designing for Performance
lara
604
68k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
810
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
Why Our Code Smells
bkeepers
PRO
335
57k
How STYLIGHT went responsive
nonsquared
95
5.2k
Transcript
Ұ͔Β࢝ΊΔ JavaScriptϢχοτςετ 2016/12/03 builderscon shiba_yu36
ࣗݾհ • @shiba_yu36 • ͘͠shibayu36 • גࣜձࣾͯͳ • খઆߘαΠτʮΧΫϤϜʯ
ͷJSڥ
ΧΫϤϜͷJSڥ • MVPΞʔΩςΫνϟ • ίϯϙʔωϯτ͝ͱʹϑΝΠϧΛࡉׂ͔͘ • ϑϨʔϜϫʔΫͳ͠ɻDOMૢ࡞jQuery • ReactͳͲʹઓ͠ͳ͔ͬͨ
࠷ॳʹ৺ʹܾΊͨ͜ͱ • શJSϑΝΠϧʹϢχοτςετΛॻ͘։ൃΛ͍ͨ͠ • ࣮ࡍͷΞϓϦέʔγϣϯαʔόͳ͠Ͱͷςετ • ϑϩϯτΤϯυͰఘΊͨ͘ͳ͍
࠷ॳʹ৺ʹܾΊͨ͜ͱ • શJSϑΝΠϧʹϢχοτςετΛॻ͘։ൃΛ͍ͨ͠ • ࣮ࡍͷΞϓϦέʔγϣϯαʔόͳ͠Ͱͷςετ • ϑϩϯτΤϯυͰఘΊͨ͘ͳ͍ ୭Ͱ؆୯ʹςετͰ͖Δ ڥ࡞ΓΛ࢝Ίͨ
ݱࡏͲ͏ͳ͔ͬͨ • શͯͷϑΝΠϧʹϢχοτςετ͕ଘࡏ • ௨ৗͷ͔ؔΒɺDOMૢ࡞ͷ͋Δػೳ·Ͱ • timerɾajaxɾlocalStorageͳͲʹؔΘΔػೳʹ
ϢχοτςετͰಘΒΕͨޮೳ ҆৺ײ ։ൃ ݁߹࣌Ҏ֎ ϒϥβݟͳ͍ͷͰ
͔͠͠… • ڥ༻ҙͷͨΊɺ࠷ॳʹௐΔ͜ͱɾΔ͜ͱ ͕ଟ͔ͬͨ • πʔϧἧ͍ͬͯΔ͕ɺͲ͏͑Α͍͔Θ͔ Γʹ͍͘
͔͠͠… • ڥ༻ҙͷͨΊɺ࠷ॳʹௐΔ͜ͱɾΔ͜ͱ ͕ଟ͔ͬͨ • πʔϧἧ͍ͬͯΔ͕ɺͲ͏͑Α͍͔Θ͔ Γʹ͍͘ ಋೖͷෑډ͕ߴ͍ʂʂʂʂ
ࠓ͍ͨ͜͠ͱ • ϢχοτςετڥΛ࡞ͬͨํ๏Λɺγϯϓϧͳ ྫΛͬͯհ • JSςετͷಋೖͷෑډΛԼ͛ΒΕͨΒ
ࠓ͞ͳ͍͜ͱ • E2Eςετ • ಛఆϑϨʔϜϫʔΫʹґଘͨ͠ςετํ๏ • ReactɺAngular • ࠓճͷํ๏ͰͰ͖Δ͔ʁ
ΞδΣϯμ •JSͷςετπʔϧΛཧ͢Δ •௨ৗͷؔͷϢχοτςετ •DOMૢ࡞͢ΔػೳͷϢχοτςετ •ͦͷଞ༷ʑͳػೳͷςετ
ΞδΣϯμ •JSͷςετπʔϧΛཧ͢Δ •௨ৗͷؔͷϢχοτςετ •DOMૢ࡞͢ΔػೳͷϢχοτςετ •ͦͷଞ༷ʑͳػೳͷςετ
ΞδΣϯμ •JSͷςετπʔϧΛཧ͢Δ •௨ৗͷؔͷϢχοτςετ •DOMૢ࡞͢ΔػೳͷϢχοτςετ
JSͷςετπʔϧΛ ཧ͢Δ
JSͷϢχοτςετ ڥΛ࡞Δͧʂʂ
ʮJavaScript ςετʯ
assert chai Mocha Karma power-assert Jasmine Sinon.js
assert chai Mocha Karma power-assert Jasmine Sinon.js ʁʁʁʁ
ׂ͝ͱʹཧ͠Α͏
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc ಉҰׂͷͷ࠷େ̍ͭͣͭ
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc πʔϧඞཁͳͷΛਵ࣌
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc ຊൃදͰ͜ͷࡾͭΛબ
ΞδΣϯμ •JSͷςετπʔϧΛཧ͢Δ •௨ৗͷؔͷϢχοτςετ •DOMૢ࡞͢ΔػೳͷϢχοτςετ
͔͜͜ΒίʔυΛ͍·͢ • Github: shibayu36/bcon-js-unit-test • src/js/ʹ࣮ɺsrc/js/test/ʹςετ • ޙͰࢀরͯ͠Έ͍ͯͩ͘͞
௨ৗͷؔͷϢχοτςετ branch: assert-mocha PR#1
ςετ͍࣮ͨ͠ function addNumber(num1, num2) { return num1 + num2; }
export { addNumber } src/js/number-util.js
addNumberͷϢχοτςετΛ ࡞ΕΔΑ͏ʹ͠·͠ΐ͏
Ξαʔγϣϯ ʮ˓˓ʯʮxxʯͰ͋Δ assert, chai, power-assert ϑϨʔϜϫʔΫ ςετ࣮ߦ& ศརΩοτҰࣜ Mocha, Jasmine
ςετϥϯφʔ ϒϥβΛհͨ͠ςετ Karma ςετπʔϧ ༻్ʹԠͯ͡ Sinon.js, etc ؔͷςετ -> ΞαʔγϣϯͱϑϨʔϜϫʔΫ
assert • ΞαʔγϣϯϥΠϒϥϦͷதͰҰ൪γϯϓϧ • assert.equal(num, 3, ‘ࣈ͕ਖ਼͍͠’) • deepEqual, throws
• https://www.npmjs.com/package/assert
Mocha • ςετ࣮ߦίϚϯυmocha • ग़ྗܗࣜΓସ͑(ਓ༻, CI༻, etc) • describe, itʹΑΔςετͷάϧʔϐϯά
• ͦͷଞςετศརΩοτҰࣜ
Πϯετʔϧ $ npm install assert $ npm install mocha
babelͷढറ $ npm install babel-preset-es2015 $ npm install babel-register {
"presets": ["es2015"] } .babelrc
import assert from 'assert'; import { addNumber } from "../number-util";
describe('addNumber', function () { it('͠ࢉͰ͖Δ', function () { assert.equal(addNumber(1, 2), 3, '1 + 2 = 3'); }); }); ςετΛॻ͘ src/js/test/number-util.js
ςετΛ࣮ߦ͢Δ $(npm bin)/mocha --require babel-register src/js/test/*.js
σϞ
ςετޭ
ςετࣦഊ
assert ςετJS ࣮JS mochaίϚϯυ ݁Ռग़ྗ ݱࡏͷςετڥ mocha src/js/test/*.js
௨ৗͷؔͷϢχοτ ςετڥΛ࡞Ͱ͖ͨ
͍ΘΏΔModelͷςετ ͜͜·ͰͷڥͰςετͰ͖Δ
ΞδΣϯμ •JSͷςετπʔϧΛཧ͢Δ •௨ৗͷؔͷϢχοτςετ •DOMૢ࡞͢ΔػೳͷϢχοτςετ
DOMૢ࡞͢Δػೳͷ Ϣχοτςετ
DOMૢ࡞͢Δػೳ • Web։ൃΛ͍ͬͯΔͱDOMૢ࡞ආ͚ΒΕͳ͍ • શϑΝΠϧςετͷͨΊɺ͜ͷΑ͏ͳ࣌ςετ ͍ͨ͠
୯७ͳྫ: ϦετʹՃ͢Δػೳ <ul class=“list”> </ul> ul = document.querySelector(‘.list’); appendList(ul, ‘ཁૉ1’);
<ul class=“list”> <li>ཁૉ1</li> </ul>
appendList(ul, ‘ཁૉ2’); <ul class=“list”> <li>ཁૉ1</li> <li>ཁૉ2</li> </ul> <ul class=“list”> <li>ཁૉ1</li>
</ul> ୯७ͳྫ: ϦετʹՃ͢Δػೳ
src/js/append-list.js function appendList(ul, text) { let li = document.createElement('li'); li.textContent
= text; ul.appendChild(li); } export { appendList }
2ͭͷ՝ • Ͳ͏ͬͯDOMૢ࡞Ͱ͖ΔϒϥβͰςετ Λಈ͔͔͢ • Ͳ͏ͬͯػೳΛ୯ମͰςετ͢Δ͔ • ࣮ࡍͷHTMLΛ৴͢ΔαʔόʔΛΘͣʹ
2ͭͷ՝ • Ͳ͏ͬͯDOMૢ࡞Ͱ͖ΔϒϥβͰςετ Λಈ͔͔͢ • Ͳ͏ͬͯػೳΛ୯ମͰςετ͢Δ͔ • ࣮ࡍͷHTMLΛ৴͢ΔαʔόʔΛΘͣʹ
Ͳ͏ͬͯDOMૢ࡞Ͱ͖Δ ϒϥβͰςετΛಈ͔͔͢ ςετϥϯφʔͷKarmaͰղܾ
Karma • CUIίϚϯυ͚ͩͰɺDOM APIͷ͋Δϒϥβ Λհͯ͠ςετ࣮ߦ • ϒϥβͰςετΛ͢ΔͨΊʹɺલॲཧͳͲͷ ػೳఏڙͯ͘͠ΕΔ
ग़ྗ ग़ྗ ग़ྗ લॲཧ ςετJS ίϚϯυ ࣮ߦ
KarmaΛͬͯaddNumberͷ ςετΛϒϥβͰಈ͔͠·͠ΐ͏ branch: karma PR#2
ࠓճChromeͰ ग़ྗ ग़ྗ ग़ྗ લॲཧ ςετJS ίϚϯυ ࣮ߦ
Πϯετʔϧ $ npm install karma $ npm install karma-browserify browserify
babelify watchify $ npm install karma-chrome-launcher $ npm install karma-mocha
Πϯετʔϧ $ npm install karma $ npm install karma-browserify browserify
babelify watchify $ npm install karma-chrome-launcher $ npm install karma-mocha લॲཧ༻ ϒϥβͭͳ͗ࠐΈ ςετϑϨʔϜϫʔΫͭͳ͗ࠐΈ
ॳظઃఆ • $(npm bin)/karma init • ࣭ʹ͍͑ͯ͘ͱɺkarma.conf.js͕Ͱ͖Δ • karma.conf.jsΛฤू •
ϑϨʔϜϫʔΫɺલॲཧɺϒϥβઃఆ
// ϑϨʔϜϫʔΫઃఆ frameworks: ['mocha', 'browserify'], // ςετϑΝΠϧॴ files: [ 'src/js/test/*.js'
], karma.conf.js
// લॲཧઃఆ preprocessors: { 'src/js/test/*.js': ['browserify'] }, browserify: { transform:
['babelify'], }, // ར༻͢Δϒϥβઃఆ browsers: ['Chrome'],
࣮ߦ͢Δ $(npm bin)/karma start
ςετΛϒϥβܦ༝Ͱ ಈ͔ͤͨ
2ͭͷ՝ • Ͳ͏ͬͯDOM APIͷ͋ΔϒϥβͰςετΛ ಈ͔͔͢ • Ͳ͏ͬͯػೳΛ୯ମͰςετ͢Δ͔ • ࣮ࡍͷαʔόʔΛΘͣʹ
Ͳ͏ͬͯػೳΛ ୯ମͰςετ͢Δ͔ branch: dom-api-unit-test PR#3
ΞΠσΞ • ػೳʹඞཁͳ࠷খݶͷHTMLஅยΛಡΈࠐΉ • JSΛ࣮ߦ͠ͳ͕ΒɺHTMLߏͷมԽ͕ҙਤ ௨Γ͔͔֬ΊΔ
ςετલʹ࠷খݶͷHTMLΛ༻ҙ <html><body> <ul class=“list”></ul> </body></html>
JSΛ࣮ߦͯ͠ςετ <html><body> <ul class=“list”></ul> </body></html> ul = document.querySelector(‘.list’); appendList(ul, ‘ཁૉ1’);
<html><body> <ul class=“list”> <li>ཁૉ1</li> </ul> </body></html>
import assert from 'assert'; import { appendList } from '../append-list';
document.body.innerHTML = '<ul class="list"></ul>'; let ul = document.querySelector('.list'); assert.equal(ul.children.length, 0, '࠷ॳ0݅'); appendList(ul, 'ཁૉ1'); assert.equal(ul.children.length, 1, '͕݅1݅ʹ'); assert.equal(ul.children[0].textContent, 'ཁૉ1'); src/js/test/append-list.js
import assert from 'assert'; import { appendList } from '../append-list';
document.body.innerHTML = '<ul class="list"></ul>'; let ul = document.querySelector('.list'); assert.equal(ul.children.length, 0, '࠷ॳ0݅'); appendList(ul, 'ཁૉ1'); assert.equal(ul.children.length, 1, '͕݅1݅ʹ'); assert.equal(ul.children[0].textContent, 'ཁૉ1'); src/js/test/append-list.js ςετલʹHTMLΛೖΕΔ
import assert from 'assert'; import { appendList } from '../append-list';
document.body.innerHTML = '<ul class="list"></ul>'; let ul = document.querySelector('.list'); assert.equal(ul.children.length, 0, '࠷ॳ0݅'); appendList(ul, 'ཁૉ1'); assert.equal(ul.children.length, 1, '͕݅1݅ʹ'); assert.equal(ul.children[0].textContent, 'ཁૉ1'); src/js/test/append-list.js JSΛ࣮ߦ͠ཁૉΛ͔֬ΊΔ
import assert from 'assert'; import { appendList } from '../append-list';
document.body.innerHTML = '<ul class="list"></ul>'; let ul = document.querySelector('.list'); assert.equal(ul.children.length, 0, '࠷ॳ0݅'); appendList(ul, 'ཁૉ1'); assert.equal(ul.children.length, 1, '͕݅1݅ʹ'); assert.equal(ul.children[0].textContent, 'ཁૉ1'); src/js/test/append-list.js
࣮ߦ͢Δ $(npm bin)/karma start
DOMૢ࡞͢Δػೳ ςετͰ͖ͨ
HTMLஅย͕ڊେͩͱςετ͕Ԛ͘… Ұ͚ͭͩ
document.body.innerHTML = '<button id="modal-panel-open-buton">ϞʔμϧදࣔϘ λϯ</button><div class="modal- container"><div class="model-panel">Ϟʔμ ϧͷ༰<button>Ϟʔμϧด͡ΔϘλϯ</ button></div></div>';
document.body.innerHTML = '<button id="modal-panel-open-buton">ϞʔμϧදࣔϘ λϯ</button><div class="modal- container"><div class="model-panel">Ϟʔμ ϧͷ༰<button>Ϟʔμϧด͡ΔϘλϯ</ button></div></div>';
HTMLஅย͕ڊେͩͱςετ͕Ԛ͘… karma-html2js-preprocessor Ұ͚ͭͩ
karma-html2js-preprocessor • karmaͷલॲཧϓϥάΠϯ • HTMLஅยΛϑΝΠϧͰஔ͍͓ͯ͘ͱɺ ؆୯ʹಡΈࠐΈͰ͖Δπʔϧ
Πϯετʔϧ $ npm install karma-html2js-preprocessor
// htmlՃ files: [ 'src/js/test/*.js', 'src/js/test/*.html' ], // લॲཧઃఆʹϓϥάΠϯՃ preprocessors:
{ 'src/js/test/*.js': ['browserify'], 'src/js/test/*.html': ['html2js'] }, karma.conf.js
<ul class="list"> </ul> src/js/test/append-list.html
document.body.innerHTML = __html__['src/js/test/append-list.html']; __html__[‘ϑΝΠϧ໊’]ͰಡΈࠐΊΔΑ͏ʹ
HTMLஅย͕େ͖ͯ͘ ςετ͕Ԛ͘ͳΔ͜ͱ͕ͳ͘ͳͬͨ
σϞ
௨ৗͷؔɺDOMૢ࡞ͷ͋Δػೳ ςετΛ࡞ΕΔڥ͕ʂ ࣮ߦkarma start͚ͩ
CIͰಈ͔͍ͨ͠ • ϒϥβʹphantomjsjsdomΛ͏ • jsdomnode͚ͩͰಈ͘ϔουϨεϒϥβ • --reportersͷࢦఆͰCI༻ͷग़ྗ͕Ͱ͖Δ
ςετJS ࣮JS ςετHTML html2js ࠷ऴߏ karma start
࠷ऴߏ ग़ྗ ग़ྗ ग़ྗ html2js
·ͱΊ • ϢχοτςετڥΛҰ͔Βಋೖ͢Δํ๏ • ௨ৗͷؔͷςετͳΒassert + MochaͰ
·ͱΊ • DOMૢ࡞͢ΔػೳͷςετͳΒɺKarma + HTMLஅยಡΈࠐΈͰ • timerɺajaxɺlocalStorageͳͲͷςετผͷػ ձʹ • 12/5ͷͯͳΤϯδχΞΞυϕϯτΧϨϯμʔͰॻ͖·͢
JSͷϢχοτςετڥ Ұ௨ΓἧͬͨͷͰ͋ͱ͍͖ͬͯ·͠ΐ͏ʂ