Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

やってみる

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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