Automatically run the JavaScript test in multiple browsers

Automatically run the JavaScript test in multiple browsers

"Automatically run the JavaScript test in multiple browsers"

Talk about JavaScript Test with Karma TestRunner.

at PHP Conference Kansai 2015
http://conference.kphpug.jp/2015/

----
PHPer だからこそ知っておきたい、JavaScript のテストを複数ブラウザで自動実行する話

PHP は得意だけれど JavaScript はいまいち苦手という人も多いのではないでしょうか。苦手なだけに自分が書いたコードに「このブラウザでは動くけど、あのブラウザだと動かない」などの不安が伴っていませんか? その不安を取り除くために、各ブラウザをそれぞれ起動して、あれこれ手で操作してテストをしていませんか?
また、QUnit や Mocha、Jasmine などのテストフレームワークを利用し、自動テストの環境を構築している場合でも、それぞれのテスト実行ファイルを各ブラウザで開いて実行していませんか?
こういった「各ブラウザを開いて実行する」という行為そのものを自動化し、コードの不安をより早く取り除く環境を「PHPer であり JavaScript に不安を持っていた私」が Karma を使って構築した経験をお話します。
■Karma http://karma-runner.github.io/
※発表内容に PHP のコードは出てきません :-)

8e528456ff66ec543952daa815353a01?s=128

Norio Suzuki

May 30, 2015
Tweet

