Enumを自動で網羅的にテストしてみた2022/11/28Rust、何もわからない….vol5riano_ @riano_17
View Slide
riano_です。• 2022年8月からestieに参加• estieではデータ管理サービスを作っています• Rustはestie入社から使い始めました• 趣味で競技プログラミングをしています1
21. データサービスを作る上での不安2. 楽に網羅的にテストしたい3. やってみた:3行書き換えればOKになった4. できなかったこと:1行書けばOKにはできなかった5. まとめ今日の内容
データが壊れたらやばい!(あたりまえ)
4データを変換しなければ、入力された文字列をそのままバケツリレーすれば、よほどのことがない限りミスはないしかし、複雑な不動産データをシンプルに扱うためにはそれではいけない坪99999円、月1,999,999円、88888円 ...データをシンプルに扱うために(非自明な)構造化が必要
5データのパターン化をおこなっている(空調設備の例)バックエンドでの構造化の例バックエンドDB
6複数回のデータ変換を行う特に、データベース(MySQL)への書き込み時に符号化を行っている書き込みと読み取りの順番を間違えて実装してしまったら?変換を行うからこそ、ミスが生じる可能性がある
7• エラーが起きることもない• 知らないうちにデータが壊れていく• (まさに立ち上げ中のサービスなので)データ列の追加もあれば、項目の追加もある• 全パターンのテストを書く ... ?ミスが起きてしまったら、取り返しがつかない→どうするか?
楽に網羅的にテストしたい!!
9全てをテストしたいわけではないAPIテストなどで全ケース網羅するのはコストが高い結合テストは重要な挙動を、単体テストはリスクに応じた網羅度でデータベースへの読み書きはリスクが高そうな部分その正しさを保証しながら、開発スピードを維持できる方法はないか?正しさの保証と、開発スピードを両立させたい
10例えば、for ループのように書けてしまえば、定型文を書くだけ&項目が増えても自動的にテストが対応してくれる例えばこんなことができればいいな
やってみる
12使ったもの• 既存の開発環境(sqlx, MySQL)• every_variantというcrate(https://github.com/TotalKrill/every_variant)crateを1つ導入してやってみた
(再掲:EveryVariantマクロを定義しておく)13Enum型への実装例
テストの例:Building構造体の中で空調のパターンを全てテストしている14Enum型への実装例
テスト結果:15Enum型への実装例
16実は類似の機能を持つクレートが他にもあったが、選んだ理由• 数値や文字列を持つenumに対応している• enumやoptionを含む構造体にも適用できるこのcrateを選んだ理由、メリットについて
メンバーにEnum型を持つやや複雑な構造体にも適用可能17やや複雑な構造体でやってみる
同じようにテスト可能181つ上位の構造体でやってみる
テスト結果:191つ上位の構造体でやってみる
20ちなみに、どんな原理でやっているの?→Enumを構文解析して、vectorにpushするマクロを生成(マクロを生成する関数の先頭部分)原理を調べてみる
21• proc_macroによる生成について(実例あり)https://qiita.com/yagince/items/546d86588aaa3fdb3c94• もう少し詳しめに、synクレートやquoteクレートも紹介https://techracho.bpsinc.jp/yoshi/2020_12_24/102304参考文献の紹介
22• 構造体の名前を返す関数をマクロで作成ちょっと手を動かしてみる
23• フィールド名とその型を取得ちょっと手を動かしてみる
24• このように動作する→これをめちゃめちゃ発展させると、Every_variantになるちょっと手を動かしてみる
コピペして3行書き換えればテスト完了!!
26関数に構造体を渡せば1行でテスト完了!なら理想 ...構造体をテンプレート化することはできるフィールド名を変数として扱うにはマクロが必要そうだが、マクロに別の箇所で定義した関数を盛り込むのが難しそう...何もわからないので、教えてください!関数化して1行で書けるようにできれば理想だった
安心感と省力化を追い風に開発を加速させます!(やることは無限にあるので)
estieではチームメンバーを募集しています!