$30 off During Our Annual Pro Sale. View Details »

Testcontainersでコンテナを使ったテストを実行しよう

H.Naka
June 19, 2022

 Testcontainersでコンテナを使ったテストを実行しよう

JJUG CCC 2022 Spring 6月19日開催
[Track A] 10:25- #jjug_ccc_a
#jjug_ccc
Testcontainersでコンテナを使ったテストを実行しよう

H.Naka

June 19, 2022
Tweet

More Decks by H.Naka

Other Decks in Programming

Transcript

  1. View Slide

  2. w ໊͓લɿͳ͔΍·ͻΖʢͤͪʣ

    5XJUUFS͸ʮͤͪʯ
    w ͓͠͝ͱɿ౎಺๭8FCαʔϏε
    w झຯɿήʔϜͱ͓ञͱࣗసं
    w ӈͷࣸਅ͸(8ʹ૸ͬͨඒϲݪ
    ࣗݾ঺հ

    View Slide

  3. ͜ͷΑ͏ͳ೰Έ͋Γ·ͤΜ͔ʁ
    w ΞϓϦέʔγϣϯΛ࣮ߦ͢Δ؀ڥߏஙͷେྔͷखॱ͕͋Δ
    w ྫ͑͹σʔλϕʔεͷΠϯετʔϧ
    w ΠϯετʔϧΛ׬ྃޙɺςετΛ࣮ߦ͢Δલʹඞཁͳ࡞ۀ
    w ςετσʔλͷσʔλͷ౤ೖ
    w ࠶౓ςετΛ࣮ߦ͢Δ৔߹͸ݩͷঢ়ଶʹ໭͢
    w ࣗಈԽ͸ͦͷ͏͍ͪͨ͠Ͱ͢Ͷɾɾɾʢԕ͍໨ʣ

    View Slide

  4. ͜ͷΑ͏ͳ೰Έ͋Γ·ͤΜ͔ʁ
    w ෳࡶͳࣄલ४උΛࣗಈԽ͢ΔͨΊɺϏϧυ৬ਓ͕εΫϦϓτΛ࡞੒
    w ؤுͬͯߏஙͯ͠΋$*Ͱෆఆظʹ͚͜Δ
    w ݪҼ͸$*؀ڥͰ͔͠ൃੜ͠ͳ͍ṖͷΤϥʔ
    w ͦͷ͏ͪΤϥʔʹͳͬͯ΋୭΋ؾʹ͠ͳ͍ɾɾɾ
    w ৬ਓ͸طʹୀ৬Ͱϝϯςφϯε΋Ͱ͖ͳ͍ɾɾɾ

    View Slide

  5. ͜ͷΑ͏ͳ೰Έ͋Γ·ͤΜ͔ʁ
    w ۤ࿑ͯࣗ͠ಈԽ͚ͨ͠ͲσʔλϕʔεΛ࢖ͬͨςετ͕஗࣮ͯ͘ߦʹ਺े
    ෼ɾɾɾ
    w ͜͏ͳͬͨΒςετΛฒྻͰ࣮ߦ͢Δ͔͠ͳ͍ʂ
    w σʔλͷߋ৽λΠϛϯάͰςετ͕ࣦഊɾɾɾ
    w σʔλϕʔεΛ૿΍ͦ͏ʹ΋ϙʔτ͕ॏෳɾɾɾ

    View Slide

  6. 5FTUDPOUBJOFSTͰղܾͰ͖Δ͔΋ʁ
    w 5FTUDPOUBJOFST͸͜Μͳ೰ΈΛղܾͯ͘͠Ε·͢
    w ηοτΞοϓ͕ͭΒ͍ˠ+BWBͱ%PDLFS͕Πϯετʔϧ͞Ε͍ͯΕ͹
    0,ʂ
    w खॱ͕ͭΒ͍ˠςετΫϥε͔Β࢖༻͢ΔίϯςφΛىಈɺޙย෇͚΋
    ෆཁ
    w ฒྻ࣮ߦ͕ͭΒ͍ˠςετΫϥε͝ͱʹσʔλϕʔεΛ༻ҙʂϙʔτ໰୊
    ΋؆୯ʹղܾ

    View Slide

  7. ຊηογϣϯͷςʔϚ
    w 5FTUDPOUBJOFSTͷಋೖํ๏͔Β4QSJOH#PPU5FTUͰ࣮ߦ·ͰΛ͝঺հ͠·͢
    w ςετର৅͸σʔλϕʔεʢ1PTUHSFTʣΛ࢖ͬͨ8FCΞϓϦέʔγϣϯͰ͢
    w ຊεϥΠυͰ͸ιʔείʔυΛஅยతʹష͍ͬͯ·͕͢ɺ(JUIVCͰಈ͘΋ͷ
    Λެ։͠·͢

    View Slide

  8. w 5FTUDPOUBJOFSTͱ͸ʁ
    w ίϯςφΛىಈ͠Α͏
    w 4QSJOH#PPU5FTUͱͷ࿈ܞ
    ΞδΣϯμ

    View Slide

  9. 5FTUDPOUBJOFSTͱ͸ʁ

    View Slide

  10. 5FTUDPOUBJOFSTͱ͸ʁ
    w +6OJUςετ͔Βܰྔ͔ͭ࢖͍ࣺͯͷ%PDLFSίϯςφΛ࣮ߦ͢ΔϥΠϒϥϦ
    w ໊લؒҧ͑΍͍͢ͷͰ஫ҙ
    w 5FTU$POUBJOFSTʢ❌ɿ$͕େจࣈʣɺ5FTUDPOUBJOFSʢ❌ɿT͕ͳ͍ʣ
    w ͞·͟·ͳ044΍঎༻ϓϩμΫτͷςετͰར༻͞Ε͍ͯ·͢
    w σʔλϕʔεΛར༻ͨ݁͠߹ςετʹ࠷ద
    w ଞʹ΋4FMFOJVNΛར༻ͨ͠6*ड͚ೖΕςετͰ΋࢖͑·͢

    View Slide

  11. Կ͕͍͍ͷ͔ʁ
    w ίϯςφͷ؅ཧͷΈʹಛԽͨ͠ϥΠϒϥϦ
    w ఏڙ͢Δػೳ͕γϯϓϧͳͷͰಋೖʹ͔͔Δֶशίετ͕গͳ͍
    w ެ͕ࣜఏڙ͢ΔϞδϡʔϧͰίϯςφ΋ѻ͍΍͘͢ͳ͍ͬͯ·͢
    w Ϟδϡʔϧʹ͍ͭͯ͸ޙ΄Ͳղઆ͠·͢

    View Slide

  12. ίϯςφΛىಈ͠Α͏

    View Slide

  13. ࣮ߦ४උ
    ඞཁ؀ڥ
    w %PDLFS🐳
    w WҎ্
    w 8JOEPXTͷαϙʔτ͸ϕετΤϑΥʔτ
    w +BWBͷόʔδϣϯʹ͍ͭͯ͸هࡌ͸͋Γ·ͤΜ͕ɺҎ্Ͱ͋Ε͹ಈ͘ͱࢥ͍
    ·͢

    View Slide

  14. ࣮ߦ४උ
    ϓϩδΣΫτ࡞੒
    w ࠓճ͸4QSJOHͷΞϓϦέʔγϣϯͷςετΛ࣮ߦ͢Δͷ͕ΰʔϧͳͷͰɺ
    4QSJOH*OJUJBMJ[S͔ΒϓϩδΣΫτΛ࡞੒͠·͢
    w 5FTUDPOUBJOFST͸4QSJOH*OJUJBMJ[Sʹొ࿥͞Ε͍ͯ·͢
    w σʔλϕʔε͸1PTUHSF42-Λબ୒͠·͢

    View Slide

  15. ४උ
    ґଘੑͷ֬ೝ
    w ϓϩδΣΫτΛੜ੒͢ΔͱQPNYNMʹ5FTUDPOUBJOFSTͷґଘੑ͕ͭೖͬͯ
    ͍·͢
    w ্͸+6OJUͱ૊Έ߹ΘͤΔϥΠϒϥϦɺԼ͸1PTUHSF42-ͷϞδϡʔϧΛఏ
    ڙ͢ΔϥΠϒϥϦͰ͢

    org.testcontainers
    junit-jupiter
    test


    org.testcontainers
    postgresql
    test

    View Slide

  16. ิ଍
    Ϟδϡʔϧʹ͍ͭͯ
    w ͜͜·ͰԿճ͔ग़͖͍ͯͯΔʮϞδϡʔϧʯʹ͍ͭͯ؆୯ʹઆ໌͠·͢
    w 5FTUDPOUBJOFST͸(FOFSJD$POUBJOFSͱ͍͏ίϯςφΛ࣮ߦ͢ΔͨΊͷڞ௨
    తͳػೳΛ࣋ͭΫϥεΛఏڙ͠·͢
    w (FOFSJD$POUBJOFSΛܧঝͯ͠ಛఆͷίϯςφʹಛԽͨ͠΋ͷΛϞδϡʔϧͱ
    ݺΜͰ͍·͢

    View Slide

  17. ิ଍
    ϞδϡʔϧʹͰ͖Δ͜ͱ
    w Ϟδϡʔϧ͸(FOFSJD$POUBJOFSͷઃఆ߲໨ʹ௥Ճͯ͠ɺ࣮ߦ͢Δίϯςφݻ
    ༗ͷઃఆΛఏڙ͠·͢
    w 1PTUHSFTϞδϡʔϧͰ͋Ε͹σʔλϕʔεͷઃఆ͕௥Ճ͞Ε͍ͯ·͢
    (FOFSJD$POUBJOFSͷઃఆ߲໨ 1PTUHSFTϞδϡʔϧͷ௥Ճઃఆ߲໨
    ࣮ߦ͢ΔΠϝʔδ σʔλϕʔε໊
    ެ։͢Δϙʔτ ઀ଓϢʔβʔ
    Ϛ΢ϯτ͢ΔϘϦϡʔϜ ύεϫʔυ

    View Slide

  18. ิ଍
    5FTUDPOUBJOFS͕ఏڙ͢ΔϞδϡʔϧʢൈਮʣ
    w 5FTUDPOUBJOFST͕ఏڙ͍ͯ͠ΔϞδϡʔϧʹ͸ҎԼͷΑ͏ͳ΋ͷ͕ἧ͍ͬͯ
    ·͢ʢ͜ΕͰશྔͰ͸ͳ͍Ͱ͢ʣ
    w ఏڙ͞Ε͍ͯͳ͍ίϯςφͰ΋ɺཁ๬͕ଟ͚Ε͹Ϟδϡʔϧͱͯ͠ొ࿥͞ΕΔ
    ͔΋͠Ε·ͤΜ
    3%#$ $BTTBOESB $PDLSPBDI%# .Z42- 0SBDMF9&
    %# .BSJB%# .POHP%# .PDLTFSWFS -PDBM4UBDL
    42-4FSWFS 3BCCJU.2 ,BGLB &MBTUJDTFBSDI 4FMFOJVN

    View Slide

  19. ίϯςφΛ࣮ߦ͠Α͏
    w 5FTUDPOUBJOFSTͰίϯςφΛىಈ͢Δํ๏͸͍͔ͭ͋͘Γ·͢
    w ࠓճ͸4QSJOH#PPU5FTUʹ૊ΈࠐΈ΍͍͢ΞϊςʔγϣϯΛར༻ͨ͠ํ๏Λ঺
    հ͠·͢

    View Slide

  20. ίϯςφΛ࣮ߦ͠Α͏
    ςετΫϥε΁ͷΞϊςʔγϣϯͷ෇༩
    w ίϯςφΛར༻͢ΔςετΫϥεʹ!5FTUDPOUBJOFSTΞϊςʔγϣϯΛ෇༩
    ͠·͢
    w 5FTUDPOUBJOFST͸͜ͷΞϊςʔγϣϯ͕͍ͭͨςετΛ࣮ߦ͢Δࡍʹίϯς
    φΛىಈͯ͘͠Ε·͢
    @Testcontainers
    public class ContainerTest {

    View Slide

  21. ίϯςφΛ࣮ߦ͠Α͏
    ࣮ߦ͢Δίϯςφͷఆٛ
    w ࣮ߦ͢ΔίϯςφΛςετΫϥεͷTUBUJDϑΟʔϧυͰఆٛ͠·͢
    w ΠϯελϯεॳظԽ࣌ʹίϯςφͷઃఆΛߦ͍·͢
    w ࠓճ͸σʔλϕʔε໊ͱ%%-Λఆٛͨ͠42-ϑΝΠϧΛಡΈࠐ·ͤ·͢
    w ෳ਺ͷίϯςφΛಉ࣌ʹىಈ͍ͨ͠৔߹͸ϑΟʔϧυΛෳ਺ఆ͍ٛͯͩ͘͠͞
    @Container
    private static PostgreSQLContainer postgresqlContainer =
    (PostgreSQLContainer)new PostgreSQLContainer("postgres:14.2")
    .withDatabaseName("todo")
    .withInitScript("todo.sql");

    View Slide

  22. ίϯςφΛ࣮ߦ͠Α͏
    ࣮ߦͯ͠ΈΑ͏
    w ίϯςφͷఆ͕ٛऴΘͬͨΒςετΛ࣮ߦ͠·͢
    w ςετΛ࣮ߦ͢Δͱ࠷ॳʹ5FTUDPOUJBOFST͕ఆٛ͞ΕͨίϯςφΛىಈ͠·
    ͢
    w ͦͷޙɺςετϝιου͕ݺͼग़͞Ε·͢
    w ͨͬͨ͜Ε͚ͩ४උͰςετͰར༻͢Δ؀ڥ͕ηοτΞοϓ͞Ε·ͨ͠
    @Test
    void ίϯςφ͕ಈ͍͍ͯΔ͜ͱ() {
    assertTrue(postgresqlContainer.isRunning());
    }

    View Slide

  23. ίϯςφΛ࣮ߦ͠Α͏
    ىಈͨ͠ίϯςφͷޙ࢝຤
    w ىಈͨ͠ίϯςφΛఀࢭͨ͠Γ࡟আͨ͠Γ͢Δॲཧ͸શ෦5FTUDPOUBJOFST͕
    ΍ͬͯ͘Ε·͢
    w ίϯςφɾϘϦϡʔϜɾωοτϫʔΫͷશͯΛ࡟আͯ͘͠Ε·͢
    w ޙ࢝຤͸5FTUDPOUBJOFSTʹ೚ͤͯςετΛॻ͘ͷʹઐ೦͠·͠ΐ͏
    w ༨ஊͰ͕͢ίϯςφΛ࡟আͯ͘͠ΕΔͷ͸Ϧϯΰ͕޷͖ͳࢮਆͰ͢
    w ϦϡʔΫͱ͍͏໊ͷίϯςφ͕ཪͰ͓૟আͯ͠·͢

    View Slide

  24. ίϯςφ࣮ߦͷิ଍
    ϩάϨϕϧͷઃఆʢ೚ҙʣ
    w σϑΥϧτͷϩάϨϕϧͰ͸ɺίϯςφͷ1VMM΍ىಈ࣌ʹϩά͕େྔग़ྗ͞Ε
    ͯ͠·͍·͢
    w ϩά͕ଟ͗͢Δͱײͨ͡৔߹͸5FTUDPOUBJOFSTͷग़ྗϨϕϧΛߜͬͯͩ͘͞
    ͍
    w ެࣜ)1ʹMPHCBDLUFTUYNM͕ఏڙ͞Ε͍ͯ·͢

    View Slide

  25. ίϯςφ࣮ߦͷิ଍
    खಈͰͷίϯςφىಈ
    w ΞϊςʔγϣϯΛར༻͠ͳ͍৔߹ɺOFXͨ͠ίϯςφΠϯελϯεͷTUBSUϝ
    ιουΛݺͼग़͢͜ͱͰίϯςφΛىಈ͢Δ͜ͱ͕Ͱ͖·͢
    w ͜ͷํ๏Ͱىಈͨ͠৔߹Ͱ΋ίϯςφͷޙ࢝຤͸5FTUDPOUBJOFST͕ߦͬͯ͘
    Ε·͢
    // ࣮ߦ͢Δίϯςφͷఆٛ


    PostgreSQLContainer postgresqlContainer =
    (PostgreSQLContainer) new PostgreSQLContainer("postgres:14.2")
    .withDatabaseName("todo")
    .withInitScript("todo.sql");
    // ىಈ


    postgresqlContainer.start();

    View Slide

  26. ίϯςφ࣮ߦͷิ଍
    ˏ$POUBJOFSͷϑΟʔϧυ
    w ࠓճ͸ˏ$POUBJOFSΛTUBUJDϑΟʔϧυʹઃఆͨͨ͠ΊɺςετΫϥεͰͭ
    ͷίϯςφ͕༻ҙ͞Ε·͢
    w ͜ΕΛTUBUJDͰ͸ͳ͘ΠϯελϯεϑΟʔϧυʹ෇༩ͨ͠৔߹ɺςετϝιο
    υ͝ͱʹίϯςφ͕༻ҙ͞Ε·͢

    View Slide

  27. ͜͜·Ͱͷ·ͱΊ
    w ΞϊςʔγϣϯΛ࢖͏͚ͩͰ؆୯ʹίϯςφΛ૊ΈࠐΊΔ͜ͱΛ঺հ͠·ͨ͠
    w ͜ΕͰ4QSJOHͷΞϓϦέʔγϣϯͰར༻͢Δσʔλϕʔεͷ४උ͸੔͍·͠
    ͨ
    w ࣍͸ىಈͨ͠σʔλϕʔεΛ4QSJOH#PPU͔Β࢖͏ํ๏Λ঺հ͠·͢

    View Slide

  28. 4QSJOH#PPU5FTUͱͷ࿈ܞ

    View Slide

  29. ςετ͢ΔΞϓϦέʔγϣϯ
    w ςετର৅ͷΞϓϦέʔγϣϯͱͯ͠ɺ؆୯ͳ5PEPͷΞϓϦΛར༻͠·͢
    w ͜ͷΞϓϦͷ4FSWJDFΫϥεʹରͯ͠ɺ4QSJOH#PPU5FTUΛ࢖ͬͨ݁߹ςετ
    Λ࣮ߦ͠·͢
    @Transactional
    Todo addTodo(String task) {
    return repository.save(new Todo(null,task,"Waiting"));
    }

    View Slide

  30. 4QSJOH#PPU5FTU
    ςετ࣮૷
    w 5FTUDPOUBJOFSTΛઃఆͨ͠ςετΫϥεʹҎԼͷͭΛ௥Ճ͠·͢
    w 4QSJOH#PPU5FTUΞϊςʔγϣϯΛ෇༩͢Δ
    w 4QSJOHͷΞϓϦʹ5FTUDPOUBJOFSTͰىಈͨ͠σʔλϕʔε΁ͷ઀ଓ৘ใΛ
    ࢦఆ͢Δ
    w ςετΫϥεʹςετ͢Δ4FSWJDFΫϥεΛ%*ͯ͠ςετϝιου͔Β࣮ߦ
    w ࠓ·Ͱͷ4QSJOH#PPUςετʹ੺࿮ͰғͬͨॲཧΛ௥Ճ͢Δ͚ͩͰ͢

    View Slide

  31. 4QSJOH#PPU5FTU
    σʔλϕʔεͷ઀ଓఆٛΛઃఆ
    w σʔλϕʔεͷ઀ଓઃఆ͸ɺ%ZOBNJD1SPQFSUZ4PVSDFΛ෇༩ͨ͠ϝιου
    ಺Ͱઃఆ͠·͢
    w ઀ଓ৘ใ͸શͯίϯςφΠϯελϯε͔ΒऔಘՄೳͰ͢
    w ༨ஊͰ͕͢͜ͷΞϊςʔγϣϯ͸4QSJOH͕5FTUDPOUBJOFSTͷͨΊʹ༻ҙͨ͠
    ΋ͷͰ͢
    @DynamicPropertySource
    static void jdbcProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.datasource.url", postgresqlContainer::getJdbcUrl);
    registry.add("spring.datasource.username", postgresqlContainer::getUsername);
    registry.add("spring.datasource.password", postgresqlContainer::getPassword);
    }

    View Slide

  32. 4QSJOH#PPU5FTU
    ςετ࣮ߦ
    w ςετϝιουͰ4QSJOHͷαʔϏεΫϥεΛݺͼग़͢ςετΛهड़͠·͢
    w ςετΛىಈ͢Δͱίϯςφͷσʔλϕʔεͱ4QSJOH͕ىಈ͠ɺςετϝι
    ου಺ͷॲཧ͕͓͜ͳΘΕ·͢
    w ͜ΕͰσʔλϕʔεΛ༻͍ͨΞϓϦέʔγϣϯͷ݁߹ςετ͕ߦ͑·ͨ͠
    @Autowired
    private TodoService service;
    @Test
    @Order(1)
    void addTodo() {
    String task = "🐱ʹ͝൧Λ΋Β͏";
    Todo todo = service.addTodo(task);
    assertEquals(task, todo.task());
    assertEquals("Waiting", todo.status());
    }

    View Slide

  33. 4QSJOH#PPU5FTUิ଍
    &YUFOTJPOΫϥεͰͷ࣮ߦ
    w ࠓճ͸ΞϊςʔγϣϯΛ༻͍ͨγϯϓϧͳํ๏Λ঺հ͠·ͨ͠
    w Ξϊςʔγϣϯͷ৔߹͸֤ΫϥεͰίϯςφͷఆٛΛߦ͏ඞཁ͕͋Γ·͕͢ɺ
    ͜ͷఆٛΛ+6OJUͷ&YUFOTJPOΛ༻͍ͯू໿͢Δํ๏΋͋Γ·͢
    w (JUIVCʹαϯϓϧͷίʔυ͕͋Γ·͢ͷͰࢀরͯ͠Έ͍ͯͩ͘͞
    public class PostgresExtension implements BeforeAllCallback, AfterAllCallback {
    private PostgreSQLContainer> postgresqlContainer;
    @Override
    public void beforeAll(ExtensionContext context) {
    postgresqlContainer =
    (PostgreSQLContainer) new PostgreSQLContainer("postgres:14.2")
    .withDatabaseName("todo");
    postgresqlContainer.start();
    System.setProperty("spring.datasource.url", postgresqlContainer.getJdbcUrl());
    System.setProperty("spring.datasource.username", postgresqlContainer.getUsername());
    System.setProperty("spring.datasource.password", postgresqlContainer.getPassword());
    }

    View Slide

  34. 4QSJOH#PPU5FTUิ଍
    5FTUDPOUBJOFSTͷόʔδϣϯ
    w 4QSJOH*OJUJBMJ[SͰ࡞੒ͨ͠ϓϩδΣΫτͷ5FTUDPOUBJOFSTͷόʔδϣϯ͸
    Ͱ͢
    w Ҏ߱Ͱ௥Ճ͞ΕͨϞδϡʔϧΛར༻͍ͨ͠৔߹͸ɺόʔδϣϯΛࢦఆ
    ͢Δඞཁ͕͋Γ·͢ʢࠓͷ࠷৽͸ʣ
    w ௥Ճ͞ΕͨϞδϡʔϧ͸4FMFOJVNɺLTɺ)JWF.2ͷͭͰ͢

    View Slide

  35. ·ͱΊ

    View Slide

  36. 5FTUDPOUBJOFSTͷಋೖޮՌ
    w ࠓ೔঺հͨ͠ൣғͰ΋5FTUDPOUBJOFST͸ͨ͘͞Μͷ࢓ࣄΛͯ͠·͢
    w σʔλϕʔεͷΠϯετʔϧ͔Β࡟আ·ͰΛςετΫϥεͱີʹ࿈ܞ
    w ʮ+BWBͱ%PDLFS͕͋Ε͹Ͳ͜ͷϚγϯͰ΋੒ޭ͢Δςετʯ͕࡞ΕΔؾ͕͠
    ͖ͯ·ͤΜ͔ʁ
    w গͳ͘ͱ΋ΞϓϦ΍ςετʹؔ܎ͳ͍໰୊Ͱɺ։ൃऀͷखΛ൥ΘͤΔ࣌ؒ΍࿑
    ྗ͸࣮֬ʹݮΓ·͢

    View Slide

  37. ·ͱΊ
    w ೉қ౓ͱൺֱͯ͠5FTUDPOUBJOFSTͷՌͨ͢໾ׂ͸େ͖͍ͱࢥ͍·͢
    w ݸਓతʹ஍ຯ͚ͩͲ࢓ࣄΛ࣮֬ʹ͜ͳͯ͘͠ΕΔ࢓ࣄਓελΠϧͳͱ͜Ζ͕޷
    ͖Ͱ͢
    w ϋϚΓϙΠϯτ͸େମ͸࣮ߦ͢Δίϯςφͷ࢓༷ɾɾɾ
    w ࠓճ͸4QSJOHͱͷ૊Έ߹ΘͤΛ঺հ͠·͕ͨ͠ɺผͷϑϨʔϜϫʔΫʢྫ͑͹
    2VBSLVTʣͱ΋࿈ܞ͢Δ͜ͱ͕Ͱ͖·͢
    w ܁Γฦ͠ʹͳΓ·͕͢ɺςετ؀ڥͷ४උͱ͔໘౗ͳ͜ͱ͸શ෦
    5FTUDPOUBJOFSTʹ೚ͤ·͠ΐ͏ʂ
    w ։ൃऀ͸͍͍ίʔυΛॻ͘͜ͱʹઐ೦͠Α͏ʂ

    View Slide

  38. ࢀߟࢿྉ
    w IUUQTXXXUFTUDPOUBJOFSTPSH
    w ެࣜ)1͸υΩϡϝϯτ͕ॆ࣮
    w (JUIVCͷFYBNQMFʹ͸༷ʑͳϞδϡʔϧͷαϯϓϧ΋͋Γ·͢
    w IUUQTHJUIVCDPNXFOBTTQSJOHUDFYBNQMF
    w ຊηογϣϯͷεϥΠυʹషͬͨίʔυ
    w શͯΛ঺հͰ͖·ͤΜͰͨ͠ͷͰɺ΋͠ΑΖ͚͠Ε͹ࢀর͍ͯͩ͘͠͞

    View Slide

  39. ίϯςφςετֵ໋
    🐳

    View Slide