Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
karmaを使ったSPA向けE2Eテスト技法
Search
kyo_ago
February 27, 2017
Programming
5.7k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
karmaを使ったSPA向けE2Eテスト技法
kyo_ago
February 27, 2017
More Decks by kyo_ago
See All by kyo_ago
フロントエンドの リソース管理の話 TechFeed Summit#1 #techfeed #techfeedsummit
kyo_ago
5
2k
TypeScriptでType Match的なことをする話 #すえなみチャンス暑気払い
kyo_ago
1
1.4k
WebReplayから見るWeb開発の未来 #builderscon
kyo_ago
2
1k
今日から始めるbugbounty
kyo_ago
0
320
E2Eという名称の指すもの
kyo_ago
0
2.7k
How to use Scala.js in real world?
kyo_ago
1
2.2k
Other Decks in Programming
See All in Programming
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
590
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
130
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.9k
AIとGame Jamで、ゲームを完成させた話
takahirosaeki
0
120
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
150
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
150
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
280
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
140
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
1
210
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
660
What We Talk About When We Talk About XP
m_seki
2
450
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.7k
Between Models and Reality
mayunak
4
450
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
520
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.3k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Music & Morning Musume
bryan
47
7.4k
Accessibility Awareness
sabderemane
1
210
Into the Great Unknown - MozCon
thekraken
41
2.7k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Transcript
karmaΛͬͨSPA͚ E2Eςετٕ๏
ࣗݾհ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ɾ@kyo_ago ɾChatworkͷதͷਓ ɾझຯLocal Proxy࡞ ɾUnder30͡Όͳ͍ΤϯδχΞ ɾਪ͠APIApplication Cache
·ͣँࡑ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ࠓճ௨Γ͕͍͍ͱࢥͬͯʮ&&ςετʯͬͯݴͬͯ·͕͢ *OUFHSBUJPOςετͬͯݴ͏ํ͕ਖ਼֬ͩͬͨΓ͠·͢ɻ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ࠓճ͍͑ͨ͜ͱ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
41"ͷςετʹ 8FC%SJWFS͔ͳ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
8FC%SJWFSͱ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
4FMFOJVN͔Βൃలͨ͠πʔϧ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ϒϥβ͝ͱͷυϥΠόͱ ͦͷυϥΠόͱ௨৴͢Δ"1* LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ChromeDriver FirefoxDriver IEDriver SafariDriver JSON Wire Protocol
"1*ʹରԠͨ͠ΫϥΠΞϯτΛ ͏͜ͱͰ൚༻తͳςετ͕Ͱ ͖Δ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ྺ࢙͋Δ&&ςετͷ మ൘πʔϧ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ 2004։ൃ։࢝
Ͱͳͥʮ41"ͷςετʹ 8FC%SJWFS͔ͳ͍ʯͷ͔ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
8FC%SJWFS͋͘·Ͱը໘ ΛભҠ͍ͯ͘͠ʮ8FCαΠτʯ ͷͨΊͷςετπʔϧ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
41"͚ͷςετπʔϧͰͳ ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
41"Λ8FC%SJWFSͰςετ͢ Δͷ͍͠ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
8FC%SJWFS௨ৗͷ։ൃπʔ ϧͱҧ͏֓೦Ͱಈ͘ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ChromeDriver FirefoxDriver IEDriver SafariDriver JSON Wire Protocol ಠࣗϓϩτίϧͷੈք
௨ৗͷ։ൃϑϩʔͱͷ ࠩҟ͕େ͖͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ྫ͑ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
/PEFDPOUFYUͱ #SPXTFSDPOUFYUͷஅ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ Electron͕ղܾ͔ͨͬͨͭ͠
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
%FWFMPQQFS5PPMTͱڝ߹ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ DriverʹΑͬͯ
DPOTPMFMPHͷ༰͕UFSNJOBM Ͱ͔֬͠ೝͰ͖ͳ͍ ʢ0CKFDUల։ͱ͔ग़དྷͳ͍ʣ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
OPEFJOEFYKT UIFOBCMF8FC%SJWFS1SPYZ\ qPX@ $POUSPM'MPX\ QSPQBHBUF6OIBOEMFE3FKFDUJPOT@USVF BDUJWF2VFVF@ 5BTL2VFVF\ OBNF@5BTL2VFVF
qPX@<$JSDVMBS> UBTLT@<0CKFDU> JOUFSSVQUT@OVMM QFOEJOH@OVMM TVC2@OVMM LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ͜Ε͕ਏ͍ʂ
ը໘ΛભҠ͍ͯ͘͠ʮ8FCα ΠτʯͰ͋ΕͦΕ΄Ͳͳ ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
41"ͷ߹ɺ͜ΕΒͷπʔϧ͕ ͑ͳ͍ͷඇৗʹ͍͠ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
·ͨɺ8FC%SJWFSϖʔδͷ ಡΈࠐΈΫϦοΫޙͷભҠΛ ࣗಈͰͭػೳ͕͋Δ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
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"͚ͷ&&ςετٕ๏ ͬͯ͘ΕΔ
͕ɺ41"Ͱ௨ৗ͜ΕΒͷػೳ ༻͠ͳ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ͦ͜Ͱ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
41"ͷ*OUFHSBUJPOςετʹ ,BSNB LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
,BSNB LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ɾɾɾͬͯ͠·͢ʁ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ࣾͰฉ͍ͯΈͨ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ʮLBSNBͷ͢ΔΜͰ͢Αʯ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ʮ͋Εɺ"OHVMBS+4ઐ༻Ͱ͢Α Ͷʁʯ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ʮ·ͩ͋ͬͨΜͰ͔͢ʁʯ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ʮ1SPUSBDUPSʹͳͬͨͱࢥͬ ͯ·ͨ͠ʯ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ɾɾɾ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ͱͱ"OHVMBS+4ͷςετ༻ ʹ։ൃ͞Εͨςετπʔϧ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ݱࡏී௨ʹ൚༻తͳπʔϧ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ʢͱݴ͏͔Ή͠ΖAngularͱͷ૬ੑྑ͘ͳ͍Α͏ͳɻɻɻʣ
·ͩ·ͩ։ൃ׆ൃ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ʢ5લʹver 1.5.0ެ։ʣ
1SPUSBDUPSͱҧ͏ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ʢProtractorWebDriverܥʣ
ͬ͘͟Γ͍͏ͱ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ϒϥβ্Ͱಈ͘ 6OJUςετϥϯφʔ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
describe('Assert', () => { it('should true', () => { expect(true).toEqual(true);
}); }); LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ͜Ε͕ϒϥβ্Ͱಈ͘
ࠓճ7FSͰՃ͞Εͨ ػೳΛͬͯ*OUFHSBUJPOςε τͷํΛհ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
DVTUPN$POUFYU'JMF LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ςετΛࢦఆ͞ΕͨIUNM্Ͱ ߦ͏ػೳ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
<!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͕ల։͞ΕΔ ͔͜͜Β࣮ߦΛ։࢝
·ΔͰαΠτ্Ͱ6OJUUFTUΛ Β͍ͤͯΔ͔ͷΑ͏ʹॻ͚Δ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
describe('Document title', () => { it('should be', () => {
expect(document.title).toEqual('Inside Frontend'); }); }); LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
Β͍͘ʂ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
͔͠͠ɻɻɻ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
DVTUPN$POUFYU'JMFʹ Γͳ͋͞Δ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
Γͳ͞ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ಡΈࠐΈॴ͕MPDBMIPTU LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ Γͳ͞
࣮ࡍςετ͍ͨ͠υϝΠϯͰಡ Έࠐ·ΕΔΘ͚Ͱͳ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ͜͏͍ͨ͠
ௐͯΈͨ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ɻɻɻͪΐͬͱແཧͬΆ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ͜͏͢Δ
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ผυϝΠϯ௨৴ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ϒϥβΛͩ·͢ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
खॱ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
௨৴ͷॻ͖͑ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
-PDBMQSPYZΛ͏ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
$ npm install --save-dev karma-proxy-plugin LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
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Ͱͳ͍͜ͱʹҙ ૹ৴Πϕϯτ ड৴Πϕϯτ
JOTJEFGSPOUFOEͷ௨৴Λ IUUQJOTJEFGSPOUFOEDPN సૹ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
௨৴ͷ͖ઌͷมߋ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
IUNM+4ͷ௨৴ͷ͖ઌΛ JOTJEFGSPOUFOEʹ͚͍ͨ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ 1ͰProxyϓϩηε্ཱ͕͕͚ͪͬͨͩͰɺ ϒϥβͷProxyઃఆΛߦͬͨΘ͚Ͱͳ͍
let base = document.createElement('base'); base.href = '/example/'; document.head.insertAdjacentElement('afterbegin', base); LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
DVTUPNDPOUFYUpMFIUNM
XMLHttpRequest = () => {/* … */}; fetch = ()
=> {/* … */}; LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ DVTUPNDPOUFYUpMFIUNM
؆୯ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ଞʹ͍Ζ͍Ζ͍ͨ͠߹ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
3FGFSFSΛॻ͖͍͑ͨ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
proxyReq: (proxyReq, req, res, options) => { proxyReq.setHeader('Referer', 'https://example.com/'); },
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ LBSNBDPOGKT
$PPLJFΛॻ͖͍͑ͨ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
proxyRes: (proxyRes) => { if (proxyRes.headers['set-cookie']) { proxyRes.headers['set-cookie'] = proxyRes.headers['set-cookie'].map((cookie)
=> { // karmahttpͳͷͰsecureΛফ͢ return cookie.replace(/\s*secure;?/i, ''); }) } }, LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ LBSNBDPOGKT
ϦμΠϨΫτઌΛมߋ͍ͨ͠ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
proxyRes: (proxyRes) => { if (proxyRes.headers['location']) { // ϦμΠϨΫτઌΛมߋ proxyRes.headers['location']
= proxyRes.headers['location'].replace(/^https:\/\/ example.com/i, '/example/'); } }, LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ LBSNBDPOGKT
ϩάΠϯ͍ͨ͠ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
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
͜͏͍ͬͨํ๏Λ͏͜ͱͰผ υϝΠϯͰಡΈࠐ·ΕΔΛ ղফ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
QSPYZ3FRɺQSPYZ3FTͷҾ ҎԼࢀর LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ IUUQTHJUIVCDPNOPEFKJUTVOPEFIUUQQSPYZ
͜͜·ͰདྷΔͱςετΛॻ͘ͷ ඇৗʹ؆୯ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ී௨ʹαΠτ্ͷ%FW5PPMT্ Ͱݕূ͢ΔͷͱมΘΒͳ͍Ϩϕ ϧͰςετ͕ॻ͚Δ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ const assert = require("power-assert"); describe('index page', () =>
{ it('Google map', () => { assert(google.maps); }); it('copyright', () => { assert(document.querySelector('.copyright')); }); });
ඇৗʹ͓͢͢Ί LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
࣮ࡍͬͯΈͯͲ͏͔ͩͬͨ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ςετඇৗʹॻ͖͍͢ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ͨͩɺϒϥβʹىҼ͢Δෆ҆ ఆ͞Ͳ͏͠Α͏ͳ͔ͬͨ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
%0.ͱ͍͏Ҭม͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ঢ়ଶͷΫϦΞ͕ࣗͷʹͳ ΔͷͰਏ͍ ʢָʹͳΔ෦͋Δ͚Ͳʣ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ࣗͰ੍ޚͰ͖Δൣғ͕͕Δ ͷخ͍͠ ʢ8FC%SJWFSͷϒϥοΫϘο Ϋεײ͕ͳ͍ʣ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ͦͦ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
8FC%SJWFSड͚ೖΕςετ ͷπʔϧͰ͋ͬͯɺ։ൃऀ͚ πʔϧͰͳ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
։ൃ͠ͳ͕Βςετ͢ΔͷͰ͋ Εผͷํ๏Λݕ౼͢Δํ͕͍ ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
ͨͩɺड͚ೖΕςετͳΒ 8FC%SJWFSͷ΄͏͕ྑ͍͔ ͠Εͳ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
8FC%SJWFSߴੑೳ͚ͩͲɺ ෆཁͳػೳଟ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
࠷ޙʹ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
&&ςετ ॻ͔ͳ͍ʹӽͨ͜͠ͱͳ͍ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
࣭͝ʁ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏
࣭͝ʁ LBSNBΛͬͨ41"͚ͷ&&ςετٕ๏ ྫ ɾ࣮ߦ࣌ؒʁ ɾ࣮ࡍͲ͏͍͏;͏ʹಈ͔ͯ͠Δʁ ɾଞͷϝϯόʔͷԠʁ ɾͬͯΑ͔ͬͨʁ ɾͲ͏͍͏ͱ͖ʹ͓͢͢Ίʁ ɾCIͱͷ࿈ܞʁ