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

サバンナ便り〜自動テストに関する連載で得られた知見のまとめ〜

 サバンナ便り〜自動テストに関する連載で得られた知見のまとめ〜

2023/03/03(金)
Forkwell エンジニア文化祭 2023

Takuto Wada
PRO

March 03, 2023
Tweet

More Decks by Takuto Wada

Other Decks in Programming

Transcript

  1. ࿨ా୎ਓʢ[email protected]ʣ
    αόϯφศΓ
    ࣗಈςετʹؔ͢Δ࿈ࡌͰಘΒΕͨ஌ݟͷ·ͱΊ
    📷🙆 🙆 'PSLXFMMจԽࡇ@"
    .BS

    View Slide

  2. t-wada

    t_wada

    twada
    📷🙆 📹🙅
    🙆
    ࣗݾ঺հ
    #Forkwell文化祭_A

    View Slide

  3. ٕज़ॻͷग़൛ʹؔΘ͍ͬͯ·͢

    View Slide

  4. αόϯφศΓʜʜʁ

    View Slide

  5. IUUQTUXBEBIBUFOBCMPHKQFOUSZXEQSFTTTBWBOOBDPMVNO
    8%#13&44ʹίϥϜΛ࿈ࡌ͍ͯ͠·͢

    View Slide

  6. IUUQTUXBEBIBUFOBCMPHKQFOUSZXEQSFTTTBWBOOBDPMVNO
    8%#13&44ʹίϥϜΛ࿈ࡌ͍ͯ͠·͢

    View Slide

  7. ΑΖ͓͘͠ئ͍͠·͢
    📷🙆 🙆 'PSLXFMMจԽࡇ@"

    View Slide

  8. "HFOEB࿈ࡌ֤ճͷςʔϚ
    ֶश༻ςετ
    ِཅੑͱِӄੑ
    ςεταΠζ
    ςετμϒϧ
    ςετϐϥϛου
    🦁

    View Slide

  9. ֶͼΛࣗಈςετͱͯ͠ॻ͘
    ଈ࣌ੑͱ࠶ݱੑ

    View Slide

  10. ֶशྫ1)1ͷ%BUF5JNFͱ%BUF5JNF*NNVUBCMF
    IUUQTXXXQIQOFUNBOVBMKBDMBTTEBUFUJNFJNNVUBCMFQIQ

    View Slide

  11. /**


    * @test


    * @group learning


    */


    public function DateTimeのaddは自身の状態を変更しつつ自身を返す(): void


    {


    $halloween = new \DateTime('2021-10-31');


    $oneYear = \DateInterval::createFromDateString('1 year');


    $halloween2022 = $halloween->add($oneYear);


    $this->assertSame($halloween, $halloween2022);


    $this->assertEquals('2022-10-31', $halloween->format('Y-m-d'));


    $this->assertEquals('2022-10-31', $halloween2022->format('Y-m-d'));


    }


    /**


    * @test


    * @group learning


    */


    public function DateTimeImmutableのaddは自身の状態を変更せず新しい状態を伴う新しいインスタンスを返す(): void


    {


    $halloween = new \DateTimeImmutable('2021-10-31');


    $oneYear = \DateInterval::createFromDateString('1 year');


    $halloween2022 = $halloween->add($oneYear);


    $this->assertNotSame($halloween, $halloween2022);


    $this->assertEquals('2021-10-31', $halloween->format('Y-m-d'));


    $this->assertEquals('2022-10-31', $halloween2022->format('Y-m-d'));


    }
    %BUF5JNFͱ%BUF5JNF*NNVUBCMFͷҧ͍Λֶशςετʹ͢Δ
    ֶशςετʢֶͼ͕໨తͷςετʣΛ
    ݟ෼͚ΔͨΊʹ
    MFBSOJOHλάΛ͚͍ͭͯ·͢
    ֶ͕͜͜ͼ
    ֶ͕͜͜ͼ

    View Slide

  12. ٙ໰Λςετʹ͢Δ

    View Slide

  13. /**


    * @test


    * @group learning


    */


    public function 同じ時刻を指している場合はタイムゾーンが異なっても等価とみなされる(): void


    {


    $utc = new DateTimeImmutable('2021-12-24T15:00:00', new DateTimeZone('UTC'));


    $jst = new DateTimeImmutable('2021-12-25T00:00:00', new DateTimeZone('Asia/Tokyo'));


    $this->assertTrue($utc == $jst);


    }
    ٙ໰Λςετʹ͢Δ
    ςετʹฉ͍ͯΈΕ͹͍͍

    View Slide

  14. ڻ͖Λςετʹ͢Δ
    ྫ͑͹ʜʜ

    View Slide

  15. ί
    ϯ
    ε
    τ
    ϥ
    Ϋ
    λ
    ͸


    Ұ
    ճ
    ͠
    ͔
    ݺ
    ΂
    ͳ
    ͍
    ͱ



    ֮
    ͠
    ͯ
    ͍
    ͨ
    ʁ















    Ұ


    ͍
    ͭ
    ͔
    Β
    ŠŠŠŠŠŠ

    View Slide

  16. /**


    * @test


    * @group learning


    */


    public function コンストラクタをもう一度呼ぶと破壊的変更ができてしまう(): void


    {


    $dt = new \DateTimeImmutable('2021-12-24');


    $this->assertSame('2021-12-24', $dt->format('Y-m-d'));


    $dt->__construct('2022-01-01');


    $this->assertSame('2022-01-01', $dt->format('Y-m-d'));


    }
    ͳΜʜʜͩͱʜʜʂʁ

    ໌ࣔతʹݺ΂ͯ͠·͏
    ༨ஊ͜ͷςετίʔυΛ͖͔͚ͬʹQIQTSDʹJTTVFͱͯ͠ใࠂ͞Εɺٞ࿦͕ߦΘΕ·ͨ͠ɻ
    IUUQTHJUIVCDPNQIQQIQTSDJTTVFT
    ༨ஊ͜ͷςετίʔυΛ͖͔͚ͬʹ੩తղੳπʔϧ1)14UBOͱ1TBMNʹػೳఏҊ͕ߦΘΕɺ
    1)14UBOʹ[email protected]͞Μ͕࡞੒ͨ͠QVMMSFRVFTU͕࠾༻͞ΕɺϦϦʔε͞Ε·ͨ͠ɻ
    IUUQTHJUIVCDPNQIQTUBOQIQTUBOTSDQVMM

    View Slide

  17. "HFOEB࿈ࡌ֤ճͷςʔϚ
    ֶश༻ςετ
    ِཅੑͱِӄੑ
    ςεταΠζ
    ςετμϒϧ
    ςετϐϥϛου
    🦁

    View Slide

  18. ࣗಈςετͷ৴པੑΛ
    Ή͠͹Ήݱ৅Λཧղ͢Δ

    View Slide

  19. ςετࣗಈԽͱاۀͷۀ੷ͷҼՌؔ܎
    IUUQTXXXBNB[PODPKQEQ
    ςετͷࣗಈԽʹ͓͍ͯɺ*5ύϑΥʔϚϯεͷ༧ଌई౓ͱͳΓ͏Δ
    ͜ͱ͕൑໌ͨ͠ͷ͸࣍ͷͭ
    ৴པੑͷߴ͍ࣗಈςετΛඋ͑Δ͜ͱ
    ։ൃऀओମͰड͚ೖΕςετΛ࡞੒ɾ؅ཧ͠ɺ

    खݩͷ։ൃ؀ڥͰ؆୯ʹ࠶ݱɾमਖ਼Ͱ͖Δ͜ͱ
    ʰ-FBOͱ%FW0QTͷՊֶʱQʢ˞༁ΛҰ෦มߋʣ

    View Slide

  20. IUUQTXXXBNB[PODPKQEQ
    ςετʹ߹֨ͨ͠ιϑτ΢ΣΞͰ͋Ε͹ϦϦʔεՄೳɺෆ߹֨Ͱ͋Ε͹ॏେͳ
    ෆ۩߹͕͋ΔɺͱνʔϜ͕֬৴Ͱ͖ΔΑ͏ͳςετΛ࣮ࢪ͍ͯ͠Δ͜ͱ
    ޡݕ஌ʢِཅੑGBMTFQPTJUJWFʣ΍ݟಀ͠ʢِӄੑGBMTFOFHBUJWFʣ͕ଟ
    ͘ɺ৴པੑʹ͚ܽΔςετεΠʔτ͕͋·Γʹ΋ଟ͗͢Δ
    ৴པ౓ͷߴ͍ςετεΠʔτΛ࡞Γ্͛Δܧଓతͳ౒ྗͱ౤ࢿ͸Ձ஋͕͋Δ
    ʰ-FBOͱ%FW0QTͷՊֶʱQʢ˞༁ΛҰ෦มߋʣ
    ৴པੑͷߴ͍ࣗಈςετΛඋ͑Δ͜ͱ

    View Slide

  21. ِཅੑͱِӄੑ
    IUUQTHJIZPKQNBHB[JOFXEQSFTTBSDIJWFWPM

    View Slide

  22. ِཅੑͱِӄੑͷύλʔϯ
    w ِཅੑ
    w ੬͍ςετ CSJUUMFUFTU GSBHJMFUFTU

    w ৴པෆೳςετ
    fl
    BLZUFTU

    w ِӄੑ
    w ۭৼΓ
    w ΧόϨοδෆ଍
    w ςετର৅ϩδοΫͷςετίʔυ΁ͷ࿙Εग़͠

    View Slide

  23. // プロダクトコード


    class Item {


    // コンストラクタ割愛


    tax_amount() {


    const rate = (this.tax_rate / 100);


    return (this.price / (1 + rate)) * rate;


    }


    }


    // テストコード


    it('税込価格から税額を返す', () => {


    const item = new Item('技評茶', 130, 8);


    const expected = (130 / (1 + (8 / 100))) * (8 / 100);


    assert.equal(item.tax_amount(), expected);


    });
    ྫςετର৅ϩδοΫͷςετίʔυ΁ͷ࿙Εग़͠
    ԁະຬͷ୺਺͕ൃੜ͢Δ
    όά͕͋Δ
    ςετίʔυͷํ΋ಉ͡ϩδοΫͰ
    ظ଴஋Λܭࢉ͍ͯ͠ΔͷͰ
    ςετ͕੒ޭͯ͠͠·͏

    View Slide

  24. ৴པෆೳੑʢ
    fl
    BLJOFTTʣ͕ʹ઀ۙ͢Δͱɺςετ͸Ձ஋Λࣦ͍࢝ΊΔ
    IUUQTXXXPSFJMMZDPKQCPPLT
    ʰ(PPHMFͷιϑτ΢ΣΞΤϯδχΞϦϯάʱQ

    View Slide

  25. "HFOEB࿈ࡌ֤ճͷςʔϚ
    ֶश༻ςετ
    ِཅੑͱِӄੑ
    ςεταΠζ
    ςετμϒϧ
    ςετϐϥϛου
    🦁

    View Slide

  26. ࣗಈςετͱ$*ʹϑΟοτ͢Δ
    ໌֬ͳςετ෼ྨج४

    View Slide

  27. օ͞Μʹ͓࢕͍͠·͢
    🙋🙋🙋
    wσʔλϕʔεʹΞΫηε͢Δͷ͸Ϣχοτςετ :FT/P
    wωοτϫʔΫʹΞΫηε͢Δͷ͸Ϣχοτςετ :FT/P
    wϑΝΠϧʹΞΫηε͢Δͷ͸Ϣχοτςετ :FT/P
    wݱࡏ࣌ࠁʹΞΫηε͢Δͷ͸Ϣχοτςετ :FT/P
    wґଘઌͷΫϥεʹຊ෺Λ࢖͏ͷ͸Ϣχοτςετ :FT/P

    View Slide

  28. IUUQTNBSUJOGPXMFSDPNCMJLJ6OJU5FTUIUNM
    6OJU5FTUͷ6OJUͬͯԿʁ

    View Slide

  29. 5FTU4J[FΑΓᐆດ͞ͷগͳ͍෼ྨ

    View Slide

  30. IUUQTUFTUJOHHPPHMFCMPHDPNUFTUTJ[FTIUNM
    5FTU4J[F

    View Slide

  31. 4NBMM

    ʢ୯Ұϓϩηεʣ
    .FEJVN

    ʢ୯ҰϚγϯʣ
    -BSHF

    ʢ੍໿ͳ͠ʣ
    6OJU
    ൺ཰

    େ͍ʹਪ঑
    ආ͚͍͕ͨ
    ͔ͨ͠ͳ͍ͱ͖΋
    ࠷ѱ͕ͩ
    Α͘ݟ͔͚Δ
    *OUFHSBUJPO
    ൺ཰

    ॻ͚ΔͳΒ
    ίεύྑ͠
    ී௨
    Ͱ͖Ε͹
    ආ͚͍ͨ
    &&
    ൺ཰

    ݪཧ্ෆՄೳʹ͍͕ۙ
    খ͍͞γεςϜͳΒՄೳʁ
    খ͍͞γεςϜ
    ͳΒՄೳ
    ී௨͔ͭ
    $6+ʹߜΓ͍ͨ
    5FTU4DPQF
    5FTU4J[F
    5FTU4DPQFͱ5FTU4J[F

    View Slide

  32. 4NBMM

    ʢ୯Ұϓϩηεʣ
    .FEJVN

    ʢ୯ҰϚγϯʣ
    -BSHF

    ʢ੍໿ͳ͠ʣ
    6OJU
    ൺ཰

    େ͍ʹਪ঑
    ආ͚͍͕ͨ
    ͔ͨ͠ͳ͍ͱ͖΋
    ࠷ѱ͕ͩ
    Α͘ݟ͔͚Δ
    *OUFHSBUJPO
    ൺ཰

    ॻ͚ΔͳΒ
    ίεύྑ͠
    ී௨
    Ͱ͖Ε͹
    ආ͚͍ͨ
    &&
    ൺ཰

    ݪཧ্ෆՄೳʹ͍͕ۙ
    খ͍͞γεςϜͳΒՄೳʁ
    খ͍͞γεςϜ
    ͳΒՄೳ
    ී௨͔ͭ
    $6+ʹߜΓ͍ͨ
    5FTU4DPQF
    5FTU4J[F
    5FTU4DPQFͱ5FTU4J[F
    ίεύྑ͠
    ίεύѱ͠

    View Slide

  33. "HFOEB࿈ࡌ֤ճͷςʔϚ
    ֶश༻ςετ
    ِཅੑͱِӄੑ
    ςεταΠζ
    ςετμϒϧ
    ςετϐϥϛου
    🦁

    View Slide

  34. ஧࣮ੑͱܾఆੑͷ
    τϨʔυΦϑΛཧղ͢Δ

    View Slide

  35. IUUQYVOJUQBUUFSOTDPN5FTU%PVCMFIUNM
    5FTU%PVCMFࣗಈςετ༻ͷِ෺

    View Slide

  36. IUUQYVOJUQBUUFSOTDPN5FTU%PVCMFIUNM
    5FTU%PVCMFͷ෼ྨʢ࿈ࡌͷϖʔδʹऩ·Βͣʜʜʣ

    View Slide

  37. ςετμϒϧͷར఺ͱ஫ҙ఺
    IUUQTXXXBNB[PODPKQEQ
    w ར఺
    w ςετ͠ʹ͍͘΋ͷΛςετՄೳʹ͢Δ
    w ςετͷ଎౓ͱܾఆੑΛ޲্ͤ͞Δ
    w ஫ҙ఺
    w ςετ͕੬͘ͳΓɺมߋΛ๦͛Δʢར఺ͷཪฦ͠ʣ
    w ςετͷِӄੑΛট͘ʢࣗ࡞ࣗԋςετʣ

    View Slide

  38. "HFOEB࿈ࡌ֤ճͷςʔϚ
    ֶश༻ςετ
    ِཅੑͱِӄੑ
    ςεταΠζ
    ςετμϒϧ
    ςετϐϥϛου
    🦁

    View Slide

  39. ࣗಈςετͷ৴པੑΛ
    த௕ظతʹอͭ
    ࠷దͳόϥϯε

    View Slide

  40. Ϣχοτ
    ΠϯςάϨʔγϣϯ
    &&
    ίετ
    ஧࣮ੑ
    ଎౓
    ςετέʔε਺
    ߴ
    ௿
    ௿
    ߴ
    ܾఆੑ
    ςετϐϥϛου

    View Slide

  41. ςετϐϥϛουͱΞΠεΫϦʔϜίʔϯΞϯνύλʔϯ
    IUUQTXBUJSNFMPOCMPHJOUSPEVDJOHUIFTPGUXBSFUFTUJOHJDFDSFBNDPOF

    View Slide

  42. ࠞཚ͸ղऍͷϒϨ͔Βੜ͕ͪ͡

    View Slide

  43. ͜Ε·Ͱͷ஌ݟΛ·ͱΊΔͱ
    ֶश༻ςετ
    ِཅੑͱِӄੑ
    ςεταΠζ
    ςετμϒϧ
    ςετϐϥϛου
    🦁
    🦁
    🦁
    🦁

    View Slide

  44. 4NBMM
    .FEJVN
    -BSHF
    ίετ
    ஧࣮ੑ
    ଎౓
    ςετέʔε਺
    ߴ
    ௿
    ௿
    ߴ
    ܾఆੑ
    ·ͱΊςετμϒϧͰαΠζμ΢ϯͯ͠ɺ֤αΠζΛϐϥϛουܕʹ഑ஔ͠ɺςετશମͷ৴པੑΛҡ࣋͢Δ
    ςετμϒϧ
    ςετμϒϧ
    ςετ༰қੑઃܭ
    υϝΠϯઃܭ

    View Slide

  45. ͓ΘΓʹ

    View Slide

  46. ࣦ৬ͷةػྑॻ͗͢Δ
    IUUQTCPPLNZOBWJKQFDQSPEVDUTEFUBJMJE

    View Slide

  47. ࣦ৬ͷةػ͍͔ʹ΋ࢲͷݴ͍ͦ͏ͳ͜ͱΛݴ͏"*
    IUUQTUXJUUFSDPNLBXBTJNBTUBUVT

    View Slide

  48. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠
    📷🙆 🙆 'PSLXFMMจԽࡇ@"

    View Slide