Slide 1

Slide 1 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. T O R A N O A N A L a b  Fresh  プラグイン のテストもプラグインを使うと捗る! 2023/12/07 虎の穴ラボ 奥谷 一陽

Slide 2

Slide 2 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 自己紹介 奥谷 一陽 所属:虎の穴ラボ株式会社 担当:Fantia、とらコインなどの開発 興味:Deno、TypeScript 最近買ったもの:ドライフルーツのサンザシ Twitter:@okutann88 github:Octo8080X

Slide 3

Slide 3 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 個人で公開している Fresh用のミドルウェアを改修している その中でプラグイン対応した 併せて自動テストを作り直すことにした

Slide 4

Slide 4 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. Freshのプラグインの自動テストに当たり - 最新版のFreshをインストールする - 最新版のFreshにプラグインを適用する を自動的に行う必要があった 一定のノウハウが見えてきたので共有する 「もっといいのがあるぞ」 という場合にはコメントください

Slide 5

Slide 5 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 1. 前提/目標 - 自動テストを実行するのは、github actions とします。 - 目標:自作プラグインを「最新のFresh」に入れてテストをする - テストでのチェック対象は、リクエストに基づくレスポンスです。 =>プラグインの機能を使ったレスポンスが必要 - 対象のリポジトリ:https://github.com/Octo8080X/fresh-session

Slide 6

Slide 6 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 1. 改修以前の状況 - tests 以下に拡張機能を入れたFreshを 直接置いていた - 問題点 - テスト対象が「最新のFresh」ではない - もしFreshをアップデートするなら、 テスト用middlewareとroutesを移植する必要がある Freshがそのまま置いてある

Slide 7

Slide 7 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2. 改修後のディレクトリ構成 - tests の下にあったFresh本体が消滅 - config、 fresh.config.tsと差し替える - plugin、routesディレクトリを追加 これが「テストするためのプラグイン」

Slide 8

Slide 8 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 3. テストをするには? - プラグインのテストを行う場合、 プラグインを自動インストールしたFreshに適用する必要がある。 =>config(fresh.config.ts)は差し替えができる - (おそらく大体のケースで、)そのプラグインを使ったレスポンスを返す ミドルウェアかroutesのどちらかを用意する必要がある。 =>プラグインの機能を使うプラグインを追加で設定すれば良い => テスト用のconfigとプラグインで    インストールした最新のfreshを動かせば良い

Slide 9

Slide 9 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 3. テストをするには? - プラグインのテストを行う場合、 プラグインを自動インストールしたFreshに適用する必要がある。 =>config(fresh.config.ts)は差し替えができる - (おそらく大体のケースで、)そのプラグインを使ったレスポンスを返す ミドルウェアかroutesのどちらかを用意する必要がある。 =>プラグインの機能を使うプラグインを追加で設定すれば良い => テスト用のconfigとプラグインで    インストールした最新のfreshを動かせば良い

Slide 10

Slide 10 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 4. github actions及びテストの流れ jobs: test: runs-on: ubuntu-latest steps: - name: Setup repo uses: actions/checkout@v3 - name: Setup Deno uses: denoland/setup-deno@v1 - name: Check version run: deno -V - name: Verify formatting run: deno fmt --check - name: Install Fresh run: deno run -A https://deno.land/x/fresh/init.ts ./tests/work --force --twind --tailwind --vscode - name: Move deno.json run: mv ./tests/work/deno.json ./deno.json - name: view deno.json run: cat ./deno.json - name: Run tests run: deno test --unstable -A 最新の Fresh を testsの下にインストール 各種オプションでインストール時質問をスキップ

Slide 11

Slide 11 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 4. github actions及びテストの流れ jobs: test: runs-on: ubuntu-latest steps: - name: Setup repo uses: actions/checkout@v3 - name: Setup Deno uses: denoland/setup-deno@v1 - name: Check version run: deno -V - name: Verify formatting run: deno fmt --check - name: Install Fresh run: deno run -A https://deno.land/x/fresh/init.ts ./tests/work --force --twind --tailwind --vscode - name: Move deno.json run: mv ./tests/work/deno.json ./deno.json - name: view deno.json run: cat ./deno.json - name: Run tests run: deno test --unstable -A deno.json をカレントディレクトリに移動

Slide 12

