Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Freshプラグインのテストもプラグインを使うと捗る!

 Freshプラグインのテストもプラグインを使うと捗る!

Freshのプラグインをgithub actions 上で自動テストをするために用意したノウハウの共有

https://yumenosora.connpass.com/event/301110/
https://www.youtube.com/watch?v=0MX1ZwBwPCg

虎の穴ラボ株式会社

December 07, 2023
Tweet

More Decks by 虎の穴ラボ株式会社

Other Decks in Technology

Transcript

  1. 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
    虎の穴ラボ 奥谷 一陽

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  10. 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の下にインストール
    各種オプションでインストール時質問をスキップ

    View full-size slide

  11. 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 をカレントディレクトリに移動

    View full-size slide

  12. 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
    テスト実行

    View full-size slide

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

    View full-size slide

  14. 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],
    });

    View full-size slide

  15. 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",
    },
    ],
    };

    View full-size slide

  16. 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}

    );
    }

    View full-size slide

  17. 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. テストコード本体

    View full-size slide

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

    View full-size slide

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

    View full-size slide