I'm building a CI pipeline from scratch for a React/Node.js project. I don't want the pipeline to take 30 minutes to run, but I also want to make sure we don't push bugs to production. What is the right balance of Unit, Integration, and End-to-End (E2E) tests that should run on every pull request?
3 answers
You should follow the "Testing Pyramid" philosophy. 70-80% of your suite should be Unit tests—they are lightning-fast and run in seconds. Then, add Integration tests (about 15-20%) to ensure your API and Database communicate correctly. Finally, keep your E2E tests (like Cypress or Playwright) to a minimum—maybe only the "happy path" for login and checkout. E2E tests are "flaky" and slow. In the CI, run Unit and Integration tests on every commit. Save the heavy E2E tests for the "Merge to Main" step or run them in parallel to keep the developer's feedback loop under 5-10 minutes.
Should we use "Sharding" to run tests in parallel if the suite starts getting too long for a single runner?
Don't forget Linting and Static Analysis (like SonarQube). They catch "stupid" bugs and style issues without even needing to execute the code.
Spot on, Cynthia. Linting is the fastest "test" you can run and saves so much time during the manual code review process
Absolutely, Paul! Parallelization is the only way to scale a test suite. Most modern CI tools like GitHub Actions or GitLab CI allow you to define a "Matrix" strategy. You can split your tests into 4 or 5 parallel jobs. If you have 20 minutes of tests, 4 shards can bring that down to about 5-6 minutes. Just ensure your tests are truly independent and don't rely on the same shared database state, otherwise, parallel runs will fail randomly due to "Race Conditions" in your test data.