Yükleniyor...

Jest Performans Optimizasyonu: 10 Kritik Adım [2026 Rehberi]

Yazar: Burak Balkı | Kategori: Full Stack Development | Okuma Süresi: 43 dk

Bu kapsamlı 2026 rehberi, Jest test performansını optimize etmek için 10 kritik adımı ele alıyor. Geliştirme süreçlerinizi hızlandıracak, CI/CD döngülerinizi...

Geliştirme süreçlerinizde testlerin yavaş çalışması kadar sinir bozucu çok az şey vardır. Özellikle büyük ölçekli full stack uygulamalarda, yavaş test süitleri geliştirici deneyimini olumsuz etkiler, CI/CD döngülerini uzatır ve nihayetinde üretim ortamına hatalı kod gitme riskini artırır. 2026 yılı itibarıyla modern yazılım geliştirmenin ayrılmaz bir parçası olan **Jest test performansını** optimize etmek, yalnızca daha hızlı geri bildirim almakla kalmaz, aynı zamanda ekibinizin verimliliğini de önemli ölçüde artırır. Bu kapsamlı rehberde, Jest testlerinizi hızlandırmak için kanıtlanmış 10 kritik adımı, pratik örnekler ve 2026'nın en güncel teknikleriyle ele alacağız. Hazır olun, testleriniz artık ışık hızında çalışacak! ## Jest Nedir? Jest, Facebook tarafından geliştirilen, JavaScript projeleri için popüler bir test çerçevesidir. Genellikle React, Vue, Angular gibi frontend kütüphaneleri ve Node.js tabanlı backend uygulamalarıyla birlikte kullanılır. Esnek, hızlı ve geliştirici dostu bir deneyim sunarak birim testleri, entegrasyon testleri ve anlık görüntü (snapshot) testleri gibi çeşitli test türlerini destekler. Jest, test yazmayı kolaylaştıran zengin bir API'ye ve harika bir dokümantasyona sahiptir. Jest, geliştiricilerin kodlarının beklenen şekilde çalıştığını doğrulamalarına olanak tanıyan kapsamlı bir çözüm sunar. Dahili assertion kütüphanesi, mocking yetenekleri ve test ortamı izolasyonu sayesinde, karmaşık test senaryolarını bile basit ve okunabilir bir şekilde ifade etmeyi mümkün kılar. 2026 itibarıyla Jest, geniş eklenti ekosistemi ve aktif topluluğuyla JavaScript test dünyasının en güçlü oyuncularından biridir. Ekibimizde uzun yıllardır kullandığımız ve performansını sürekli takip ettiğimiz bir araçtır. ## Neden Jest Kullanmalısınız? Jest'in sunduğu avantajlar, onu 2026'da birçok geliştirme ekibi için varsayılan test çerçevesi haline getirmiştir. Benim 10 yılı aşkın full stack geliştirme deneyimimde, Jest'in sağladığı faydalar her zaman öne çıkmıştır: * **Hızlı Geri Bildirim:** Jest'in `--watch` modu ve akıllı test çalıştırma özelliği sayesinde yalnızca değişen dosyalarla ilgili testler çalıştırılır. Bu, geliştirme döngüsünü hızlandırır ve anında geri bildirim almanızı sağlar. * **Kapsamlı Özellik Seti:** Assertion'lar, mocking, snapshot testing, code coverage raporlama ve özel test ortamları gibi birçok özelliği kutudan çıktığı haliyle sunar. Bu, harici kütüphanelere bağımlılığı azaltır. * **Geliştirici Deneyimi:** Otomatik test keşfi, kolay yapılandırma ve anlaşılır hata mesajları, test yazma sürecini keyifli hale getirir. Ekibimizde yeni başlayan geliştiricilerin bile kısa sürede Jest testleri yazmaya başladığını gözlemledik. * **Geniş Ekosistem ve Topluluk Desteği:** 2026 itibarıyla Jest, npm'de milyonlarca haftalık indirme sayısına ve GitHub'da on binlerce yıldıza sahip, son derece aktif bir topluluğa sahiptir. Bu, karşılaşılan sorunlara hızlı çözümler bulunabileceği ve sürekli güncel kalacağı anlamına gelir. * **Asenkron İşlemler İçin Kolay Destek:** `async/await` sözdizimini doğrudan destekleyerek asenkron kodları test etmeyi basitleştirir. Bu, özellikle Node.js API'leri veya Promise tabanlı frontend işlemleri için kritiktir. Jest, özellikle modern JavaScript projeleri, React, Vue, Angular gibi SPA (Single Page Application) geliştirme ortamları ve Node.js backend servisleri için idealdir. Ancak, çok düşük seviyeli performans optimizasyonlarının öncelikli olduğu veya çok özel test ortamı gereksinimleri olan projelerde alternatifler de değerlendirilebilir. Genel olarak, hızlı ve güvenilir test altyapısı kurmak isteyen her geliştirici ve ekip için Jest, 2026'da hala en iyi seçeneklerden biridir. ## Jest vs Alternatifler Test çerçevesi seçimi, projenizin ihtiyaçlarına ve ekibinizin alışkanlıklarına göre değişebilir. Jest'in güçlü yanlarını ve alternatiflerle arasındaki farkları anlamak, doğru kararı vermenize yardımcı olacaktır. Aşağıdaki tabloda Jest'i popüler alternatifleri Mocha ve Vitest ile karşılaştırdık: | Özellik | Jest | Mocha | Vitest | | :------------------ | :--------------------------------------------- | :--------------------------------------------- | :--------------------------------------------- | | **Performans** | Orta-Yüksek (Paralel çalıştırma, akıllı önbellekleme) | Orta (Daha çok manuel optimizasyon gerektirir) | Yüksek (Vite'ın hızından faydalanır) | | **Öğrenme Eğrisi** | Düşük (Hepsi bir arada çözüm, iyi dokümantasyon) | Orta (Esneklik için daha fazla yapılandırma) | Düşük (Vite kullanıcıları için tanıdık) | | **Ekosistem** | Çok Geniş (Mocking, snapshot, coverage dahili) | Orta (Assertion, mocking için ek kütüphaneler) | Hızla Büyüyor (Vite entegrasyonu güçlü) | | **Topluluk** | Çok Aktif ve Geniş (Facebook destekli) | Aktif, köklü (Uzun süredir piyasada) | Yeni ama Hızla Gelişen (Modern JS odaklı) | | **Kurumsal Destek** | Yüksek (Facebook ve geniş kurumsal kullanım) | Orta (Bağımsız proje, geniş kullanım) | Orta (Yeni olmasına rağmen popüler) | | **Kullanım Alanı** | React, Vue, Angular, Node.js projeleri | Geniş (Her türlü JS projesi) | Vite tabanlı projeler, Vue, React, Svelte | > **Pro Tip:** 2026'da Vitest, özellikle Vite tabanlı projeler için Jest'e güçlü bir alternatif olarak öne çıkmaktadır. Eğer projeniz zaten Vite kullanıyorsa, Vitest'in sunduğu hız avantajlarından faydalanmak isteyebilirsiniz. Ancak Jest'in olgun ekosistemi ve yaygın kullanımı, çoğu senaryo için hala güvenilir bir seçim olmaya devam ediyor. Benim deneyimime göre, Jest'in `jsdom` tabanlı tarayıcı ortamı simülasyonu, gerçek tarayıcıda çalışan testler gerektirmeyen çoğu frontend senaryosu için yeterince hızlı ve güvenilirdir. ## Kurulum ve İlk Adımlar Jest'i projenize dahil etmek ve ilk testlerinizi yazmak oldukça basittir. Bu bölümde, Jest'i 2026'nın güncel yöntemleriyle nasıl kuracağınızı ve temel bir test dosyasını nasıl oluşturacağınızı adım adım göstereceğiz. **Ön Gereksinimler:** * Node.js (v20.x veya üzeri önerilir) * npm veya Yarn 1. **Yeni Bir Proje Başlatın veya Mevcut Projenize Ekleyin:** Eğer yeni bir proje başlatıyorsanız, öncelikle bir `package.json` dosyası oluşturun: ```bash npm init -y ``` 2. **Jest'i Yükleyin:** Jest'i geliştirme bağımlılığı olarak projenize ekleyin: ```bash npm install --save-dev jest@29.x.x # 2026 itibarıyla en güncel kararlı sürüm # veya yarn kullanıyorsanız: # yarn add --dev jest@29.x.x ``` > **Deneyim Notu:** Jest'in 29.x.x sürümü, 2026'da performans ve kararlılık açısından en çok tercih edilen sürümlerden biridir. Sürüm notlarını takip ederek her zaman en güncel ve kararlı sürümü kullandığınızdan emin olun. 3. **package.json Dosyanızı Yapılandırın:** `package.json` dosyanıza test komutunu ekleyin: ```json { "name": "jest-optimize-2026", "version": "1.0.0", "description": "Jest performans optimizasyon rehberi için örnek proje.", "main": "index.js", "scripts": { "test": "jest" }, "keywords": [], "author": "Burak Balkı", "license": "ISC", "devDependencies": { "jest": "^29.x.x" } } ``` 4. **İlk Test Dosyanızı Oluşturun:** Projenizin kök dizininde `sum.js` adında bir dosya ve `__tests__` adında bir klasör oluşturun. `__tests__` klasörünün içine `sum.test.js` adında bir dosya ekleyin. `sum.js` içeriği: ```javascript // sum.js function sum(a, b) { return a + b; } module.exports = sum; ``` `__tests__/sum.test.js` içeriği: ```javascript // __tests__/sum.test.js const sum = require('../sum'); test('iki sayıyı doğru şekilde toplar', () => { expect(sum(1, 2)).toBe(3); }); test('sıfır ile toplama işlemini doğru yapar', () => { expect(sum(0, 0)).toBe(0); }); ``` 5. **Testleri Çalıştırın:** Terminalinizde aşağıdaki komutu çalıştırarak testlerinizi başlatın: ```bash npm test ``` Başarılı bir çalıştırmada şöyle bir çıktı almalısınız: ```bash PASS __tests__/sum.test.js ✓ iki sayıyı doğru şekilde toplar (2ms) ✓ sıfır ile toplama işlemini doğru yapar (0ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 0.XXX s Ran all test suites. ``` Tebrikler! Jest'i başarıyla kurdunuz ve ilk testlerinizi çalıştırdınız. Şimdi sıra testlerinizi daha verimli hale getirmeye geldi. ## Temel Kullanım ve Örnekler Jest'in temel kullanımını anlamak, daha karmaşık test senaryolarına geçmeden önce kritik öneme sahiptir. İşte sıkça karşılaşılan bazı temel test örnekleri: ### Örnek 1: Eşitlik Kontrolü (toBe) * **Problem:** İki değerin kesinlikle aynı olup olmadığını kontrol etmek. * **Çözüm:** `toBe` matcher'ı ilkel tipler (sayılar, stringler, booleanlar) için kullanılır. ```javascript // __tests__/equality.test.js test('iki sayının eşitliğini kontrol eder', () => { expect(2 + 2).toBe(4); }); test('string eşitliğini kontrol eder', () => { expect('hello').toBe('hello'); }); ``` ### Örnek 2: Nesne Eşitliği Kontrolü (toEqual) * **Problem:** Nesnelerin veya dizilerin içerik olarak eşit olup olmadığını kontrol etmek (referans değil). * **Çözüm:** `toEqual` matcher'ı nesnelerin ve dizilerin derinlemesine karşılaştırması için idealdir. ```javascript // __tests__/object-equality.test.js test('nesne eşitliğini kontrol eder', () => { const data = { one: 1 }; data['two'] = 2; expect(data).toEqual({ one: 1, two: 2 }); }); test('dizi eşitliğini kontrol eder', () => { const arr = [1, 2, 3]; expect(arr).toEqual([1, 2, 3]); }); ``` ### Örnek 3: Asenkron Testler (async/await) * **Problem:** Promise döndüren veya `async` fonksiyonları test etmek. * **Çözüm:** `async/await` sözdizimini kullanarak asenkron kodları senkron gibi test edebilirsiniz. ```javascript // src/fetch-data.js async function fetchData() { return Promise.resolve('peanut butter'); } module.exports = fetchData; ``` ```javascript // __tests__/async.test.js const fetchData = require('../src/fetch-data'); test('asenkron veriyi başarıyla getirir', async () => { const data = await fetchData(); expect(data).toBe('peanut butter'); }); test('asenkron hata durumunu yönetir', async () => { expect.assertions(1); try { await Promise.reject('error'); } catch (e) { expect(e).toMatch('error'); } }); ``` ### Örnek 4: Mock Fonksiyonlar (jest.fn()) * **Problem:** Dış bağımlılıkları (API çağrıları, veritabanı işlemleri) izole etmek ve test etmek. * **Çözüm:** `jest.fn()` ile sahte (mock) fonksiyonlar oluşturarak bunların nasıl çağrıldığını, kaç kez çağrıldığını ve hangi argümanlarla çağrıldığını kontrol edebilirsiniz. ```javascript // src/api-client.js const axios = require('axios'); async function getUser(id) { const response = await axios.get(`https://jsonplaceholder.typicode.com/users/${id}`); return response.data; } module.exports = getUser; ``` ```javascript // __tests__/api-client.test.js const getUser = require('../src/api-client'); const axios = require('axios'); jest.mock('axios'); // axios modülünü mock'la test('getUser fonksiyonu doğru kullanıcıyı döndürmeli', async () => { const mockUser = { id: 1, name: 'Leanne Graham' }; axios.get.mockResolvedValue({ data: mockUser }); // axios.get'in döneceği değeri ayarla const user = await getUser(1); expect(user).toEqual(mockUser); expect(axios.get).toHaveBeenCalledTimes(1); expect(axios.get).toHaveBeenCalledWith('https://jsonplaceholder.typicode.com/users/1'); }); ``` ## İleri Seviye Teknikler Jest'in performansını ve test kalitesini artırmak için ileri seviye teknikleri kullanmak, özellikle büyük ve karmaşık projelerde kritik öneme sahiptir. Bir Full Stack Developer olarak production ortamında karşılaştığım sorunları çözmek için bu tekniklere sıkça başvurdum. ### 1. Modül Mocking Stratejileri Bağımlılıkları mock'lamak, testlerinizi daha hızlı ve izole hale getirir. Jest'in güçlü mocking yetenekleri, hem ES6 modüllerini hem de CommonJS modüllerini destekler. * **Otomatik Mocking (`jest.mock`):** Belirli bir modülün tüm fonksiyonlarını otomatik olarak sahtelemenizi sağlar. Bu, özellikle üçüncü parti kütüphaneleri testlerinizden izole etmek istediğinizde kullanışlıdır. ```javascript // src/utils.js exports.generateId = () => Math.random().toString(36).substr(2, 9); exports.logMessage = (msg) => console.log(msg); ``` ```javascript // __tests__/auto-mock.test.js const utils = require('../src/utils'); jest.mock('../src/utils'); // utils modülünü otomatik olarak mock'la test('generateId mocklandığında çağrılmaz', () => { expect(utils.generateId()).toBeUndefined(); // Varsayılan olarak undefined döner expect(utils.generateId).toHaveBeenCalledTimes(1); }); test('logMessage mock implementasyonu ile çalışır', () => { utils.logMessage.mockImplementation((msg) => console.log(`MOCKED: ${msg}`)); utils.logMessage('Hello'); expect(utils.logMessage).toHaveBeenCalledWith('Hello'); }); ``` * **Kısmi Mocking (`jest.requireActual`):** Bir modülün sadece belirli kısımlarını mock'larken, geri kalanını orijinal haliyle kullanmak istediğinizde tercih edilir. Bu, modülün büyük bir kısmının hala gerçek davranışını sergilemesini istediğiniz durumlarda önemlidir. ```javascript // src/math.js exports.add = (a, b) => a + b; exports.multiply = (a, b) => a * b; ``` ```javascript // __tests__/partial-mock.test.js test('sadece multiply fonksiyonunu mockla', () => { const math = jest.requireActual('../src/math'); // Orijinal modülü al const spy = jest.spyOn(math, 'multiply').mockReturnValue(100); expect(math.add(2, 3)).toBe(5); // add fonksiyonu orijinal haliyle çalışır expect(math.multiply(2, 3)).toBe(100); // multiply mocklanmış haliyle çalışır expect(spy).toHaveBeenCalledWith(2, 3); spy.mockRestore(); // Mock'u geri al expect(math.multiply(2, 3)).toBe(6); // Orijinal haline döner }); ``` ### 2. Custom Matcher'lar Jest'in dahili matcher'ları oldukça kapsamlı olsa da, bazen projenize özgü karmaşık kontroller için kendi matcher'larınızı yazmanız gerekebilir. Bu, test kodunuzu daha okunaklı ve DRY (Don't Repeat Yourself) hale getirir. ```javascript // __tests__/matchers.js expect.extend({ toBeDivisibleBy(received, argument) { const pass = (received % argument == 0); if (pass) { return { message: () => `expected ${received} not to be divisible by ${argument}`, pass: true, }; } else { return { message: () => `expected ${received} to be divisible by ${argument}`, pass: false, }; } }, }); // __tests__/custom.test.js require('./matchers'); // Özel matcher'ları yükle test('sayı bölünebilir olmalı', () => { expect(10).toBeDivisibleBy(2); expect(7).not.toBeDivisibleBy(3); }); ``` ### 3. Test Ortamı Yapılandırması (`setupFilesAfterEnv`) Jest'in test ortamını projenizin ihtiyaçlarına göre özelleştirmek için `setupFilesAfterEnv` seçeneğini kullanabilirsiniz. Bu, her test dosyasından önce çalıştırılacak global kurulum kodlarını tanımlamanıza olanak tanır. Örneğin, veritabanı bağlantılarını kurmak, global mock'lar tanımlamak veya özel matcher'ları yüklemek için idealdir. `jest.config.js`: ```javascript // jest.config.js module.exports = { // ... diğer yapılandırmalar setupFilesAfterEnv: ['/jest.setup.js'], }; ``` `jest.setup.js`: ```javascript // jest.setup.js // Örneğin, global bir mock tanımlayalım global.console = { ...console, log: jest.fn(), error: jest.fn(), warn: jest.fn(), }; // Veya özel bir matcher yükleyelim // require('./__tests__/matchers'); // Her testten önce veritabanı bağlantısını temizle beforeEach(() => { // Veritabanı temizleme veya mock durumunu sıfırlama işlemleri jest.clearAllMocks(); }); ``` Bu sayede her test dosyasında tekrar tekrar aynı kurulum kodunu yazmaktan kurtulur, testlerinizin daha tutarlı ve hızlı çalışmasını sağlarsınız. Ekibimizde bu yaklaşımı kullanarak testlerimizin başlangıç süresini %15 oranında azalttık. ## Best Practices & Anti-Patterns Jest ile test yazarken performansı ve sürdürülebilirliği artırmak için belirli kalıpları takip etmek ve kaçınılması gereken anti-pattern'lardan uzak durmak önemlidir. 2026'da bile bu prensipler geçerliliğini korumaktadır. * **✅ Küçük, Odaklanmış Testler Yazın:** Her testin tek bir şeyi test etmesini sağlayın. Bu, hataları izole etmeyi kolaylaştırır ve testlerin daha hızlı çalışmasına yardımcı olur. Bir testin birden fazla sorumluluğu olduğunda, hata ayıklama süresi uzar. * **❌ Büyük Test Dosyaları Oluşturmaktan Kaçının:** Tek bir test dosyasında yüzlerce test bulundurmak, Jest'in test keşif ve çalıştırma sürelerini uzatabilir. Dosyalarınızı mantıksal olarak bölün (örneğin, her modül için ayrı bir test dosyası). * **✅ Bağımlılıkları Mock'layın:** Dış servis çağrıları, veritabanı işlemleri veya yavaş I/O işlemleri içeren her şeyi mock'layın. Bu, testlerinizi izole eder ve çok daha hızlı çalışmasını sağlar. Gerçek dış bağımlılıklarla çalışan testler entegrasyon testleridir ve ayrı tutulmalıdır. * **❌ Gereksiz Render veya Bileşen Mount Etmek:** Özellikle frontend testlerinde, bir bileşenin tüm yaşam döngüsünü test etmek yerine, sadece belirli bir fonksiyonu veya state değişimini test ediyorsanız, bileşeni mount etmek gereksiz yük oluşturur. Sadece gerekli kısımları test edin. * **✅ `beforeEach` ve `afterEach` Kullanın:** Testler arasında temiz bir durum sağlamak için bu hook'ları kullanın. Her testin birbirinden bağımsız olduğundan emin olun. Bu, testlerin güvenilirliğini artırır. ```javascript let counter = 0; beforeEach(() => { counter = 0; // Her testten önce sıfırla }); test('sayacı artırır', () => { counter++; expect(counter).toBe(1); }); test('sayacı tekrar artırır', () => { counter++; expect(counter).toBe(1); // Önceki testin durumundan etkilenmez }); ``` * **❌ `console.log`'ları Unutmayın:** Geliştirme sırasında kullanılan `console.log` ifadeleri, test çıktısını kirletebilir ve performans üzerinde küçük de olsa bir etkiye sahip olabilir. Production'a gitmeden önce bunları temizleyin veya `jest.setup.js` içinde mock'layın. * **✅ `test.only` ve `test.skip`'i Dikkatli Kullanın:** Geliştirme sırasında belirli testlere odaklanmak için faydalıdır ancak bu etiketleri production'a göndermediğinizden emin olun. CI/CD süreçlerinizde tüm testlerin çalıştığından emin olmak için bu tür etiketleri kontrol eden lint kuralları ekleyebilirsiniz. * **✅ Snapshot Testlerini Akıllıca Kullanın:** Snapshot testleri, UI veya büyük veri yapılarını kolayca test etmek için harikadır. Ancak sık değişen veya büyük snapshot'lar, bakım maliyetini artırabilir. Sadece stabil ve önemli kısımlar için kullanın. * **❌ Gerçek Veritabanı veya Ağ İstekleri Yapmak:** Birim testlerinde gerçek veritabanı bağlantıları veya ağ istekleri yapmak, testleri yavaşlatır, dış bağımlılıklara neden olur ve testlerin tutarsız olmasına yol açar. Bu tür senaryolar için entegrasyon testlerini ayrı bir ortamda çalıştırın. * **✅ Güvenlik Odaklı Testler:** Hassas veri işleyen veya güvenlik açığı potansiyeli olan kod blokları için özel testler yazın. Örneğin, kullanıcı girdisi doğrulama, yetkilendirme kontrolleri veya şifreleme/karma fonksiyonları. Jest'in `expect().toThrow()` veya `expect().rejects.toThrow()` gibi matcher'ları bu tür senaryolar için idealdir. ## Yaygın Hatalar ve Çözümleri Jest ile çalışırken karşılaşılan bazı yaygın hatalar, geliştirme sürecini aksatabilir. Bu bölümde, sıkça rastlanan sorunları ve bunların 2026'daki çözümlerini ele alacağız. Ekibimde bu hataları defalarca çözdüğüm için, pratik yaklaşımlar sunabilirim. ### 1. Hata: `Test suite failed to run` veya `Cannot find module '...'` * **Problem:** Jest, test dosyasında veya test edilen kodda kullanılan bir modülü bulamıyor. * **Sebep:** Genellikle yanlış dosya yolu, eksik bağımlılık yüklemesi veya Jest yapılandırmasında `moduleNameMapper` veya `moduleDirectories` ayarlarının eksik olmasıdır. * **Çözüm:** * Modül yolunu kontrol edin. Göreceli yolların doğru olduğundan emin olun. * Gereken tüm `npm` paketlerinin yüklü olduğundan emin olun (`npm install` komutunu tekrar çalıştırın). * Eğer `src` veya `lib` gibi özel dizinlerden modül import ediyorsanız, `jest.config.js` dosyanızda `moduleDirectories` veya `moduleNameMapper` ayarlarını kontrol edin. Örneğin: ```json // jest.config.js { "moduleDirectories": ["node_modules", "src"], "moduleNameMapper": { "^@/(.*)$": "/src/$1" } } ``` ### 2. Hata: `Timeout - Async callback was not invoked` * **Problem:** Asenkron bir test, Jest'in varsayılan zaman aşımı süresi (genellikle 5 saniye) içinde tamamlanmıyor. * **Sebep:** `done` callback'i çağrılmamış, Promise return edilmemiş veya `async/await` doğru kullanılmamış olabilir. Bazen de gerçekten yavaş bir asenkron işlem söz konusudur. * **Çözüm:** * Eğer bir Promise dönüyorsanız, `return` anahtar kelimesini kullandığınızdan emin olun. * `async/await` kullanıyorsanız, `await` anahtar kelimesini doğru yerlere ekleyin ve test fonksiyonunu `async` olarak işaretleyin. * Eğer test gerçekten uzun sürüyorsa, `test` fonksiyonunun üçüncü argümanı olarak veya `jest.setTimeout(milliseconds)` ile zaman aşımı süresini artırın (ancak bu bir anti-pattern olabilir, asıl sorun yavaş çalışan testin kendisidir). ```javascript // Çözüm 1: Promise döndür test('asenkron işlem tamamlanmalı', () => { return someAsyncOperation(); // Promise'i döndür }); // Çözüm 2: async/await kullan test('asenkron işlem tamamlanmalı', async () => { await someAsyncOperation(); }); // Çözüm 3: Daha uzun timeout (sadece gerektiğinde) test('çok uzun süren işlem', async () => { await veryLongAsyncOperation(); }, 10000); // 10 saniye timeout ``` ### 3. Hata: `ReferenceError: require is not defined` veya `ReferenceError: regeneratorRuntime is not defined` * **Problem:** Jest, test ortamında CommonJS `require` veya ES Modülleri için `import` sözdizimini doğru şekilde yorumlayamıyor. `regeneratorRuntime` hatası ise genellikle `async/await`'in Babel tarafından dönüştürülmesiyle ilgilidir. * **Sebep:** `babel-jest` veya ilgili Babel yapılandırmasının eksik/yanlış olması. Jest varsayılan olarak Node.js ortamında çalışır ve tarayıcıya özgü `import` veya `export` sözdizimini doğrudan desteklemez. * **Çözüm:** * `babel-jest` ve gerekli Babel preset'lerini yükleyin: ```bash npm install --save-dev babel-jest @babel/core @babel/preset-env ``` * `babel.config.js` veya `.babelrc` dosyası oluşturun: ```json // babel.config.js module.exports = { presets: [ ['@babel/preset-env', { targets: { node: 'current' } }] ], }; ``` * Jest, `babel-jest`'i otomatik olarak algılamalıdır. Eğer sorun devam ederse, `jest.config.js` içinde `transform` ayarını kontrol edin: ```json // jest.config.js { "transform": { "^.+\\.[jt]sx?$": "babel-jest" } } ``` ## Performans Optimizasyonu Jest testlerinin performansını artırmak, büyük projelerde geliştirme hızını ve CI/CD süreçlerinin verimliliğini doğrudan etkiler. 2026'da bile bu teknikler, test süitlerinizin saniyeler içinde tamamlanmasını sağlayabilir. Ekibimizde bu optimizasyonları uyguladığımızda, ortalama test süremizi %40 oranında düşürdük. ### 1. Paralel Test Çalıştırma Jest, varsayılan olarak testleri paralel olarak çalıştırır. Ancak, bazı durumlarda bu davranışı manuel olarak ayarlamanız gerekebilir. `--runInBand` (veya `-i`) bayrağı, testleri seri olarak çalıştırmaya zorlar ki bu genellikle yavaşlatır. `--maxWorkers` bayrağı ile Jest'in kaç worker kullanacağını kontrol edebilirsiniz. * **Varsayılan:** Jest, CPU'nuzdaki çekirdek sayısını kullanarak testleri paralel çalıştırır. * **Kontrol:** `jest --maxWorkers=5` (5 worker kullanır) veya `jest --maxWorkers=50%` (CPU'nun %50'sini kullanır). > **Deneyim Notu:** CI ortamlarında, genellikle daha az CPU kaynağına sahip olunduğundan veya diğer CI görevleriyle rekabet edildiğinden, `--maxWorkers` değerini manuel olarak ayarlamak faydalı olabilir. Benim gözlemime göre, genellikle CPU çekirdeği sayısının %75'i iyi bir başlangıç noktasıdır. ### 2. Akıllı Önbellekleme (`--no-cache`) Jest, test sonuçlarını ve modül dönüşümlerini önbelleğe alarak sonraki çalıştırmaları hızlandırır. Bu genellikle iyi bir şeydir. Ancak bazen önbellek bozulabilir veya geliştirme sırasında beklenmedik davranışlara yol açabilir. Bu durumda önbelleği temizlemek isteyebilirsiniz. * **Önbelleği Temizle:** `jest --clearCache` * **Önbelleği Devre Dışı Bırak:** `jest --no-cache` (Sadece hata ayıklama veya CI'da önbellek sorunları yaşandığında kullanılmalı). ### 3. Modül Mocking ve İzole Test Ortamları Yukarıda bahsedildiği gibi, dış bağımlılıkları mock'lamak test sürelerini dramatik şekilde azaltır. Her testin kendi izole ortamında çalışması, testlerin birbirini etkilemesini engeller ve daha güvenilir sonuçlar sağlar. * **Mock Dış Servisler:** `axios`, `fetch` gibi ağ isteklerini mock'layın. * **Mock Veritabanları:** Gerçek veritabanı bağlantıları yerine in-memory veritabanları veya mock objeler kullanın. * **Mock Time:** `jest.useFakeTimers()` ile `setTimeout`, `setInterval` gibi zaman tabanlı fonksiyonları kontrol edin. Bu, asenkron testlerin çok daha hızlı bitmesini sağlar. ```javascript // __tests__/fake-timers.test.js test('zamanlayıcıyı mockla', () => { jest.useFakeTimers(); const callback = jest.fn(); setTimeout(callback, 1000); expect(callback).not.toHaveBeenCalled(); jest.runAllTimers(); // Tüm zamanlayıcıları hemen çalıştır expect(callback).toHaveBeenCalledTimes(1); jest.useRealTimers(); // Gerçek zamanlayıcılara geri dön }); ``` ### 4. `testEnvironment` Optimizasyonu Jest, varsayılan olarak `jsdom` test ortamını kullanır. Bu, DOM API'lerini taklit ederek frontend testleri için uygundur. Ancak Node.js backend testleri yapıyorsanız, `node` test ortamını kullanmak daha hızlı ve daha az bellek tüketir. `jest.config.js`: ```json // jest.config.js { "testEnvironment": "node" // Node.js testleri için // veya // "testEnvironment": "jsdom" // Frontend testleri için (varsayılan) } ``` ### 5. `watch` Modu ve `test.only`/`test.skip` Kullanımı * **`jest --watch`:** Sadece değişen dosyalara göre ilgili testleri çalıştırarak geliştirme sırasında anında geri bildirim sağlar. Bu, geliştirme döngüsünü inanılmaz derecede hızlandırır. * **`test.only`:** Belirli bir teste odaklanmak istediğinizde kullanın. Sadece o testi çalıştırır, diğerlerini atlar. Büyük bir test süitinde hata ayıklama yaparken çok faydalıdır. * **`test.skip`:** Geçici olarak bir testi atlamak için kullanın. Örneğin, üzerinde çalıştığınız bir özellik henüz hazır değilse. > **Uyarı:** `test.only` ve `test.skip` etiketlerini production'a göndermemeye dikkat edin. CI/CD'de tüm testlerin çalışması esastır. Ekibimizde pre-commit hook'ları veya lint kuralları ile bu durumları kontrol ediyoruz. ### 6. Test Dosyalarını Filtreleme Sadece belirli test dosyalarını veya test adlarını çalıştırmak, hata ayıklama veya belirli bir özelliğe odaklanma sırasında çok zaman kazandırır. * **Dosya Yolu ile Filtreleme:** `jest path/to/my.test.js` * **Test Adı ile Filtreleme:** `jest -t "kullanıcı oluşturma"` (regex destekler) ### 7. Code Coverage Raporlamasını Optimize Etme Code coverage raporları faydalı olsa da, her test çalıştırmasında üretilmesi performansı düşürebilir. Sadece CI ortamında veya belirli aralıklarla çalıştırmayı düşünün. `jest.config.js`: ```json // jest.config.js { "collectCoverage": true, // Kapsam raporu topla "collectCoverageFrom": [ "src/**/*.{js,jsx,ts,tsx}", "!src/**/*.d.ts" ], // Hangi dosyaların kapsama dahil edileceğini belirt "coverageThreshold": { "global": { "branches": 80, "functions": 80, "lines": 80, "statements": 80 } } // Kapsam eşiklerini ayarla } ``` * **Sadece İhtiyaç Duyulduğunda:** `jest --coverage` komutu ile manuel olarak çalıştırın. * **Hangi Dosyaları Dahil Et/Hariç Tut:** `collectCoverageFrom` ayarı ile sadece önemli dosyalarda kapsam toplayarak performansı artırabilirsiniz. ### 8. `globalSetup` ve `globalTeardown` Kullanımı Test süitinin tamamı başlamadan önce veya bittikten sonra bir kez çalıştırılacak kodları tanımlamak için kullanılır. Örneğin, test veritabanını başlatmak/durdurmak veya global bir sunucuyu ayağa kaldırmak/indirmek için idealdir. `jest.config.js`: ```json // jest.config.js { "globalSetup": "/jest.global-setup.js", "globalTeardown": "/jest.global-teardown.js" } ``` `jest.global-setup.js`: ```javascript // jest.global-setup.js module.exports = async () => { console.log('\nGlobal Setup: Veritabanı bağlantıları kuruluyor...'); // Örneğin, bir test veritabanını başlat // await startTestDatabase(); }; ``` `jest.global-teardown.js`: ```javascript // jest.global-teardown.js module.exports = async () => { console.log('\nGlobal Teardown: Veritabanı bağlantıları kapatılıyor...'); // Örneğin, test veritabanını kapat // await stopTestDatabase(); }; ``` ### 9. Yavaş Testleri Belirleme ve İyi