Upgrade to Pro — share decks privately, control downloads, hide ads and more …

karmaを使ったSPA向けE2Eテスト技法

C2dcf3e2f7861b2ec5d84045273ed5bd?s=47 kyo_ago
February 27, 2017

 karmaを使ったSPA向けE2Eテスト技法

C2dcf3e2f7861b2ec5d84045273ed5bd?s=128

kyo_ago

February 27, 2017
Tweet

Transcript

  1. karmaΛ࢖ͬͨSPA޲͚ E2Eςετٕ๏

  2. ࣗݾ঺հ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ɾ@kyo_ago ɾChatworkͷதͷਓ ɾझຯ͸Local Proxy੡࡞ ɾUnder30͡Όͳ͍ΤϯδχΞ ɾਪ͠API͸Application Cache

  3. ·ͣ͸ँࡑ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  4. ࠓճ௨Γ͕͍͍ͱࢥͬͯʮ&&ςετʯͬͯݴͬͯ·͕͢ *OUFHSBUJPOςετͬͯݴ͏ํ͕ਖ਼֬ͩͬͨΓ͠·͢ɻ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  5. ࠓճ఻͍͑ͨ͜ͱ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  6. 41"ͷςετʹ 8FC%SJWFS͸޲͔ͳ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  7. 8FC%SJWFSͱ͸ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  8. 4FMFOJVN͔Βൃలͨ͠πʔϧ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  9. ϒϥ΢β͝ͱͷυϥΠόͱ ͦͷυϥΠόͱ௨৴͢Δ"1* LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  10. LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ChromeDriver FirefoxDriver IEDriver SafariDriver JSON Wire Protocol

  11. "1*ʹରԠͨ͠ΫϥΠΞϯτΛ ࢖͏͜ͱͰ൚༻తͳςετ͕Ͱ ͖Δ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  12. ྺ࢙͋Δ&&ςετͷ మ൘πʔϧ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ 2004೥։ൃ։࢝

  13. Ͱ͸ͳͥʮ41"ͷςετʹ 8FC%SJWFS͸޲͔ͳ͍ʯͷ͔ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  14. 8FC%SJWFS͸͋͘·Ͱ΋ը໘ ΛભҠ͍ͯ͘͠ʮ8FCαΠτʯ ͷͨΊͷςετπʔϧ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  15. 41"޲͚ͷςετπʔϧͰ͸ͳ ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  16. 41"Λ8FC%SJWFSͰςετ͢ Δͷ͸೉͍͠ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  17. 8FC%SJWFS͸௨ৗͷ։ൃπʔ ϧͱ͸ҧ͏֓೦Ͱಈ͘ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  18. LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ChromeDriver FirefoxDriver IEDriver SafariDriver JSON Wire Protocol ಠࣗϓϩτίϧͷੈք

  19. ௨ৗͷ։ൃϑϩʔͱͷ ࠩҟ͕େ͖͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  20. ྫ͑͹ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  21. /PEFDPOUFYUͱ #SPXTFSDPOUFYUͷ෼அ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ Electron͕ղܾ͔ͨͬͨ͠΍ͭ

  22. let webdriver = require('selenium-webdriver');
 
 let driver = new webdriver.Builder()


    .forBrowser('chrome')
 .build();
 
 driver.executeScript('return 2').then((res) => {
 console.log('returned ', res);
 });
 
 driver.get('https://www.google.co.jp/').then(() => {
 driver.quit();
 }); LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ͚ͩ͜͜#SPXTFSDPOUFYU
  23. %FWFMPQQFS5PPMTͱڝ߹ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ DriverʹΑͬͯ͸

  24. DPOTPMFMPHͷ಺༰͕UFSNJOBM Ͱ͔֬͠ೝͰ͖ͳ͍ ʢ0CKFDUల։ͱ͔ग़དྷͳ͍ʣ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  25. OPEFJOEFYKT UIFOBCMF8FC%SJWFS1SPYZ\ qPX@ $POUSPM'MPX\ QSPQBHBUF6OIBOEMFE3FKFDUJPOT@USVF  BDUJWF2VFVF@ 5BTL2VFVF\ OBNF@5BTL2VFVF 

    qPX@<$JSDVMBS>  UBTLT@<0CKFDU>  JOUFSSVQUT@OVMM  QFOEJOH@OVMM  TVC2@OVMM LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ͜Ε͕ਏ͍ʂ
  26. ը໘ΛભҠ͍ͯ͘͠ʮ8FCα ΠτʯͰ͋Ε͹ͦΕ΄Ͳ໰୊ͳ ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  27. 41"ͷ৔߹ɺ͜ΕΒͷπʔϧ͕ ࢖͑ͳ͍ͷ͸ඇৗʹ೉͍͠ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  28. ·ͨɺ8FC%SJWFS͸ϖʔδͷ ಡΈࠐΈ΍ΫϦοΫޙͷભҠΛ ࣗಈͰ଴ͭػೳ͕͋Δ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  29. var webdriver = require('selenium-webdriver'),
 By = webdriver.By,
 until = webdriver.until;


    
 var driver = new webdriver.Builder()
 .forBrowser('firefox')
 .build();
 driver.get('http://www.google.com/');
 driver.findElement(By.name(‘q')).sendKeys('webdriver');
 driver.findElement(By.name('btnG')).click();
 driver.wait(until.titleIs('webdriver - Google Search'), 1000);
 driver.quit(); LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ଴ͬͯ͘ΕΔ
  30. ͕ɺ41"Ͱ͸௨ৗ͜ΕΒͷػೳ ͸࢖༻͠ͳ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  31. ͦ͜Ͱ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  32. 41"ͷ*OUFHSBUJPOςετʹ͸ ,BSNB LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  33. ,BSNB LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  34. ɾɾɾͬͯ͠·͢ʁ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  35. ࣾ಺Ͱฉ͍ͯΈͨ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  36. ʮLBSNBͷ࿩͢ΔΜͰ͢Αʯ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  37. ʮ͋Εɺ"OHVMBS+4ઐ༻Ͱ͢Α Ͷʁʯ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  38. ʮ·ͩ͋ͬͨΜͰ͔͢ʁʯ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  39. ʮ1SPUSBDUPSʹͳͬͨͱࢥͬ ͯ·ͨ͠ʯ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  40. ɾɾɾ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  41. ΋ͱ΋ͱ"OHVMBS+4ͷςετ༻ ʹ։ൃ͞Εͨςετπʔϧ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  42. ݱࡏ͸ී௨ʹ൚༻తͳπʔϧ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ʢͱݴ͏͔Ή͠ΖAngularͱͷ૬ੑྑ͘ͳ͍Α͏ͳɻɻɻʣ

  43. ·ͩ·ͩ։ൃ͸׆ൃ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ʢ5೔લʹver 1.5.0ެ։ʣ

  44. 1SPUSBDUPSͱ͸ҧ͏ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ʢProtractor͸WebDriverܥʣ

  45. ͬ͘͟Γ͍͏ͱ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  46. ϒϥ΢β্Ͱಈ͘ 6OJUςετϥϯφʔ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  47. describe('Assert', () => {
 it('should true', () => {
 expect(true).toEqual(true);


    });
 }); LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ͜Ε͕ϒϥ΢β্Ͱಈ͘
  48. ࠓճ͸7FSͰ௥Ճ͞Εͨ ػೳΛ࢖ͬͯ*OUFHSBUJPOςε τͷ࢓ํΛ঺հ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  49. DVTUPN$POUFYU'JMF LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  50. ςετΛࢦఆ͞ΕͨIUNM্Ͱ ߦ͏ػೳ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  51. <!DOCTYPE html>
 <html lang="ja">
 <head>
 <script src="context.js"></script>
 <script type="text/javascript">
 %CLIENT_CONFIG%


    window.__karma__.setupContext(window);
 %MAPPINGS%
 </script>
 %SCRIPTS%
 <title>Inside Frontend</title>
 </head>
 <body>
 <script type="text/javascript">
 window.__karma__.loaded();
 </script>
 </body>
 </html> LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ͜͜ʹLBSNBDPOGKTͷ'JMF͕ల։͞ΕΔ ͔͜͜Β࣮ߦΛ։࢝
  52. ·ΔͰαΠτ্Ͱ6OJUUFTUΛ ૸Β͍ͤͯΔ͔ͷΑ͏ʹॻ͚Δ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  53. describe('Document title', () => {
 it('should be', () => {


    expect(document.title).toEqual('Inside Frontend');
 });
 }); LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏
  54. Β͍͘ʂ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  55. ͔͠͠ɻɻɻ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  56. DVTUPN$POUFYU'JMFʹ΋ ෺଍Γͳ͞͸͋Δ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  57. ෺଍Γͳ͞ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  58. ಡΈࠐΈ৔ॴ͕MPDBMIPTU LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  59. LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ෺଍Γͳ͞

  60. ࣮ࡍςετ͍ͨ͠υϝΠϯͰಡ Έࠐ·ΕΔΘ͚Ͱ͸ͳ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  61. LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ͜͏͍ͨ͠

  62. ௐ΂ͯΈͨ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  63. ɻɻɻͪΐͬͱແཧͬΆ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  64. LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ͜͏͢Δ

  65. ໰୊ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  66. ผυϝΠϯ௨৴ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  67. ϒϥ΢βΛͩ·͢ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  68. खॱ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  69. ௨৴ͷॻ͖׵͑ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  70. -PDBMQSPYZΛ࢖͏ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  71. $ npm install --save-dev karma-proxy-plugin LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  72. customContextFile: "custom-context-file.html",
 proxyValidateSSL: false,
 client: { clearContext: false },
 middleware:

    ['proxy'],
 proxy: {
 '/inside-frontend/': {
 'target': 'http://inside-frontend.com/',
 'changeOrigin': true
 }
 }, proxyReq: (proxyReq, req, res, options) => {
 },
 proxyRes: (proxyRes) => {
 }, LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ LBSNBDPOGKT 44-1SPYZ࣌ͷূ໌ॻΤϥʔΛແࢹ ςετ࣮ߦ͝ͱʹ؀ڥΛΫϦΞ͠ͳ͍ LBSNBQSPYZQMVHJO࢖༻ LBSNBඪ४ͷQSPYJFTͰͳ͍͜ͱʹ஫ҙ ૹ৴Πϕϯτ ड৴Πϕϯτ
  73. JOTJEFGSPOUFOE΁ͷ௨৴Λ IUUQJOTJEFGSPOUFOEDPN ΁సૹ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  74. ௨৴ͷ޲͖ઌͷมߋ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  75. IUNM΍+4಺ͷ௨৴ͷ޲͖ઌΛ JOTJEFGSPOUFOEʹ޲͚͍ͨ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ 1Ͱ͸Proxyϓϩηε্ཱ͕͕͚ͪͬͨͩͰɺ ϒϥ΢βͷProxyઃఆΛߦͬͨΘ͚Ͱ͸ͳ͍

  76. let base = document.createElement('base');
 base.href = '/example/';
 document.head.insertAdjacentElement('afterbegin', base); LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

    DVTUPNDPOUFYUpMFIUNM
  77. XMLHttpRequest = () => {/* … */};
 fetch = ()

    => {/* … */}; LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ DVTUPNDPOUFYUpMFIUNM
  78. ؆୯ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  79. ଞʹ͍Ζ͍Ζ͍ͨ͠৔߹ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  80. 3FGFSFSΛॻ͖׵͍͑ͨ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  81. proxyReq: (proxyReq, req, res, options) => {
 proxyReq.setHeader('Referer', 'https://example.com/');
 },

    LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ LBSNBDPOGKT
  82. $PPLJFΛॻ͖׵͍͑ͨ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  83. proxyRes: (proxyRes) => {
 if (proxyRes.headers['set-cookie']) {
 proxyRes.headers['set-cookie'] = proxyRes.headers['set-cookie'].map((cookie)

    => {
 // karma಺͸httpͳͷͰsecureΛফ͢
 return cookie.replace(/\s*secure;?/i, '');
 })
 }
 }, LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ LBSNBDPOGKT
  84. ϦμΠϨΫτઌΛมߋ͍ͨ͠ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  85. proxyRes: (proxyRes) => {
 if (proxyRes.headers['location']) {
 // ϦμΠϨΫτઌΛมߋ
 proxyRes.headers['location']

    = proxyRes.headers['location'].replace(/^https:\/\/ example.com/i, '/example/');
 }
 }, LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ LBSNBDPOGKT
  86. ϩάΠϯ͍ͨ͠ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  87. fetch('/example/login', {
 method: 'POST',
 body: new FormData(document.getElementById('#login'))
 }).then((response) => response.text()).then((text)

    => {
 // ϨεϙϯεʹToken͕͋Ε͹ม਺ʹอଘ
 // Cookie͸อ࣋͞ΕΔ
 window.__karma__.loaded();
 }); LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ DVTUPNDPOUFYUpMFIUNM
  88. ͜͏͍ͬͨํ๏Λ࢖͏͜ͱͰผ υϝΠϯͰಡΈࠐ·ΕΔ໰୊Λ ղফ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  89. QSPYZ3FRɺQSPYZ3FTͷҾ਺ ͸ҎԼࢀর LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ IUUQTHJUIVCDPNOPEFKJUTVOPEFIUUQQSPYZ

  90. ͜͜·ͰདྷΔͱςετΛॻ͘ͷ ͸ඇৗʹ؆୯ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  91. ී௨ʹαΠτ্ͷ%FW5PPMT্ Ͱݕূ͢ΔͷͱมΘΒͳ͍Ϩϕ ϧͰςετ͕ॻ͚Δ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  92. LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ const assert = require("power-assert");
 
 describe('index page', () =>

    {
 it('Google map', () => {
 assert(google.maps);
 });
 it('copyright', () => {
 assert(document.querySelector('.copyright'));
 });
 });
  93. ඇৗʹ͓͢͢Ί LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  94. ࣮ࡍ΍ͬͯΈͯͲ͏͔ͩͬͨ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  95. ςετ͸ඇৗʹॻ͖΍͍͢ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  96. ͨͩɺϒϥ΢βʹىҼ͢Δෆ҆ ఆ͞͸Ͳ͏͠Α͏΋ͳ͔ͬͨ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  97. %0.ͱ͍͏޿Ҭม਺΍͹͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  98. ঢ়ଶͷΫϦΞ͕ࣗ෼ͷ੹೚ʹͳ ΔͷͰਏ͍
 ʢָʹͳΔ෦෼΋͋Δ͚Ͳʣ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  99. ࣗ෼Ͱ੍ޚͰ͖Δൣғ͕޿͕Δ ͷ͸خ͍͠ ʢ8FC%SJWFSͷϒϥοΫϘο Ϋεײ͕ͳ͍ʣ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  100. ͦ΋ͦ΋ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  101. 8FC%SJWFS͸ड͚ೖΕςετ ͷπʔϧͰ͋ͬͯɺ։ൃऀ޲͚ πʔϧͰ͸ͳ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  102. ։ൃ͠ͳ͕Βςετ͢ΔͷͰ͋ Ε͹ผͷํ๏Λݕ౼͢Δํ͕͍ ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  103. ͨͩɺड͚ೖΕςετͳΒ 8FC%SJWFSͷ΄͏͕ྑ͍͔΋ ͠Εͳ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  104. 8FC%SJWFS͸ߴੑೳ͚ͩͲɺ ෆཁͳػೳ΋ଟ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  105. ࠷ޙʹ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  106. &&ςετ͸ ॻ͔ͳ͍ʹӽͨ͜͠ͱ͸ͳ͍ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  107. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  108. ࣭͝໰͸ʁ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏

  109. ࣭͝໰͸ʁ LBSNBΛ࢖ͬͨ41"޲͚ͷ&&ςετٕ๏ ྫ ɾ࣮ߦ࣌ؒ͸ʁ ɾ࣮ࡍͲ͏͍͏;͏ʹಈ͔ͯ͠Δʁ ɾଞͷϝϯόʔͷ൓Ԡ͸ʁ ɾ΍ͬͯΑ͔ͬͨʁ ɾͲ͏͍͏ͱ͖ʹ͓͢͢Ίʁ ɾCIͱͷ࿈ܞ͸ʁ