cloudflare / workers-sdk

⛅️ Home to Wrangler, the CLI for Cloudflare Workers®
https://developers.cloudflare.com/workers/
Apache License 2.0
2.7k stars 709 forks source link

🚀 Feature Request: Pages Function Template with Tests #3407

Closed humphd closed 6 months ago

humphd commented 1 year ago

Describe the solution

I'm writing Pages functions, and it's been a fairly smooth experience. However, as I now try to add tests, I'm finding a lack of useful examples, docs, etc.

For example, I want to invoke one of my Pages functions (e.g., a onRequestGet()) in a test and assert various things about the response. I'm unclear how one would do this outside of the Cloudflare runtime invoking it.

It seems like I somehow have to get/simulate an EventContext:

export type EventContext<Env, P extends string, Data> = {
  request: Request;
  functionPath: string;
  waitUntil: (promise: Promise<any>) => void;
  passThroughOnException: () => void;
  next: (input?: Request | string, init?: RequestInit) => Promise<Response>;
  env: Env & {
    ASSETS: {
      fetch: typeof fetch;
    };
  };
  params: Params<P>;
  data: Data;
};

Maybe there's some way to do this in Miniflare or Wrangler, etc. but the docs and existing examples I can find are all focused on how one would do this with a Worker vs. Pages Function.

It would be nice if at least one of the Templates you have in this repo included a simple example to show how you wire up a test for Pages functions.

There may be a better place for this issue to live, I'm not sure. I've also tried asking this on the CloudFlare Discord and Twitter as well.

JacobMGEvans commented 1 year ago

Greetings! I appreciate this suggestion, the testing story with Workers/Pages is something actively being worked on by the team. We have some hopeful prototypes but it is still early stages.

Cc: @mrbbot do you have any suggestions for the interim with Miniflare or something else?

humphd commented 1 year ago

So far, I've been testing my Pages Functions by calling a secondary function that lets avoid dealing with context of the direct call. For example:

import { getTokens } from "../token";

interface Env {
  JWT_SECRET: string;
}

export async function handleLogout({
  accessToken,
  idToken,
  JWT_SECRET,
}: {
  accessToken: string | null;
  idToken: string | null;
  JWT_SECRET: string;
}) {
   // ...
}

export const onRequestGet: PagesFunction<Env> = async ({ request, env }) => {
  const { JWT_SECRET } = env;
  const { accessToken, idToken } = getTokens(request);

  return handleLogout({ accessToken, idToken JWT_SECRET });
};

My tests are agains handleLogout, etc. vs. onRequest*(), which works, but obviously isn't ideal. I've also run into a roadblock with testing against mock R2 buckets.

I'll be interested to see how you progress with your work on testing.

JacobMGEvans commented 1 year ago

I think some of our testing framework stuff is still in the works and in planning.

cc: @admah

jspspike commented 1 year ago

As Jacob mentioned we have some things in the work for tests but for now it's recommended to use unstable_dev or invoke wrangler pages dev directly. Here is an example with pages using functions.

I'll leave this issue open as an issue to improve documentation around testing with pages

admah commented 7 months ago

@humphd I'm not sure if you're still interested in a solution for this, but we recently introduced a new way to test via Vitest - https://developers.cloudflare.com/workers/testing/vitest-integration/. #5288 has an example that might be able to help you using that new library.

humphd commented 7 months ago

@humphd I'm not sure if you're still interested in a solution for this, but we recently introduced a new way to test via Vitest - https://developers.cloudflare.com/workers/testing/vitest-integration/. #5288 has an example that might be able to help you using that new library.

I am, thank you for following up. I'll take a look!

admah commented 7 months ago

Great! Sorry for the delay. Let me know if that works.

CarmenPopoviciu commented 6 months ago

@humphd pls let us know if Adam's suggestion helped with your issue 🙏

humphd commented 6 months ago

New APIs look good. I won't have time to try implementing for a while, but I'm excited to try them when I do.

CarmenPopoviciu commented 6 months ago

sure thing! I'll go ahead and close this issue in favour of https://github.com/cloudflare/workers-sdk/issues/5288, which tracks the creation of an example for Pages Functions using @cloudflare/vitest-pool-workers. Feel free to re-open if you think necessary <3