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

Enumを自動で網羅的にテストしてみた

 Enumを自動で網羅的にテストしてみた

estie | エスティ

December 26, 2022
Tweet

More Decks by estie | エスティ

Other Decks in Programming

Transcript

  1. Enumを自動で網羅的にテストしてみた
    2022/11/28
    Rust、何もわからない….vol5
    riano_ @riano_17

    View Slide

  2. riano_です。
    • 2022年8月からestieに参加
    • estieではデータ管理サービスを作っています
    • Rustはestie入社から使い始めました
    • 趣味で競技プログラミングをしています
    1

    View Slide

  3. 2
    1. データサービスを作る上での不安
    2. 楽に網羅的にテストしたい
    3. やってみた:3行書き換えればOKになった
    4. できなかったこと:1行書けばOKにはできなかった
    5. まとめ
    今日の内容

    View Slide

  4. データが壊れたらやばい!
    (あたりまえ)

    View Slide

  5. 4
    データを変換しなければ、
    入力された文字列をそのままバケツリレーすれば、
    よほどのことがない限りミスはない
    しかし、複雑な不動産データをシンプルに扱うためにはそれではいけない
    坪99999円、月1,999,999円、88888円 ...
    データをシンプルに扱うために(非自明な)構造化が必要

    View Slide

  6. 5
    データのパターン化をおこなっている
    (空調設備の例)
    バックエンドでの構造化の例
    バックエンド
    DB

    View Slide

  7. 6
    複数回のデータ変換を行う
    特に、データベース(MySQL)への書き込み時に符号化を行っている
    書き込みと読み取りの順番を間違えて実装してしまったら?
    変換を行うからこそ、ミスが生じる可能性がある

    View Slide

  8. 7
    • エラーが起きることもない
    • 知らないうちにデータが壊れていく
    • (まさに立ち上げ中のサービスなので)
    データ列の追加もあれば、項目の追加もある
    • 全パターンのテストを書く ... ?
    ミスが起きてしまったら、取り返しがつかない→どうするか?

    View Slide

  9. 楽に網羅的にテストしたい!!

    View Slide

  10. 9
    全てをテストしたいわけではない
    APIテストなどで全ケース網羅するのはコストが高い
    結合テストは重要な挙動を、単体テストはリスクに応じた網羅度で
    データベースへの読み書きはリスクが高そうな部分
    その正しさを保証しながら、開発スピードを維持できる方法はないか?
    正しさの保証と、開発スピードを両立させたい

    View Slide

  11. 10
    例えば、for ループのように書けてしまえば、
    定型文を書くだけ&項目が増えても自動的にテストが対応してくれる
    例えばこんなことができればいいな

    View Slide

  12. やってみる

    View Slide

  13. 12
    使ったもの
    • 既存の開発環境(sqlx, MySQL)
    • every_variantというcrate
    (https://github.com/TotalKrill/every_variant)
    crateを1つ導入してやってみた

    View Slide

  14. (再掲:EveryVariantマクロを定義しておく)
    13
    Enum型への実装例

    View Slide

  15. テストの例:
    Building構造体の中で
    空調のパターンを
    全てテストしている
    14
    Enum型への実装例

    View Slide

  16. テスト結果:
    15
    Enum型への実装例

    View Slide

  17. 16
    実は類似の機能を持つクレートが他にもあったが、選んだ理由
    • 数値や文字列を持つenumに対応している
    • enumやoptionを含む構造体にも適用できる
    このcrateを選んだ理由、メリットについて

    View Slide

  18. メンバーにEnum型を持つやや複雑な構造体にも適用可能
    17
    やや複雑な構造体でやってみる

    View Slide

  19. 同じようにテスト可能
    18
    1つ上位の構造体でやってみる

    View Slide

  20. テスト結果:
    19
    1つ上位の構造体でやってみる

    View Slide

  21. 20
    ちなみに、どんな原理でやっているの?
    →Enumを構文解析して、vectorにpushするマクロを生成
    (マクロを生成する関数の先頭部分)
    原理を調べてみる

    View Slide

  22. 21
    • proc_macroによる生成について(実例あり)
    https://qiita.com/yagince/items/546d86588aaa3fdb3c94
    • もう少し詳しめに、synクレートやquoteクレートも紹介
    https://techracho.bpsinc.jp/yoshi/2020_12_24/102304
    参考文献の紹介

    View Slide

  23. 22
    • 構造体の名前を返す関数をマクロで作成
    ちょっと手を動かしてみる

    View Slide

  24. 23
    • フィールド名と
    その型を取得
    ちょっと手を動かしてみる

    View Slide

  25. 24
    • このように動作する
    →これをめちゃめちゃ
    発展させると、
    Every_variantになる
    ちょっと手を動かしてみる

    View Slide

  26. コピペして3行書き換えれば
    テスト完了!!

    View Slide

  27. 26
    関数に構造体を渡せば1行でテスト完了!なら理想 ...
    構造体をテンプレート化することはできる
    フィールド名を変数として扱うにはマクロが必要そうだが、
    マクロに別の箇所で定義した関数を盛り込むのが難しそう...
    何もわからないので、教えてください!
    関数化して1行で書けるようにできれば理想だった

    View Slide

  28. 安心感と省力化を追い風に
    開発を加速させます!
    (やることは無限にあるので)

    View Slide

  29. estieではチームメンバーを募集しています!

    View Slide