Transcript

  1. ʙ1)1FS͔ͩΒͦ͜஌͓͖͍ͬͯͨʙ +BWB4DSJQUͷςετΛ ෳ਺ϒϥ΢βͰࣗಈ࣮ߦ͢Δ࿩ 1)1$POGFSFODF,BOTBJ  !TV[VLJ

  2. 4IPVMELOPXCFDBVTFZPVBSF1)1FS "VUPNBUJDBMMZSVOUIF+BWB4DSJQU UFTUJONVMUJQMFCSPXTFST 1)1$POGFSFODF,BOTBJ  !TV[VLJ

  3. "HFOEB w "CPVUNF w 5PEBZTUIFNF w 3FDFOU+BWB4DSJQU w ,BSNB w

    $PODMVTJPO
  4. "CPVUNF w *MPWFTV[VLJBDDPVOU w IUUQTUXJUUFSDPNTV[VLJ w IUUQTHJUIVCDPNTV[VLJ w IUUQTLFZCBTFJPTV[VLJ w

    IUUQTV[VLJUEJBSZOFU
  5. "CPVUNF w *SFDFJWFENFOUJPOTBCPVU46;6,*.0503 $03103"5*0/ FWFSZEBZ

  6. 1BTUQSFTFOUBUJPO IUUQTTQFBLFSEFDLDPNTV[VLJ

  7. .Z1)1DPEFJT -(5.

  8. .Z+BWB4DSJQU DPEFJTOPU-(5.

  9. 5PEBZTUIFNF

  10. ,BSNB IUUQLBSNBSVOOFSHJUIVCJP

  11. 8IFOVTF,BSNB w :PVXBOUUPUFTUDPEFJOSFBMCSPXTFST w :PVXBOUUPUFTUDPEFJONVMUJQMFCSPXTFST EFTLUPQ NPCJMF UBCMFUT FUD 

    w :PVXBOUUPFYFDVUFZPVSUFTUTMPDBMMZEVSJOH EFWFMPQNFOU w :PVXBOUUPFYFDVUFZPVSUFTUTPOBDPOUJOVPVT JOUFHSBUJPOTFSWFS IUUQTHJUIVCDPNLBSNBSVOOFSLBSNB
  12. 8IFOVTF,BSNB w :PVXBOUUPFYFDVUFZPVSUFTUTPOFWFSZTBWF w :PVMPWFZPVSUFSNJOBM w :PVEPOUXBOUZPVS UFTUJOH MJGFUPTVDL w

    :PVXBOUUPVTF*TUBOCVMUPBVUPNBHJDBMMZHFOFSBUF DPWFSBHFSFQPSUT w :PVXBOUUPVTF3FRVJSF+4GPSZPVSTPVSDFpMFT IUUQTHJUIVCDPNLBSNBSVOOFSLBSNB
  13. SFBMCSPXTFST IUUQTLBSNBSVOOFSHJUIVCJPDPOpHCSPXTFSTIUNM

  14. #SPXTFSDPNQBUJCJMJUZ IUUQDBOJVTFDPNGFBUDIBOOFMNFTTBHJOH

  15. ,BSNBEFNP

  16. 3FDFOU +BWB4DSJQU

  17. ,FZXPSETPG3FDFOU+4 ,FZXPSE 1SPEVDUT 4FSWFS4JEF /PEFKTJPKT -BOHVBHF $P⒎FF4DSJQU5ZQF4DSJQU&$."4DSJQU 1BDLBHF OQN#PXFSDPNQPOFOU 5BTL3VOOFS

    (VMQ(SVOU 4UZMFTIFFU -&444BTT -JOU +4-JOU+4)JOU&4)JOU .PEVMF 3FRVJSF+4#SPXTFSJGZ8FC1BDL 'SBNFXPSL "OHVMBS+4#BDLCPOFKT3FBDU 5FTU'SBNFXPSL 26OJU.PDIB+BTNJOF #SPXTFS 1IBOUPN+4$BTQFS+4 5FTU3VOOFS ,BSNB
  18. 4FSWFS4JEF  1BDLBHF

  19. /PEFKT IUUQTOPEFKTPSH

  20. OQN IUUQTXXXOQNKTDPN

  21. 5BTL3VOOFS

  22. (VMQ IUUQHVMQKTDPN

  23. (SVOU IUUQHSVOUKTDPN

  24. (SVOU 1)16OJU IUUQFOHJOFFSJOHDSPDPTKQQPTUHSVOUXBUDIQIQVOJU

  25. .PEVMF

  26. 3FRVJSF+4 IUUQSFRVJSFKTPSH

  27. #SPXTFSJGZ IUUQCSPXTFSJGZPSH

  28. XFCQBDL IUUQXFCQBDLHJUIVCJP

  29. 5SBEJUJPOBMTUZMF <!DOCTYPE html> <html> <head> <!-- Do NOT change this

    order --> <script src="functions.js"></script> <script src="library.js"></script> <script src="app.js"></script> </head> <body> <!-- [snip] --> </body> </html>
  30. 3FRVJSF+4 <!DOCTYPE html> <html> <head> <script src="require.js"></script> <script src="app.js"></script> </head>

    <body> <!-- [snip] --> </body> </html>
  31. 3FRVJSF+4 // app.js require(['functions', 'library'], function(functions, library) { } );

  32. #SPXTFSJGZXFCQBDL <!DOCTYPE html> <html> <head> <script src="app.js"></script> </head> <body> <!--

    [snip] --> </body> </html>
  33. #SPXTFSJGZXFCQBDL // app.js var functions = require('functions'); var library =

    require('library');
  34. &$."4DSJQU // app.js import 'functions' as functions; import 'library' as

    library;
  35. 6OJU5FTU

  36. 5FTUBCMFDPEF

  37. /PU5FTUBCMF <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Karma Samples</title> <script>

    function add(x, y) { return x + y; } </script> </head> <body> <h1>Karma Samples</h1> </body> </html>
  38. &YUFSOBMJTHPPE <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Karma Samples</title> <script

    src="functions.js"></script> </head> <body> <h1>Karma Samples</h1> </body> </html>
  39. .PSF5FTUBCMF w 6TF.PEVMFTZTUFN w 3FRVJSF+4 w #SPXTFSJGZ w XFCQBDL w

    &$."4DSJQU w #VU OPUGPDVTJUUPEBZ
  40. +BTNJOF IUUQKBTNJOFHJUIVCJP

  41. +BTNJOFJOTUBMM % npm install jasmine-core --save-dev

  42. +BTNJOFCBTJD 5FTU3VOOFS )5.- GVODUJPOTKT GVODUJPOT4QFDKT TDSJQUTSDGVODUJPOTKTTDSJQU TDSJQUTSDGVODUJPOT4QFDKTTDSJQU

  43. 4QFD3VOOFSIUNM <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Jasmine Test Runner</title>

    <!-- Jasmine --> <link rel="stylesheet" href="spec/lib/jasmine/jasmine.css"> <script src="spec/lib/jasmine/jasmine.js"></script> <script src="spec/lib/jasmine/jasmine-html.js"></script> <script src="spec/lib/jasmine/boot.js"></script> <!-- Target code --> <script src="src/functions.js"></script> <!-- Test code --> <script src="spec/functionsSpec.js"></script> </head> <body> </body> </html>
  44. GVODUJPOTKT // functions.js function add(x, y) { return x +

    y; }
  45. GVODUJPOT4QFDKT // functionsSpec.js describe('add() tests', function() { it('1 + 2

    equal 3', function() { expect(add(1, 2)).toBe(3); }); it('2 + 2 not equal 5', function() { expect(add(2, 2)).not.toBe(5); }); });
  46. 3VO

  47. 3VO 3VO 3VO

  48. /PUSIZUINJD  8SJUF5FTU  8SJUF$PEF  3FMPBE#SPXTFSˡ#SFBLUIFSIZUIN  3FMPBE#SPXTFSˡ#SFBLUIFSIZUIN 

    3FMPBE#SPXTFSˡ#SFBLUIFSIZUIN  8SJUF5FTU  8SJUF$PEF  3FMPBE#SPXTFSˡ#SFBLUIFSIZUIN  3FMPBE#SPXTFSˡ#SFBLUIFSIZUIN  3FMPBE#SPXTFSˡ#SFBLUIFSIZUIN
  49. ,BSNB IUUQLBSNBSVOOFSHJUIVCJP

  50. 4UFQUPVTF,BSNB w *OTUBMM w 4UBSU,BSNB w 4UBSUUFTUTCZ,BSNB w 8BUDIDIBOHJOHpMFT w

    8SJUFUFTUPSDPEF w %FUFDUDIBOHJOHBpMFCZ,BSNB w 4UBSUUFTUTCZ,BSNB
  51. ,BSNBJOTUBMM % npm install \ karma \ karma-chrome-launcher \ --save-dev

  52. ,BSNBJOJU % ./node_modules/karma/bin/karma init

  53. ,BSNBJOJU Which testing framework do you want to use ?

    Press tab to list possible options. Enter to move to the next question. > jasmine Do you want to use Require.js ? This will add Require.js plugin. Press tab to list possible options. Enter to move to the next question. > no Do you want to capture any browsers automatically ? Press tab to list possible options. Enter empty string to move to the next question. > Chrome >
  54. ,BSNBJOJU What is the location of your source and test

    files ? You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js". Enter empty string to move to the next question. > src/*.js > spec/*Spec.js > Should any of the files included by the previous patterns be excluded ? You can use glob patterns, eg. "**/*.swp". Enter empty string to move to the next question. > Do you want Karma to watch all the files and run the tests on change ? Press tab to list possible options. > yes Config file generated at "/Users/suzuki/work/karma-samples/ karma.conf.js".
  55. ,BSNBDPOpHpMF // karma.conf.js module.exports = function(config) { config.set({ basePath: '',

    frameworks: ['jasmine'], files: [ 'src/*.js', 'spec/*Spec.js' ], exclude: [], preprocessors: {}, reporters: ['progress'], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, browsers: ['Chrome'], singleRun: false }); };
  56. ,BSNBTUBSU % ./node_modules/karma/bin/karma start

  57. ,BSNBTUBSU ᶃ4UBSU,BSNB

  58. ,BSNBTUBSU ᶄPQFO$ISPNFCZ,BSNB ᶅ&YFDVUFUFTUT ᶆ8BUDIpMFT

  59. ,BSNBBEECSPXTFST % npm install \
 karma-safari-launcher \
 karma-firefox-launcher \
 --save-dev

  60. MBVODIFS ,BSNB DISPNFMBVODIFS TBGBSJMBVODIFS pSFGPYMBVODIFS

  61. ,BSNBBEECSPXTFST // karma.conf.js module.exports = function(config) { // [snip] browsers:

    ['Chrome'], // [snip] }); }; // karma.conf.js module.exports = function(config) { // [snip] browsers: ['Chrome', 'Safari', 'Firefox'], // [snip] }); }; .PEJGZDPOpH
  62. ,BSNBBEECSPXTFST

  63. ,BSNBBEECSPXTFST

  64. TQFDJpDCSPXTFS % ./node_modules/karma/bin/karma start \
 --browsers 'Firefox'

  65. VTFPO$*TFWFS

  66. 1IBOUPN+4 IUUQQIBOUPNKTPSH

  67. ,BSNBBEECSPXTFST % npm install \
 karma-phantomjs-launcher \
 --save-dev

  68. LBSNBDPOGKT // karma.conf.js module.exports = function(config) { // [snip] browsers:

    [ 'Chrome', 'Safari', 'Firefox', 'PhantomJS' // added ], // [snip] }); };
  69. PO$*TFSWFS % ./node_modules/karma/bin/karma start \
 --browsers 'PhantomJS'

  70. *OUFSOFU&YQMPSFS

  71. 7JSUVBM#PY IUUQTXXXWJSUVBMCPYPSH

  72. EFWNPEFSOJF IUUQEFWNPEFSOJF

  73. NPEFSOJF PMETUZMF IUUQTXXXNPEFSOJFKBKQ

  74. JFWNT IUUQYEJTTFOUHJUIVCJPJFWNT

  75. 4UFQUPVTF*& w *OTUBMM7JSUVBM#PY w &YFDVUFJFWNT w %PXOMPBE*&7JSUVBM.BDIJOFT w 4FUVQ7.UP7JSUVBM#PY

  76. *OTUBMM7JSUVBM#PY w %PXOMPBEGSPN8FCTJUF w IUUQTXXXWJSUVBMCPYPSHXJLJ%PXOMPBET PS w 6TF)PNFCSFX$BTL % brew

    cask install virtualbox
  77. 6TFJFWNT w %PXOMPBE"MMWFSTJPOT % curl -s https://raw.githubusercontent.com/ xdissent/ievms/master/ievms.sh | bash

    w %PXOMPBE4QFDJpDWFSTJPOT % curl -s https://raw.githubusercontent.com/ xdissent/ievms/master/ievms.sh | env IEVMS_VERSIONS="7 9" bash
  78. 8"3/*/( %0/564&JFWNT)&3& #FDBVTF*&WJSUVBMNBDIJOFTWFSZWFSZMBSHF

  79. %JTLTQBDFPG7.T % du -sh ~/.ievms 43G /Users/suzuki/.ievms

  80. *&TJO7JSUVBM#PY

  81. LBSNBJFWNT % npm install karma-ievms --save-dev

  82. LBSNBDPOGKT // karma.conf.js // [snip] browsers: [ //'Chrome', //'Safari', //'Firefox',

    //'PhantomJS', 'IE7 - WinXP', // added 'IE8 - WinXP', // added 'IE9 - Win7', // added 'IE10 - Win7', // added 'IE11 - Win7' // added ], // [snip]
  83. ,BSNBXJUI*&T

  84. )FBEMFTTNPEF

  85. ,BSNBFYUFOET

  86. 1SFQSPDFTTPST IUUQTXXXOQNKTDPNCSPXTFLFZXPSELBSNBQSFQSPDFTTPS

  87. 1MVHJOT IUUQTXXXOQNKTDPNCSPXTFLFZXPSELBSNBQMVHJO

  88. .ZGVUVSFQMBO w .PCJMF w J04MBVODIFS w "OESPJEMBVODIFS w 3FNPUF#SPXTFST w

    8FC%SJWFSMBVODIFS w #SPXTFS4UBDLMBVODIFS w .JDSPTPGU&EHF w 
  89. $PODMVTJPO

  90. *N)BQQZXJUI,BSNB w *N)BQQZXJUI,BSNB w *FBTFEBTFOTFPGJOTFDVSJUZXJUISFBMCSPXTFSUFTU

  91. :PVXJMMCF)BQQZ w -FUTVTFUIF,BSNBUPHFUIFS w *GZPVVTFUIF,BSNB 
 QMFBTFXSJUFBOBSUJDMFUPZPVSCMPH w *XBOUUPLOPXNPSFJOGPSNBUJPOBCPVU,BSNB

  92. )FMQNF1)1FST  ZPVSFNZPOMZIPQF

  93. 5IBOLZPV