Slide 12 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 4. github actions及びテストの流れ jobs: test: runs-on: ubuntu-latest steps: - name: Setup repo uses: actions/checkout@v3 - name: Setup Deno uses: denoland/setup-deno@v1 - name: Check version run: deno -V - name: Verify formatting run: deno fmt --check - name: Install Fresh run: deno run -A https://deno.land/x/fresh/init.ts ./tests/work --force --twind --tailwind --vscode - name: Move deno.json run: mv ./tests/work/deno.json ./deno.json - name: view deno.json run: cat ./deno.json - name: Run tests run: deno test --unstable -A テスト実行

Slide 13

Slide 13 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 5. テスト用のconfig(fresh.config.ts)とプラグインの中身 - tests/config => fresh.config.tsとの差し替え - tests/plugin => テスト用に追加で設定する   プラグイン - tests/routes => テスト用プラグインで 設定する新しいroute

Slide 14

Slide 14 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 5. テスト用のconfig(fresh.config.ts)とプラグインの中身 - tests/config => dres.config.tsとの差し替え - tests/plugin => テスト用に追加で設定する   プラグイン - tests/routes => テスト等プラグインで 設定する新しいroute // tests/config/redis_session_test_plugin_fresh.config.ts import { defineConfig } from "$fresh/server.ts"; import { getCookieSessionPlugin } from "../../mod.ts"; import { testPlugin } from "../plugin/test_plugin.ts"; export default defineConfig({ plugins: [getCookieSessionPlugin("/"), testPlugin], });

Slide 15

Slide 15 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 5. テスト用のconfig(fresh.config.ts)とプラグインの中身 - tests/config => dres.config.tsとの差し替え - tests/plugin => テスト用に追加で設定する   プラグイン - tests/routes => テスト等プラグインで 設定する新しいroute // tests/config/redis_session_test_plugin_fresh.config.ts import { defineConfig } from "$fresh/server.ts"; import { getCookieSessionPlugin } from "../../mod.ts"; import { testPlugin } from "../plugin/test_plugin.ts"; export default defineConfig({ plugins: [getCookieSessionPlugin("/"), testPlugin], }); // tests/plugin/test_plugin.ts import { PageProps, Plugin } from "$fresh/server.ts"; import TestComponent from "../routes/session_test_route.tsx"; import { ComponentType } from "preact"; export const testPlugin: Plugin = { name: "TestPlugin", routes: [ { component: TestComponent as ComponentType, path: "/session", }, ], };

Slide 16

Slide 16 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 5. テスト用のconfig(fresh.config.ts)とプラグインの中身 - tests/config => dres.config.tsとの差し替え - tests/plugin => テスト用に追加で設定する プラグイン - tests/routes => テスト等プラグインで 設定する新しいroute // tests/routes/session_test_route.tsx import { PageProps } from "$fresh/server.ts"; import type { WithSession } from "../../mod.ts"; export default function Home( props: PageProps>, ) { const count = props.state.session.get("count") || 0; props.state.session.set("count", Number(count) + 1); return (

count:{count}

); }

Slide 17

Slide 17 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. // tests/redis_session_test.ts(一部省略) import { createHandler, ServeHandlerInfo } from "$fresh/server.ts"; import manifest from "./work/fresh.gen.ts"; import config from "./config/redis_session_test_plugin_fresh.config.ts"; import { assertEquals } from "../deps.ts"; const CONN_INFO: ServeHandlerInfo = { remoteAddr: { hostname: "127.0.0.1", port: 53496, transport: "tcp" }, }; Deno.test("Redis Session Test", async (t) => { const handler = await createHandler(manifest, config); // <<= これが プラグインが適用されたFresh await t.step("Work Session", async () => { let resp = await handler( new Request("http://127.0.0.1/session"), CONN_INFO, ); assertEquals(resp.status, 200); let text = await resp.text(); assertEquals(text.includes("

count:0

"), true); }); } } テスト用のconfigを使ってハンドラを取得しテストする テスト用のプラグインで設定したレスポンスが返ってくる 6. テストコード本体

Slide 18

Slide 18 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. まとめ - Freshのプラグインをテストする時 テスト用のconfigとプラグイン(middlewareとroutes)を用意すると、 プラグインの機能を使った最新のFreshのレスポンスのテストができる - 他に何かノウハウお持ちの方いたらぜひコメントください。

Slide 19

Slide 19 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. ありがとうございました