Depending on what you test, my approach is to have three clear ways to describe tests, each with a specific purpose.
For pure function logic, the idea is isolation and portability. I would recommend Jest, Vitest, or another modern and fast test environment, focused on speed and standard compatibility. By pure logic I mean code that could be migrated to other codebases not using Meteor. Think of functions that do one thing, without accessing Meteor-specific APIs or Atmosphere packages, at most using standard NPM packages. These tests should be fast, framework-agnostic and easy to maintain. In Jest and similar tools you can always mock Meteor APIs, but I usually don’t rely on it much, for Meteor specific testing I use another strategy for testing.
For integration logic, I use meteortesting:mocha. The idea here is to validate how your business logic works inside the real Meteor environment. I rely on the current Meteor testing infrastructure to test real interactions. It can be slower, but it lets you filter tests and keep a good dev loop, while matching the final runtime behavior. Here you directly test Meteor-specific APIs such as Mongo collections, methods, and subscriptions.
For E2E tests, the idea is to describe real use cases from your frontend and backend expectations. I go with Playwright because it is stable and designed to reduce flaky behavior. It also provides automatic recording of actions in your frontend, which makes it easier to write specs. These tests validate the full behavior of the app from the user perspective.
Of course, E2E provides the most behavior coverage since it tests the full presentation of your app and everything involved. The idea is not to test everything, but to identify the critical points and focus on what gives you better coverage and maintenance.
In the future, on the Meteor core side, hopefully we can rethink test tools and how we integrate them, so testing can evolve beyond Mocha and support faster and new strategies like snapshot testing. Testing in Meteor should evolve to support faster and more flexible strategies.
Maybe after Rspack integration, we could consider rstest as a quick win for Meteor-side testing improvements.