1.7K Views
December 04, 24
スライド概要
2024/12/04 toranoana.deno #19 https://yumenosora.connpass.com/event/335803/
Working at Deno Land, Studying at Georgia Tech
deno test --doc 解体新書 2024/12/04 toranoana.deno #19 Yusuke Tanaka
Who am I 米ジョージア工科大学のオンライン修士 課程に通いながらDeno Land Inc.で Deno Deployを作っています🦕 ← リアルで会った方にはもれなくこの名 刺をプレゼント! GitHub: https://github.com/magurotuna 𝕏: https://x.com/yusuktan 🦋: https://bsky.app/profile/magurotuna.bsky.social
Bluesky 🔥 https://go.bsky.app/FY3ACh4 BlueskyにDenoのメンバーが集結
今日の内容
Deno 2.0から利用可能 真のDoc Test
真の ← 🤔 DocTest ← 🤔
What are doc tests?
Doc Test ● ドキュメントコメント中に書いたコードスニペットを、通常のテストケースの ようにテストすることができる ○ Rustにもある (Pythonにもあるらしい) ● Markdownも対応 ● 何が嬉しい? ○ ユーザーへのドキュメントとして機能するコードサンプルが、常に機能 するものであることを保証できる ○ 例: https://jsr.io/@std/streams/doc/~/toText
真の? ● ドキュメントコメント中に書いたコードスニペットを「型チェック」する機能は 以前からあった ● = 必ずしも「挙動」を保証できているわけではなかった ● 実際、ユーザー側で力技でスニペット抽出 → 実行していたことも ○ deno_std: スニペット抽出して `deno eval` で実行 ○ Milli/ts-streams: 抽出して、Data URL化して、dynamic import する
Quick Demo!
How does it work?
どうやって動いているのか at a high level 1. コードフェンス ```...``` で囲われている部分を抽出 2. 抽出したコードを `Deno.test(...)` で囲む 3. テストごとにpseudo fileを生成 ○ foo_test.ts$13-42.ts のような疑似ファイルをメモリ上に作成 するイメージ 4. pseudo fileごとにワーカー (V8 Isolate) を立ち上げて、実行
どうやって動いているのか Step 1 1. コードフェンスに囲 われた部分を抽出
どうやって動いているのか Step 2-4 2.`Deno.test(...)` で囲む 3. maguro.ts$5-11.ts を生成 4. ワーカーを起動し、実行
単なるテキスト処理ではない 2.`Deno.test(...)` で囲む 🤔🤔🤔 ただ囲むだけではない
単なるテキスト処理ではない ● テスト対象の関数を自動で import ● 元からあるimport / export はtop levelに置く必要あり ● コメントも保持しなければなら ない (e.g. // @ts-expect-error)
単なるテキスト処理ではない 💡解決方法 SWCを使ってかっちりASTレベル で処理をする 実装に興味がある方へ: cli/util/extract.rs
力技によるユーザー側での実装との違い ● 個別のテストが別々のワーカーで実行される ○ テスト間の独立性を保証 ○ `deno eval` して別プロセスを立ち上げるより早い(多分) ● stats などが通常の `deno test` と統合されている ● ASTベースの丁寧なスニペット変換をしている
テスト実装者としての注意点 ● (Doc Test機能の有無には関係ないが)サンプルコードは、対象の関数の振る舞いを簡 潔かつ必要十分に説明し、かつ再利用性が高いもの(コピペビリティが高 い)であることが望ましい
テスト実装者としての注意点 ● 型チェックのみされていたものが、実際に実行されるようになった ○ 外界に副作用を起こすコードは推奨されない ■ 例: example.com にHTTPリクエストを送るコード ● ■ 💯 テスト用のHTTPサーバーを立ち上げる 例: カレントディレクトリに foo.txt を作成するコード ● 💯 `Deno.makeTempDir()` で一時置き場を作る ● 💯 実際のファイルである必要があるのか、 /dev/null や他のsink ではダメなのかを検討する ● 従来の「型チェックだけ行う」機能は `deno check --doc` で引き続 き利用可能
今後の展望 (時間に余裕があれば ……) ● LSPとの連携 ○ Doc Testを書いているときに補完や型チェックが効く ○ Doc Testに対してもテスト実行ボタンを表示 ● doc generatorとの連携 ○ 「スニペットを独立したテストとして実行するためには必要だが、サン プルコードとしてユーザーに見せるには冗長なコード行」をdoc生成 から省ける仕組み (Rustにあるやつ)
Thank you all 🦕 Questions?