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
FODにおけるホーム画面編成のレコメンド
watarukudo
PRO
2
250
ドメイン駆動設計の実践により事業の成長スピードと保守性を両立するショッピングクーポン
lycorptech_jp
PRO
6
710
AWSサービスアップデート 2024/12 Part3
nrinetcom
PRO
0
140
エンジニアリングマネージャー視点での、自律的なスケーリングを実現するFASTという選択肢 / RSGT2025
yoshikiiida
4
3.6k
なぜfreeeはハブ・アンド・スポーク型の データメッシュアーキテクチャにチャレンジするのか?
shinichiro_joya
2
170
Unsafe.BitCast のすゝめ。
nenonaninu
0
190
The future we create with our own MVV
matsukurou
0
2k
あなたの知らないクラフトビールの世界
miura55
0
110
Reactフレームワークプロダクトを モバイルアプリにして、もっと便利に。 ユーザに価値を届けよう。/React Framework with Capacitor
rdlabo
0
110
JAWS-UG20250116_iOSアプリエンジニアがAWSreInventに行ってきた(真面目編)
totokit4
0
130
生成AI × 旅行 LLMを活用した旅行プラン生成・チャットボット
kominet_ava
0
150
iPadOS18でフローティングタブバーを解除してみた
sansantech
PRO
1
120
Featured
See All Featured
Gamification - CAS2011
davidbonilla
80
5.1k
Side Projects
sachag
452
42k
Thoughts on Productivity
jonyablonski
68
4.4k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.3k
Building Your Own Lightsaber
phodgson
104
6.2k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
860
Building Applications with DynamoDB
mza
93
6.2k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
230
52k
The Pragmatic Product Professional
lauravandoore
32
6.4k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
127
18k
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ͷϢχοτςετڥ Ұ௨ΓἧͬͨͷͰ͋ͱ͍͖ͬͯ·͠ΐ͏ʂ