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
32k
一から始める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.3k
エンジニアメンター制度の効果的な運用を目指して/improve-mentor-system
shibayu36
27
10k
グレードイメージ具体化のため昇格理由を公開する
shibayu36
8
5.7k
新機能作成時に開発ブランチに細かくmergeしていく戦略/merge-strategy-for-new-feature
shibayu36
6
17k
技術ブログを書くことについて/writing-tech-blog
shibayu36
17
26k
はてなと技術研修
shibayu36
1
6.2k
はてなブログチームの開発フローとGitHub
shibayu36
145
76k
課題をテストで解決する
shibayu36
2
2.2k
Fluentd, mongoDB, Kibanaを利用したはてなブログABテストの事例
shibayu36
30
12k
Other Decks in Technology
See All in Technology
プログラム検証入門
riru
6
860
CRTO/CRTL/OSEPの比較・勉強法とAV/EDRの検知実験
chayakonanaika
1
1.1k
四国クラウドお遍路 2024 in 高知 オープニング
yukataoka
0
200
疎通2024
sadnessojisan
5
1k
DroidKaigi 2024 たすけて!ViewModel
mhidaka
5
880
リアルお遍路+SORACOM IoT
ozk009
1
130
Mocking in Rust Applications
taiki45
1
410
Discovering AI Models
picardparis
4
3.9k
Google CloudのLLM活用の選択肢を広げるVertex AIのパートナーモデル
nayuts
0
130
突撃! 隣のAmazon Bedrockユーザー 〜YouはどうしてAWSで?〜
minorun365
PRO
3
380
Developer Experienceを向上させる基盤づくりの取り組み事例集
coconala_engineer
0
140
「自動テストのプラクティスを効果的に学ぶためのカードゲーム」 ( #sqip2024 )
teyamagu
PRO
2
180
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
58
3.4k
Six Lessons from altMBA
skipperchong
26
3.3k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
109
6.9k
Music & Morning Musume
bryan
46
6k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.4k
[RailsConf 2023] Rails as a piece of cake
palkan
48
4.6k
Done Done
chrislema
180
16k
What's in a price? How to price your products and services
michaelherold
242
11k
Facilitating Awesome Meetings
lara
49
5.9k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
225
22k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
227
52k
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ͷϢχοτςετڥ Ұ௨ΓἧͬͨͷͰ͋ͱ͍͖ͬͯ·͠ΐ͏ʂ