I'm experiencing frustrating Jest coverage inconsistencies in my React project. When I run tests for individual files in isolation, I get perfect 100% coverage as expected. However, when I run the complete test yarn test --coverage , the coverage results become unreliable and inconsistent. \certain lines randomly show as uncovered across different test runs, even though I know these lines are being properly tested.
The problem seems to affect some files particularly, and they "take turns" showing incomplete coverage. One run might show file A with missing coverage, while the next run shows file B with missing coverage, seemingly at random.
jest.config.ts
import type { Config } from 'jest'; import nextJest from 'next/jest.js'; const createJestConfig = nextJest({ dir: './', }); const config: Config = { coverageProvider: 'v8', testEnvironment: 'jsdom', clearMocks: true, restoreMocks: true, resetMocks: true, preset: 'ts-jest', testEnvironmentOptions: { url: 'http://localhost' }, setupFilesAfterEnv: ['./jest.setup.tsx'], collectCoverageFrom: ['src/**/*.{ts,tsx}'], coveragePathIgnorePatterns: [ '/node_modules/', 'src/app/layout.tsx', 'src/i18n/', 'typings.d.ts', 'stories.tsx', 'sanityClient.ts', 'src/app/stores/index', ], moduleNameMapper: { 'lucide-react': require.resolve('lucide-react'), '^components/(.*)$': '<rootDir>/src/app/components/$1', '^stores$': '<rootDir>/src/app/stores', '^stores/(.*)$': '<rootDir>/src/app/stores/$1', '^designSystem/(.*)$': '<rootDir>/src/app/designSystem/$1', '^lib/(.*)$': '<rootDir>/src/app/lib/$1', '^pdp/(.*)$': '<rootDir>/src/app/pdp/$1', '^akills/(.*)$': '<rootDir>/src/app/skills/$1', '^home/(.*)$': '<rootDir>/src/app/home/$1', '^@/(.*)$': '<rootDir>/src/app/$1', }, }; export default createJestConfig(config); jest.setup.tsx
import 'react'; import '@testing-library/jest-dom'; export const mockEmblaApi = { scrollPrev: jest.fn(), scrollNext: jest.fn(), scrollTo: jest.fn(), selectedScrollSnap: jest.fn().mockReturnValue(0), canScrollPrev: jest.fn().mockReturnValue(false), canScrollNext: jest.fn().mockReturnValue(false), on: jest.fn(), off: jest.fn(), reInit: jest.fn(), }; export const updateMockEmblaApi = (updates: Partial<typeof mockEmblaApi>) => { Object.assign(mockEmblaApi, updates); }; jest.mock('embla-carousel-react', () => { return { __esModule: true, default: () => [jest.requireActual('react').createRef(), mockEmblaApi], }; }); module.exports = { updateMockEmblaApi, mockEmblaApi }; const mockSanity = { fetch: jest.fn().mockResolvedValue([]), }; jest.mock('./src/app/lib/sanityClient', () => ({ sanityClient: mockSanity })); jest.mock('./src/app/stores', () => ({ useCategoriesStore: jest.fn(), useSkillsStore: jest.fn(), useFiltersStore: jest.fn(), useSortStore: jest.fn(), useRefinementStore: jest.fn(), useSkillProductsStore: jest.fn(), usePortfolioSettingsStore: jest.fn(), })); jest.mock('next/navigation', () => ({ ...jest.requireActual('next-router-mock/navigation'), notFound: jest.fn(), })); What I've already tried:
Added
resetMocks: trueto Jest config (but this introduced React hook errors)Used
clearMocksand various reset configurationsAttempted to isolate modules
Fixed numerous individual tests
I'd like to diagnose and fix this issue. any help is appreciated.