Open mattrubin opened 7 months ago
Hey! ๐ For the time being, I'd recommend you either:
nodejs_compat
flag to all your Workers. As you say, this will ensure the prod and test runtimes have access to roughly the same modules, although note there a few other differences between the prod and test runtimes (e.g. prod is bundled with esbuild
, whereas test loads modules from disk at runtime more like Node).nodejs_compat
flag. They behave as close to the prod runtime as possible. This is effectively your Options 2 & 3
combined. See https://github.com/cloudflare/workers-sdk/tree/main/fixtures/vitest-pool-workers-examples/basics-integration-auxiliary for an example.I think it's going to be tricky to remove the nodejs_compat
flag requirement for the test runner Worker any time soon, as Vitest was initially designed for Node.js and relies on quite a few of these APIs.
Thanks for the quick reply! I'll give your second suggestion a try.
The suggested approach โ building the worker in a global setup script, then running it as an auxiliary worker during testing โ worked well as a solution for catching the sort of runtime dependency resolution issue described above. ๐
However, the primary limitation of this approach is that there seems to be no mechanism for mocking outbound fetch()
requests made by an auxiliary worker. This means that the actual testing of my worker's functionality needs to still be done via unit testing and SELF
-based integration testing. In this case, the auxiliary worker testing exists simply to answer the question "will my worker run in a production-like environment?".
@mrbbot This and other limitations of auxiliary workers are fairly well documented, and the docs do acknowledge the developer experience shortcomings. That said, would you welcome new feature request/improvement GitHub issues to track these areas of potential improvement, or do you feel that they are already tracked elsewhere (or are unfixable)?
there seems to be no mechanism for mocking outbound
fetch()
requests made by an auxiliary worker
This is possible using the Miniflare outboundService
or fetchMock
options. See here for an example:
See https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare#interface-workeroptions for documentation. To create a MockAgent
for the fetchMock
option, import and call the createFetchMock()
function from the miniflare
package.
I think it's going to be tricky for us to provide the same developer experience for auxiliary workers. Not using Vite for module resolution and transformation makes them good for as-close-to-production integration tests, but also makes it hard to provide things like automatic test re-runs. It's possible we could improve the experience with support for TypeScript entrypoints, but I don't think it's possible to get the same DX without sacrificing test fidelity.
there seems to be no mechanism for mocking outbound
fetch()
requests made by an auxiliary workerThis is possible using the Miniflare
outboundService
orfetchMock
options. See here for an example:
This is fantastic, thanks! I had interpreted too broadly the documentation's statement that auxiliary workers are "not affected by global mocks defined in your tests" and thought that fetch mocking was not possible.
I think it's going to be tricky for us to provide the same developer experience for auxiliary workers. Not using Vite for module resolution and transformation makes them good for as-close-to-production integration tests, but also makes it hard to provide things like automatic test re-runs. It's possible we could improve the experience with support for TypeScript entrypoints, but I don't think it's possible to get the same DX without sacrificing test fidelity.
Understood.
Personally, automatic test re-runs are less of a priority for integration tests. At the top of my DX wishlist would be:
wrangler.toml
to configure auxiliary workersglobal-setup.ts
(perhaps this is what you meant by "support for TypeScript entrypoints")โฆbut I also understand if the effort involved does not make these changes worth it for the somewhat-smaller DX improvements.
Ok, I'm going to repurpose this issue to track adding support for wrangler.toml
and TypeScript entrypoints to auxiliary Workers. I agree these would be good DX improvements. I'll update the title, and add a note to your initial description to capture this. ๐
(Note: this issue was updated to track support for
wrangler.toml
configuration and TypeScript entrypoints for auxiliary Workers, see https://github.com/cloudflare/workers-sdk/issues/5264#issuecomment-2008044798)I would like to test my project with
@cloudflare/vitest-pool-workers
, to ensure it is able to run onworkerd
. Unfortunately, the fact that@cloudflare/vitest-pool-workers
requires thenodejs_compat
compatibility flag introduces the possibility of code that passes the tests but fails to build viawrangler
.The code in question uses
crypto.subtle.verify
from the Web Crypto API, which does not require Node.js compatibility. However, the lineimport crypto from 'node:crypto';
was mistakenly added to the file.This import is valid when the tests are run with the mandatory
nodejs_compat
, and so the test suite passes without issue.When I run the worker (which does not have
nodejs_compat
in itswrangler.toml
) viawrangler dev
, it fails to start with:and
I am curious what the recommended approach to this problem might be. I can think of several possibilities: 1) Add the
nodejs_compat
compatibility flag to all my workers โ even though it is not necessary โ just to ensure the prod and test runtimes are the same 2) Add a test that usesunstable_dev
to build and run the worker via Wrangler (This might require a separate test suite with a different vitest config, since I don't think it is possible to useunstable_dev
from inside@cloudflare/vitest-pool-workers
.) 3) Addwrangler deploy --dry-run
to mynpm test
script, to check the result of the actual build process in parallel with running the test suite 4) Leave this all as-is, accept the risk of code that passes the tests but fails to build, and wait for thenodejs_compat
requirement to (hopefully) be lifted in the futureI would prefer to avoid option 1, as it adds unnecessary runtime dependencies (and potential complexity) to my workers. Options 2 and 3 are both possible, and option 3 in particular is not an unreasonable change to make, but this would only help with testing workers โ testing non-worker packages that are meant to be depended on by workers would require wrapping the code in a test-only worker to make use of Wrangler's build process. Option 4 would feel palatable only if removing
nodejs_compat
is an anticipated goal of the@cloudflare/vitest-pool-workers
project.I'd appreciate any guidance or suggestions from the project's developers. Thank you for all of the work that has already gone into the new Vitest integration!