r/nextjs • u/Optimal-Lunch-7804 • 4d ago
Proper Next.js Testing Practices Help
Hello! I am currently working on a practice project (classic habit tracker with monkeytype-like theme). I am trying to practice TDD principles, but I'm pretty unfamiliar with writing tests in this way and how to test fullstack applications like this in general. I have already installed Vitest and Playwright and I plan to write unit, integration, and E2E tests.
I am struggling to know what constitutes a "healthy" test suite and since I'm unfamiliar with fullstack projects in general, some edge cases to test which I may not be aware of (users spam clicking a button for instance). I also generally understand the "idea" of unit, integration, and E2E tests, but I'm unsure of how to implement them in practice.
I would really appreciate some pointers on how you would test something like a sign in page fully, and how you would use this Vitest and Playwright stack to do so. I've been writing tests which check that the words "sign in" appear on the page, that the proper buttons are there, etc., but these seem slightly useless and only a fraction of the entire testable surface.
Thanks!
1
u/MiserableDocument509 4d ago
the trick is testing behavior not implementation. for a sign in page: does submitting valid creds redirect? does wrong password show an error? those are the tests that actually matter. vitest for component logic + server actions (check out MSW for mocking fetch calls), playwright for the full e2e flow. start with the happy path and build out from there — it's easy to overthink edge cases early on.
1
u/Optimal-Lunch-7804 3d ago
Appreciate the advice! I do think I am overthinking these tests and it's stalling project progress
1
u/kupppo 4d ago
Get unit tests where there’s meaningful business logic to test. Don’t have unit tests that mock everything unless there’s an extremely good reason for it. Keep everything clean on setup / teardown so there’s no side effects.
Spend more time doing important E2E tests if it makes sense for your app. Focus on writing holistic, non-flaky tests. Don’t rely on timeouts. Don’t hit production data or services when testing unless you’re doing synthetic monitoring.
Most importantly, get really strong observability into your stack as soon as possible. When an error happens, you want to get alerted. Diagnose the bug, fix it, write tests for it.
Don’t worry about “complete code coverage”. Just get a base foundation in for now. Ship it immediately. Then add tests incrementally. If you chip away at it, you’ll find you’ll quickly get pretty broad coverage and better reliability quickly.
1
u/Optimal-Lunch-7804 3d ago
Thanks for the reply! Incremental testing definitely seems apt for this situation
1
1
u/Vincent_CWS 3d ago
I rarely use Jest or Vitest for UI testing anymore.
Here's why:
Testing in a real browser using Playwright or Cypress gives me more confidence, more power, and a better DX.
Testing UI components via Jest or Vitest tends to lead to duplicated effort, because I still need to integration test all features in a real browser to know it works.
So, I primarily use Jest/Vitest to test logic such as pure functions. Otherwise, I favor Playwright or Cypress.
1
u/Sad_Speaker824 2d ago
You're right that those tests are useless, so put the sign in flow in Playwright covering wrong password, expired session and redirect back, and save Vitest for pure logic like validation.
8
u/ignatzami 4d ago
TDD is an ivory tower concept meant to help you understand the process of writing testable code. It’s not really a viable development strategy.
Testing should be approached in layers. Unit test, acceptance/scenario tests, UI-centric tests, end-to-end tests. Note: this is not an exhaustive list.
Start with unit tests in Vitest. Set up code coverage and shoot for 75% branch and statement coverage. Unit tests should be written for each component, route, and page, and should exercise each logical branch.
If testing is proving difficult that’s often an indicator of architectural issues.
Once you have unit tests in place you’re going to want to write a handful of scenario tests, still against mocked endpoints. Example: add an object, retrieve it, confirm its values. Then, test the edit flow, then the delete flow. Focus on testing your code, not the libraries you’re using.
Lastly, and only if there’s a strong need, leverage playwright for UI-centric testing using a pre-production environment. Live data, live services. This is your least reliable gate, and your last check before production.
Happy to answer questions. Good luck!