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

組込みソフトウェア基礎_連続講座#8_テスト駆動開発の魅力を語る〜実装編〜

k-abe
February 16, 2023

 組込みソフトウェア基礎_連続講座#8_テスト駆動開発の魅力を語る〜実装編〜

2023/2/16(木)Twitterスペースの連続イベント(https://twitter.com/i/spaces/1dRKZMXygnQxB)の説明資料です

前々回の【ホスト編】ではLEDドライバをテーマにホストPCでテスト駆動開発(以降TDD)した際の概要を話しました。
前回の【ターゲット編】ではマイコンでTDDを試した話をしました。
今回は【実装編】としてホスト編・ターゲット編でテストコードを書いたときの話です。

※リンクが有効な資料はこちらを参照してください。
https://www.docswell.com/s/juraruming/5VV7PQ-2023-02-16-122410

k-abe

February 16, 2023
Tweet

More Decks by k-abe

Other Decks in Programming

Transcript

  1. ૊ ࠐ Έ ι ϑ τ ΢ Σ Ξ ج ૅ
    ݱ৔ϊ΢ϋ΢Λ஌Ζ͏


    ςετۦಈ։ൃͷັྗΛޠΔ


    ʙ࣮૷ฤʙ
    2023/2/16ʢ໦ʣ 19:30ʙ20:15
    Twitterεϖʔε: https://twitter.com/i/spaces/1dRKZMXygnQxB

    View Slide

  2. ▪ύʔιϧΫϩεςΫϊϩδʔגࣜձࣾ


    ɹୈ1ٕज़։ൃຊ෦ɾ౦೔ຊ։ൃ෦ɹट౎ݍ2GɹѨ෦ɹߞೋʢ͋΂ɹ͜͏͡ʣ


    ▪ҩྍػث։ൃ


    ɾ૊ࠐΈιϑτ΢ΣΞ։ൃɻ


    ɾCݴޠɺϕΞϝλϧͷ։ൃۀ຿ܦݧ͕΄ͱΜͲɻ


    ࣗݾ঺հ 1
    2

    View Slide

  3. ▪ٕज़ॻΛॻ͍ٕͯज़ॻయ13ʹࢀՃͨ͠Γɺ


    ɹ


    ▪ϚΠίϯͷίϯςετ(※)ʹࢀՃͨ͠Γɺ


    ɹ※SPRESENSE™ ׆༻ίϯςετ


    ɹ૊ࠐΈιϑτ΢ΣΞ։ൃ͕޷͖ͳ͓͡͞ΜͰ͢ɻ


    ɹΑΖ͓͘͠ئ͍͠·͢ɻ


    ▪LAPRASϙʔτϑΥϦΦɿhttps://lapras.com/public/k-abe


    ▪twitter: @juraruming
    ࣗݾ঺հ 2
    3

    View Slide

  4. ɾจࣈ௨ΓςετͰιϑτ΢Σ
    Ξ։ൃΛۦಈ(ਐΊ͍ͯ͘)͜ͱɻ


    ςετϑΝʔετͰΑΓྑ͍ઃܭ
    Λಋ͘ɻ
    ʲςετۦಈ։ൃ(Ҏ߱TDD) ͱ͸Կ?ʳ
    4

    View Slide

  5. 1.ָ͍͠


    2.ෆ͕҆ݮΔ


    3.ྑ͍ઃܭΛಋ͘


    4.ϋʔυ΢ΣΞ͕ͳͯ͘΋ςετ
    ΛਐΊΔํ๏࿦ֶ͕΂Δ
    ʲTDDֶशϝϦοτʳ
    5

    View Slide

  6. ɾϗετͱ͸?

    ɹ

    TDDΛ࣮ߦ͢Δ؀ڥͰɺ

    ϗετ → ϗετPCͰTDD͢Δɻ

    λʔήοτˠ૊ΈࠐΈ૷ஔͰTDD͢Δɻɹ
    ϗετɾλʔήοτͱ͸?
    6
    ϗετPC → ϗετ
    ૊ΈࠐΈ૷ஔ → λʔήοτ


    LED
    ▪ ϗετͰTDD͢Δಛ௃


    ɾ૊ΈࠐΈ૷ஔʹςετϓϩάϥϜΛμ΢
    ϯϩʔυ͠ͳͯ͘ྑ͍ͷͰૣ͘ςετͰ͖
    Δɻ


    ɾϋʔυ΢ΣΞΛ੍ޚ͠ͳ͍ɻϋʔυ΢Σ
    ΞΛԾ૝తʹѻ͏ɻ


    ɾςετϑϨʔϜϫʔΫʹࣗ༝౓͕͋Δɻ


    ɹGoogleTest, CppUTest, Unity, ͦͷଞ


    ▪ λʔήοτ


    ɾϗετʹൺ΂ͯςετΛճ͢ʲεϐʔ
    υʳ͕஗͍(ϗετˠλʔήοτ΁ͷϓϩ
    άϥϜͷμ΢ϯϩʔυͳͲ)ɻ


    ɾϋʔυ΢ΣΞΛ੍ޚ͢Δɻϋʔυ΢ΣΞ
    ΛབྷΊͨςετ͕Ͱ͖Δɻ


    ɾ࢖͑ΔςετϑϨʔϜϫʔΫʹ੍ݶ͕Ͱ
    ͯ͘ΔɻϚΠίϯ͸RAM͕গͳ͍ͨΊɻ


    ɹCppUTest, Unity, ͦͷଞ


    View Slide

  7. ʲϗετʳ


    ▪ϗετPC: macOS Monterey όʔδϣϯ 12.6

    ▪ςετϑϨʔϜϫʔΫ: CppUTest 4.0

    ▪ίϯύΠϥ: Apple clang version 11.0.0 (clang-1100.0.33.8)

    ▪ςετର৅ϓϩάϥϛϯάݴޠ: C

    ▪ϏϧυγεςϜ: cmake 3.21.1

    ʲλʔήοτʳ


    ※λʔήοτ͸ಈ࡞֬ೝͰ͖·ͤΜͰͨ͠ɻߏ૝ͷΈɻ


    ɾSTM32CubeIDE Version: 1.11.0


    ɾςετϑϨʔϜϫʔΫ: CppUTest 4.0(ϗετͱಉ͡)

    ʲࠓճͷ؀ڥʹ͍ͭͯʳ
    7

    View Slide

  8. ϗετฤͷҰ࿈ͷखॱ͸࣍ͷࢿྉʹॻ͖·ͨ͠ɻ


    Α͚Ε͹ࢀর͍ͯͩ͘͠͞ɻ


    ϗετฤࢿྉɿ


    ૊ΈࠐΈιϑτ΢ΣΞجૅ_ʲ࿈ଓߨ࠲ #6ʳTDD#2 LED
    ド
    ϥΠ
    バ

    ετPCฤ)_slide


    https://www.docswell.com/s/juraruming/
    5G31LZ-2022-10-31-220730


    ιʔείʔυ͸ͪ͜Βɻ


    https://github.com/grace2riku/evkart_tdd/tree/LedDriver_221031
    ʲϗετฤͷςετίʔυ࣮૷ʳ
    8

    View Slide

  9. ΍Δ͜ͱ


    ɾςετϦετ࡞੒


    ɾςετ؀ڥͭ͘Δ


    ɾςετΛॻ͘
    ʲϗετฤͷςετίʔυ࣮૷ʳ
    9

    View Slide

  10. ▪ςετϦετ࡞੒


    ɾςετ͢Δ͜ͱΛϦετԽ͢Δɻ૊ࠐΈTDDຊͷखॱΛਅࣅͨ͠ɻ


    ྫ) LedDriverςετϦετ


    https://github.com/grace2riku/evkart_tdd/tree/LedDriver_221031
    ʲϗετฤͷςετίʔυ࣮૷ʳ
    10

    View Slide

  11. ▪ςετ؀ڥΛͭ͘Δ


    ɹCppUTestͷ৔߹ɺ࣍ͷεΫϦϓτ࣮ߦͰTDD؀ڥͷ਽ܗ͕ͭ͘ΕΔɻ


    $ NewPackageDirs HallSensorLedDriver


    creating src/HallSensorLedDriver


    creating include/HallSensorLedDriver


    creating tests/HallSensorLedDriver


    $ NewCModule.sh HallSensorLedDriver HallSensorLedDriver


    creating include/HallSensorLedDriver/HallSensorLedDriver.h


    creating src/HallSensorLedDriver/HallSensorLedDriver.c


    creating tests/HallSensorLedDriver/HallSensorLedDriverTest.cpp


    ਽ܗͷιʔείʔυΛϏϧυର৅ʹ௥Ճ͠ɺςετΛॻ͍͍ͯ͘ɻ


    ϗετฤࢿྉͷp28Λࢀরɻ


    ʲϗετฤͷςετίʔυ࣮૷ʳ
    11

    View Slide

  12. ▪ςετΛॻ͘


    ɹςετίʔυɿ


    // υϥΠόΛॳظԽͨ͠Βɺ͢΂ͯͷLED͕ফ౮͍ͯ͠Δ


    TEST(HallSensorLedDriver, LedsOffAfterCreate)


    {


    unsigned char virtualLeds = 0xff; // ফ౮֬ೝͷͨΊʹLEDΦϯʹॳظԽ


    HallSensorLedDriver_Create(&virtualLeds); // υϥΠόॳظԽ


    BYTES_EQUAL(0, virtualLeds); // ॳظԽޙʹ0(LEDΦϑ)͔֬ೝ


    }


    ιʔείʔυɿ https://github.com/grace2riku/evkart_tdd/blob/LedDriver_221031/tests/
    HallSensorLedDriver/HallSensorLedDriverTest.cpp
    ʲϗετฤͷςετίʔυ࣮૷ʳ
    12

    View Slide

  13. ▪ςετΛॻ͘


    ɹϓϩμΫτίʔυɿ υϥΠόΛॳظԽ(͢΂ͯͷLEDΛOFF͢Δ)


    static unsigned char* hallSensorLedsAddress;


    void HallSensorLedDriver_Create(unsigned char* address)


    {


    hallSensorLedsAddress = address;


    *hallSensorLedsAddress = 0;


    }


    ιʔείʔυɿ https://github.com/grace2riku/evkart_tdd/blob/LedDriver_221031/
    src/HallSensorLedDriver/HallSensorLedDriver.c
    ʲϗετฤͷςετίʔυ࣮૷ʳ
    13

    View Slide

  14. ɾLedDriverͷTDD͸ಈ࡞֬ೝʹࢸΓ·ͤΜͰͨ͠ɻ


    ɹ˞LedDriverͷϕʔεʹ͠Α͏ͱͨ͠ޙड़ͷ͓ࢼ͠ίʔυ͕ಈ͔ͳ͘ͳΓݪҼௐࠪதɾɾɾ(ϗε
    τPCͷOS΋͘͠͸STM32CubeIDEͷόʔδϣϯΞοϓ͕ݪҼ͔ͱਪଌ)ɻ


    ɹ࣮૷ͷߏ૝͸ͪ͜Βͷࢿྉʹ·ͱΊ·ͨ͠ɻ


    ɹhttps://www.docswell.com/s/juraruming/KN4MW5-2022-12-15-210619


    ɾҎલɺ؆୯ͳ͓ࢼ͠ίʔυͰSTM32ϚΠίϯͰTDDͨ࣌͠ͷ࿩Λ͍ͨ͠ͱࢥ͍·͢ɻ


    ɹQiitaهࣄ͸ͪ͜ΒͰ͢ɻ


    ɹSTM32CubeIDEʹCppUTestΛ؀ڥߏங͠ɺSTM32ϚΠίϯͰTDD͢Δ


    ɹhttps://qiita.com/juraruming/items/1f91db17ba93b40d3730


    ɹιʔείʔυ͸ͪ͜ΒͰ͢ɻ


    ɹhttps://github.com/grace2riku/hello_stm32_cpputestɹ
    ʲλʔήοτฤͷςετίʔυ࣮૷ʳ
    14

    View Slide

  15. ςετίʔυ͸ͪ͜Β(ςετࣗମʹҙຯ͸ͳ͍Ͱ͢)


    https://github.com/grace2riku/hello_stm32_cpputest/blob/main/446re_test/Core/Src/
    test_src.cpp


    #include "CppUTest/TestHarness.h"
    TEST_GROUP(FirstTestGroup)
    {
    };
    TEST(FirstTestGroup, FirstTest) // ඞࣦͣഊ͢Δςετ
    {
    FAIL("FAIL: FirstTestGroup, FirstTest\n");
    }
    TEST(FirstTestGroup, SecondTest) // ඞͣ੒ޭ͢Δςετ Ҿ਺ʹ0Λ༩͍͑ͯΔ͔Β
    {
    CHECK_EQUAL_ZERO(0);
    }
    TEST(FirstTestGroup, IntSize) // ੒ޭ͢Δςετ STM32ϚΠίϯ͸32bitͰint͸4byteͷͨΊ
    {
    LONGS_EQUAL(4, sizeof(int));
    }
    ʲλʔήοτฤͷςετίʔυ࣮૷ʳ
    15

    View Slide

  16. mainؔ਺͔Βςετ࣮ߦ͠·͢ɻ


    https://github.com/grace2riku/hello_stm32_cpputest/blob/main/446re_test/Core/Src/main.cpp


    int main(void) {


    const char* empty[] = {};


    const char* command_v[] = {"cpputest", "-v"};


    printf("\n----- RunAllTests(0, empty) -----\n");


    CommandLineTestRunner::RunAllTests(0, empty);


    printf("\n----- RunAllTests(2, command_v) -----\n");


    CommandLineTestRunner::RunAllTests(2, command_v);


    while (1)


    {


    }


    }
    ʲλʔήοτฤͷςετίʔυ࣮૷ʳ
    16

    View Slide

  17. ςετͷ࣮ߦ݁Ռ


    #include "CppUTest/TestHarness.h"
    TEST_GROUP(FirstTestGroup)
    {
    };
    TEST(FirstTestGroup, FirstTest) // ඞࣦͣഊ͢Δςετ
    {
    FAIL("FAIL: FirstTestGroup, FirstTest\n");
    }
    TEST(FirstTestGroup, SecondTest) // ඞͣ੒ޭ͢Δςετ Ҿ਺ʹ0Λ༩͍͑ͯΔ͔Β
    {
    CHECK_EQUAL_ZERO(0);
    }
    TEST(FirstTestGroup, IntSize) // ੒ޭ͢Δςετ STM32ϚΠίϯ͸32bitͰint͸4byteͷͨΊ
    {
    LONGS_EQUAL(4, sizeof(int));
    }
    ಈը͸ͪ͜Βˠhttps://youtu.be/8rb3picKkjw
    ʲλʔήοτฤͷςετίʔυ࣮૷ʳ
    17

    View Slide

  18. ▪ςετ͸ࢿ࢈ɻΘ͔Γ΍໋໊͍͢Λ


    ▪λʔήοτͰTDD͢Δࡍ͸ඞཁϦιʔε
    Λ೺Ѳ͢Δɻ
    ʲϗετฤɾλʔήοτฤͷ࣮૷ϙΠϯτʳ
    18

    View Slide

  19. ▪ςετ͸ࢿ࢈ɻΘ͔Γ΍໋໊͍͢Λ


    ●ςετ͸܁Γฦ͠࢖͏͜ͱʹͳΔͱࢥ͏ɻޙ
    Ͱ࢖͏ͱ͖ʹΘ͔Γ΍͍͢ςετ໊ʹ͓ͯ͠
    ͘ɻ


    ●ςετ໊ͱςετ಺༰͕ෆҰகɺςετͷத
    ͰԿ߲໨΋ςετ͍ͯ͠ΔͳͲɺςετͷ඼
    ࣭ɾΘ͔Γ΍͢͞΋ॏཁͩͱࢥ͏ɻ
    ʲϗετฤɾλʔήοτฤͷ࣮૷ϙΠϯτʳ
    19

    View Slide

  20. ▪λʔήοτͰTDD͢Δࡍ͸ඞཁϦιʔεΛ೺Ѳ͢Δɻ


    ੍໿ͷݫ͍͠૊ࠐΈͰTDD͢Δ৔߹ɺςετϑϨʔϜϫʔΫ͕ͲΕ͘
    Β͍RAMΛফඅ͢Δ͔೺Ѳ͓ͯ͘͠ɻ


    ςετͰ͖·ͨ͠ɺ͔͠͠ΞϓϦέʔγϣϯ૊ΈࠐΊ·ͤΜɺͰ͸͓
    ࿩͠ʹͳΒͳ͍ɾɾɾɻ


    ※STM32ϚΠίϯʹCppUTestΛ૊ΈࠐΜͩͱ͖ͷϝϞϦ࢖༻ྔ͸͜
    ͪΒͰ͢ɻࢀߟ·Ͱʹɻ


    STM32CubeIDEʹCppUTestΛ؀ڥߏங͠ɺSTM32ϚΠίϯͰTDD͢Δ -> ϝϞϦ࢖༻ྔ


    https://qiita.com/juraruming/items/1f91db17ba93b40d3730


    ʲϗετฤɾλʔήοτฤͷ࣮૷ϙΠϯτʳ
    20

    View Slide

  21. ͝੩ௌ͋Γ͕ͱ͏
    ͍͟͝·ͨ͠ɻ
    ऴΘΓ
    21

    View Slide