This episode covers Jest migration and upgrades: upgrading versions safely, migrating from other frameworks, handling breaking changes and test refactoring, and maintaining long-term suite stability.

Jest keeps evolving, and so must your suite. Episode 18 covers migrating & upgrading Jest — the process of upgrading versions safely, migrating from other testing frameworks, handling breaking changes and test refactoring, and maintaining long-term suite stability.
A careless migration can stop an entire team for days. With a structured approach, upgrading becomes a calm, predictable routine.
Before upgrading, know where you stand:
npx jest --version
npm outdated jestnpx jest --version shows the installed version, while npm outdated jest shows the latest available version. Also note the major changes between versions — every major version usually has a list of breaking changes in its release notes.
Never jump several major versions at once without a pause. The safe steps:
npm install --save-dev jest@29
npm testThe command npm install --save-dev jest@29 pins a specific major version explicitly. Run npm test afterward; the failures that appear are a real to-do list for fixes.
Mocha, Jasmine, and Ava use patterns similar to Jest. Most tests can be mapped directly:
describe and it → already identical in Jest.expect(x).to.equal(y) → expect(x).toBe(y).assert.ok → expect(x).toBeTruthy().// Sebelum (Chai):
// expect(nilai).to.be.above(10);
// Sesudah (Jest):
test("nilai di atas 10", () => {
expect(nilai).toBeGreaterThan(10);
});expect(nilai).toBeGreaterThan(10) is Jest's equivalent of expect(nilai).to.be.above(10). This mapping can be done mechanically for most tests.
Sinon and other spy libraries need to be mapped to Jest's mocking engine: sinon.spy becomes jest.spyOn, sinon.stub becomes jest.fn with mockReturnValue, and sinon.mock is replaced by the jest.mock pattern. Focus your attention here — mocking is the part of migration that most often causes surprises.
Some categories of breaking changes are common when upgrading Jest:
transform configuration that must be adjusted.testEnvironment.For snapshots that change due to a new format, run --updateSnapshot only after verifying the diff — don't accept it blindly.
Refactoring tests isn't just fixing failures. It's an opportunity to clean up: remove duplicate tests, merge same-pattern ones with test.each, and split helpers that have grown too large. Clean tests are easier to maintain when the next upgrade comes.
Suite stability is a product of habits, not luck. A few practices that keep a suite stable:
for i in 1 2 3; do npm test || break; doneThe command npm test || break inside a loop runs the suite three times to detect flakiness. If the suite fails only on certain iterations, there's a non-deterministic test that needs investigation.
Episode 18 covered migration and upgrades: upgrading versions gradually and safely, mapping APIs when migrating from another framework, handling breaking changes with ordered refactoring, and maintaining suite stability through long-term habits.
Key takeaways:
test.each for same patterns.In the next episode, episode 19, we'll cover operational readiness & runbooks — runbooks for failing suites and flaky tests, managing debugging and test ownership, large-scale maintenance strategies, and recovery from test regressions.