{"id":32964,"date":"2025-10-27T23:03:15","date_gmt":"2025-10-27T20:03:15","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/"},"modified":"2025-10-27T23:03:15","modified_gmt":"2025-10-27T20:03:15","slug":"angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/","title":{"rendered":"Angular&#8217;da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut"},"content":{"rendered":"<p><body><\/p>\n<p>Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular test s\u00fcre\u00e7lerinizi nas\u0131l ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftirebilece\u011finizi ke\u015ffedin. Performans, h\u0131z ve g\u00fcvenilirli\u011fi art\u0131rarak geli\u015ftirici deneyiminizi zirveye ta\u015f\u0131y\u0131n.<\/p>\n<p>Modern web uygulamalar\u0131 geli\u015ftirmek, \u00f6zellikle Angular gibi kapsaml\u0131 bir framework ile \u00e7al\u0131\u015f\u0131rken, s\u00fcrekli de\u011fi\u015fen gereksinimler ve karma\u015f\u0131k etkile\u015fimlerle dolu bir yolculuktur. Bu yolculu\u011fun olmazsa olmaz bir par\u00e7as\u0131 da testtir. Ancak, geli\u015ftiricilerin en s\u0131k kar\u015f\u0131la\u015ft\u0131\u011f\u0131 sorunlardan biri, test s\u00fcitlerinin zamanla yava\u015flamas\u0131d\u0131r. \u00d6zellikle b\u00fcy\u00fck \u00f6l\u00e7ekli Angular projelerinde Karma, Jasmine veya Jest tabanl\u0131 testlerin ba\u015flang\u0131\u00e7 s\u00fcreleri uzayabilir, test \u00e7al\u0131\u015ft\u0131rma s\u00fcreleri dakikalar\u0131 bulabilir. Bu durum, h\u0131zl\u0131 geri bildirim d\u00f6ng\u00fcs\u00fcn\u00fc engeller ve geli\u015ftirici \u00fcretkenli\u011fini olumsuz etkiler. Yava\u015f testler, geli\u015ftirme motivasyonunu d\u00fc\u015f\u00fcr\u00fcr ve hatalar\u0131n ge\u00e7 fark edilmesine yol a\u00e7abilir.<\/p>\n<p>Peki, Angular test s\u00fcre\u00e7leriniz neden yava\u015fl\u0131yor? Temel nedenler aras\u0131nda \u015funlar say\u0131labilir:<\/p>\n<ol>\n<li><strong>A\u011f\u0131r Ba\u015flang\u0131\u00e7 Maliyetleri:<\/strong> Geleneksel test ko\u015fucular\u0131 (\u00f6rne\u011fin Karma), taray\u0131c\u0131 ortam\u0131n\u0131 ba\u015flatmak, mod\u00fclleri y\u00fcklemek ve derlemek i\u00e7in \u00f6nemli bir zaman harcar. Bu, her test \u00e7al\u0131\u015ft\u0131rmas\u0131nda tekrarlanan bir maliyettir ve \u00f6zellikle CI\/CD boru hatlar\u0131nda ciddi zaman kay\u0131plar\u0131na neden olabilir.<\/li>\n<li><strong>Mod\u00fcl \u00c7\u00f6z\u00fcmleme ve Derleme Karma\u015fas\u0131:<\/strong> Angular&#8217;\u0131n mod\u00fcler yap\u0131s\u0131 ve TypeScript&#8217;in derleme s\u00fcreci, test ortam\u0131nda da kendini g\u00f6sterir. \u00c7ok say\u0131da dosyan\u0131n i\u015flenmesi ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n \u00e7\u00f6z\u00fcmlenmesi, \u00f6zellikle b\u00fcy\u00fck ba\u011f\u0131ml\u0131l\u0131k a\u011fa\u00e7lar\u0131 olan projelerde zaman al\u0131c\u0131d\u0131r.<\/li>\n<li><strong>Gereksiz Taray\u0131c\u0131 \u0130\u015flemleri:<\/strong> Karma, genellikle Chrome gibi ger\u00e7ek bir taray\u0131c\u0131da testleri \u00e7al\u0131\u015ft\u0131r\u0131r. Bu, ek kaynak t\u00fcketimi ve daha yava\u015f \u00e7al\u0131\u015ft\u0131rma s\u00fcreleri anlam\u0131na gelir, \u00f6zellikle sunucusuz veya hafif CI\/CD ortamlar\u0131nda ek y\u00fck olu\u015fturur.<\/li>\n<li><strong>Boilerplate Kod:<\/strong> Angular&#8217;\u0131n <code>TestBed<\/code> gibi ara\u00e7lar\u0131 g\u00fc\u00e7l\u00fc olsa da, her bir bile\u015fen testi i\u00e7in tekrarlayan bir kurulum (boilerplate) gerektirir. Bu, hem kod miktar\u0131n\u0131 art\u0131r\u0131r hem de test yazma s\u00fcrecini yava\u015flat\u0131r, testlerin okunabilirli\u011fini d\u00fc\u015f\u00fcr\u00fcr.<\/li>\n<\/ol>\n<p>Bu zorluklar\u0131n \u00fcstesinden gelmek, daha h\u0131zl\u0131, daha verimli ve daha keyifli bir test deneyimi sa\u011flamak i\u00e7in sekt\u00f6r yeni ara\u00e7lara y\u00f6neliyor. \u0130\u015fte tam da bu noktada, Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut gibi modern \u00e7\u00f6z\u00fcmler devreye giriyor. Bu ara\u00e7lar, Angular test ekosisteminde ger\u00e7ek bir devrim niteli\u011findedir. Geleneksel y\u00f6ntemlerin aksine, bu yeni nesil ara\u00e7lar, testlerinizi saniyeler i\u00e7inde \u00e7al\u0131\u015ft\u0131rman\u0131za, asenkron i\u015flemleri etkili bir \u015fekilde y\u00f6netmenize ve karma\u015f\u0131k bile\u015fen testlerini basitle\u015ftirmenize olanak tan\u0131r. Art\u0131k yava\u015f test d\u00f6ng\u00fcleriyle m\u00fccadele etmek yerine, an\u0131nda geri bildirim alarak \u00e7ok daha \u00fcretken olabilirsiniz. Bu makalede, bu ara\u00e7lar\u0131n her birini derinlemesine inceleyecek ve Angular projenize nas\u0131l entegre edebilece\u011finizi ad\u0131m ad\u0131m g\u00f6sterece\u011fiz. H\u0131zl\u0131, g\u00fcvenilir ve s\u00fcrd\u00fcr\u00fclebilir bir test altyap\u0131s\u0131 kurmak i\u00e7in haz\u0131rsan\u0131z, bu devrimsel yolculu\u011fa ba\u015flayal\u0131m!<\/p>\n<h2>Vitest Nedir ve Angular Projelerinize Nas\u0131l Entegre Edilir?<\/h2>\n<p>Angular projelerinizdeki test h\u0131z\u0131n\u0131 art\u0131rmak ve geli\u015ftirici deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirmek mi istiyorsunuz? O zaman Vitest ile tan\u0131\u015fman\u0131z\u0131n tam zaman\u0131! Vitest, Vite tabanl\u0131, ultra h\u0131zl\u0131 bir birim test \u00e7er\u00e7evesidir. Vite&#8217;\u0131n ESM (ECMAScript Mod\u00fclleri) tabanl\u0131 mimarisini ve an\u0131nda mod\u00fcl hot-reloading (HMR) yeteneklerini kullanarak, testlerinizi inan\u0131lmaz bir h\u0131zda \u00e7al\u0131\u015ft\u0131r\u0131r. Geleneksel test ko\u015fucular\u0131na k\u0131yasla \u00e7ok daha hafif ve performans odakl\u0131d\u0131r. Bu modern yakla\u015f\u0131m, geli\u015ftiricilerin test d\u00f6ng\u00fcs\u00fcn\u00fc minimize ederek daha h\u0131zl\u0131 iterasyon yapmas\u0131na olanak tan\u0131r.<\/p>\n<h3>Vitest&#8217;in Avantajlar\u0131 Nelerdir?<\/h3>\n<p>Vitest, geli\u015ftiriciler i\u00e7in bir dizi cazip avantaj sunar:<\/p>\n<ul>\n<li><strong>S\u00fcper H\u0131zl\u0131 \u00c7al\u0131\u015ft\u0131rma S\u00fcreleri:<\/strong> Vite&#8217;\u0131n yerel ESM deste\u011fi sayesinde, testleriniz derleme ad\u0131m\u0131na gerek kalmadan do\u011frudan \u00e7al\u0131\u015f\u0131r. Bu, \u00f6zellikle k\u00fc\u00e7\u00fck de\u011fi\u015fikliklerde an\u0131nda geri bildirim alman\u0131z\u0131 sa\u011flar, bu da geli\u015ftirme ak\u0131\u015f\u0131n\u0131 kesintisiz hale getirir.<\/li>\n<li><strong>Geli\u015ftirici Deneyimi (DX):<\/strong> HMR deste\u011fi ile dosyalar\u0131 kaydetti\u011finiz anda ilgili testler otomatik olarak yeniden \u00e7al\u0131\u015ft\u0131r\u0131l\u0131r, bu da geli\u015ftirme ak\u0131\u015f\u0131n\u0131 kesintisiz hale getirir. Interaktif watch modu, testlerinizin her an g\u00fcncel kalmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Daha Hafif ve Basit Kurulum:<\/strong> Jest veya Karma&#8217;ya g\u00f6re daha az ba\u011f\u0131ml\u0131l\u0131\u011fa sahiptir ve kurulumu genellikle daha basittir. Bu, proje boyutunu k\u00fc\u00e7\u00fclt\u00fcr ve ba\u011f\u0131ml\u0131l\u0131k y\u00f6netimi karma\u015fas\u0131n\u0131 azalt\u0131r.<\/li>\n<li><strong>Jest ile Uyumluluk:<\/strong> Jest ile uyumlu bir API sundu\u011fu i\u00e7in, mevcut Jest testlerinizi kolayca Vitest&#8217;e ta\u015f\u0131yabilirsiniz. Mocking, spy ve assertion (beklenti) API&#8217;leri olduk\u00e7a tan\u0131d\u0131kt\u0131r, bu da \u00f6\u011frenme e\u011frisini d\u00fc\u015f\u00fcr\u00fcr.<\/li>\n<li><strong>Geni\u015f Entegrasyon:<\/strong> TypeScript, JSX\/TSX ve \u00e7e\u015fitli UI k\u00fct\u00fcphaneleriyle sorunsuz \u00e7al\u0131\u015f\u0131r. Ayr\u0131ca, kod kapsam\u0131 (code coverage) raporlamas\u0131 gibi geli\u015fmi\u015f \u00f6zellikler de sunar.<\/li>\n<\/ul>\n<h3>Angular Projelerinize Vitest Nas\u0131l Entegre Edilir? Ad\u0131m Ad\u0131m Rehber<\/h3>\n<p>Angular CLI, varsay\u0131lan olarak Karma ve Jasmine ile gelir. Vitest&#8217;i entegre etmek i\u00e7in birka\u00e7 manuel ad\u0131m izlememiz gerekecek. \u0130\u015fte bu d\u00f6n\u00fc\u015f\u00fcm\u00fc ger\u00e7ekle\u015ftirmek i\u00e7in yapman\u0131z gerekenler:<\/p>\n<h4>Ad\u0131m 1: Gerekli Paketleri Kurun<\/h4>\n<p>\u0130lk olarak, Angular projenizin k\u00f6k dizininde Vitest ve ilgili paketleri y\u00fcklemelisiniz. Bu paketler, test ortam\u0131n\u0131 kurmak ve Angular ile Vitest aras\u0131nda k\u00f6pr\u00fc kurmak i\u00e7in gereklidir:<\/p>\n<pre><code>\nnpm install -D vitest @vitest\/coverage-v8 @angular\/compiler-cli @angular\/platform-browser @angular\/platform-browser-dynamic happy-dom @testing-library\/angular @testing-library\/jest-dom\n<\/pre>\n<p><\/code><\/p>\n<p>Burada <code>happy-dom<\/code>, bir DOM ortam\u0131 sa\u011flar (taray\u0131c\u0131 yerine, Node.js ortam\u0131nda testlerin \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131na olanak tan\u0131r). <code>@testing-library\/angular<\/code> ise Angular bile\u015fenlerini daha eri\u015filebilir ve kullan\u0131c\u0131 odakl\u0131 bir \u015fekilde test etmenize yard\u0131mc\u0131 olur.<\/p>\n<h4>Ad\u0131m 2: Vitest Yap\u0131land\u0131rma Dosyas\u0131n\u0131 Olu\u015fturun<\/h4>\n<p>Projenizin k\u00f6k dizininde <code>vitest.config.ts<\/code> ad\u0131nda bir dosya olu\u015fturun ve i\u00e7ine a\u015fa\u011f\u0131daki i\u00e7eri\u011fi ekleyin. Bu dosya, Vitest'in nas\u0131l davranaca\u011f\u0131n\u0131 ve testlerinizi nerede bulaca\u011f\u0131n\u0131 belirler:<\/p>\n<pre><code>\nimport { defineConfig } from 'vitest\/config';\nimport { resolve } from 'path';\n\nexport default defineConfig({\n  test: {\n    globals: true, \/\/ global API'leri etkinle\u015ftirir (describe, it, expect vb.)\n    environment: 'happy-dom', \/\/ DOM ortam\u0131 sa\u011flar, taray\u0131c\u0131ya gerek kalmaz\n    setupFiles: [resolve(__dirname, 'src\/test-setup.ts')], \/\/ Test kurulum dosyam\u0131z\n    include: ['src\/**\/*.spec.ts'], \/\/ Test dosyalar\u0131n\u0131 belirler\n    exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'],\n    coverage: {\n      provider: 'v8', \/\/ Kod kapsam\u0131 raporu sa\u011flay\u0131c\u0131s\u0131\n      reporter: ['html', 'lcov', 'text'], \/\/ Rapor formatlar\u0131\n      exclude: [ \/\/ Kapsam d\u0131\u015f\u0131 b\u0131rak\u0131lacak dosyalar\n        'src\/main.ts',\n        'src\/polyfills.ts',\n        'src\/environments\/**',\n        'src\/**\/*.module.ts',\n        'src\/**\/*.routes.ts',\n        'src\/**\/*.config.ts',\n        'src\/**\/*.interface.ts',\n        'src\/app\/core\/constants\/**',\n      ],\n    },\n  },\n});\n<\/pre>\n<p><\/code><\/p>\n<h4>Ad\u0131m 3: Test Kurulum Dosyas\u0131n\u0131 Haz\u0131rlay\u0131n<\/h4>\n<p><code>src\/test-setup.ts<\/code> dosyas\u0131n\u0131 olu\u015fturun. Bu dosya, testlerin \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131ndan \u00f6nce Angular test ortam\u0131n\u0131 ba\u015flatmak ve gerekli polyfill'leri y\u00fcklemek i\u00e7in kullan\u0131l\u0131r. Bu, Angular'\u0131n Zone.js ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 ve test yata\u011f\u0131n\u0131 d\u00fczg\u00fcn bir \u015fekilde ba\u015flatmas\u0131n\u0131 sa\u011flar:<\/p>\n<pre><code>\nimport 'zone.js'; \/\/ Angular i\u00e7in gerekli\nimport 'zone.js\/testing'; \/\/ Angular testleri i\u00e7in gerekli\nimport { getTestBed } from '@angular\/core\/testing';\nimport {\n  BrowserDynamicTestingModule,\n  platformBrowserDynamicTesting\n} from '@angular\/platform-browser-dynamic\/testing';\nimport '@testing-library\/jest-dom\/extend-expect'; \/\/ @testing-library i\u00e7in expect geni\u015fleticiler\n\n\/\/ Angular test ortam\u0131n\u0131 ba\u015flat\ngetTestBed().initTestEnvironment(\n  BrowserDynamicTestingModule,\n  platformBrowserDynamicTesting(),\n  { teardown: { destroyAfterEach: true }} \/\/ Her testten sonra bile\u015fenleri temizle\n);\n<\/pre>\n<p><\/code><\/p>\n<h4>Ad\u0131m 4: <code>tsconfig.spec.json<\/code> G\u00fcncellemesi<\/h4>\n<p><code>tsconfig.spec.json<\/code> dosyan\u0131z\u0131 g\u00fcncelleyerek Vitest'in global t\u00fcr tan\u0131mlamalar\u0131n\u0131 ekleyin. Bu, TypeScript'in Vitest'in global fonksiyonlar\u0131n\u0131 tan\u0131mas\u0131n\u0131 sa\u011flar ve derleme hatalar\u0131n\u0131 \u00f6nler:<\/p>\n<pre><code>\n{\n  \"extends\": \".\/tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \".\/out-tsc\/spec\",\n    \"types\": [\n      \"vitest\/globals\", \/\/ Vitest'in global API'leri i\u00e7in\n      \"node\", \/\/ Node.js ortam\u0131 i\u00e7in (e\u011fer Node API'leri kullan\u0131l\u0131yorsa)\n      \"jest\", \/\/ @testing-library\/jest-dom i\u00e7in gerekli\n      \"vitest\/import\" \/\/ Yeni Vitest import y\u00f6ntemi i\u00e7in\n    ]\n  },\n  \"include\": [\n    \"src\/**\/*.spec.ts\",\n    \"src\/**\/*.d.ts\",\n    \"vitest.config.ts\"\n  ]\n}\n<\/pre>\n<p><\/code><\/p>\n<p><code>vitest\/globals<\/code> ve <code>jest<\/code> (<code>@testing-library\/jest-dom<\/code> i\u00e7in) t\u00fcrlerini eklemek, test dosyalar\u0131n\u0131zda hata almadan <code>describe<\/code>, <code>it<\/code>, <code>expect<\/code> gibi global fonksiyonlar\u0131 kullanman\u0131z\u0131 sa\u011flar.<\/p>\n<h4>Ad\u0131m 5: <code>package.json<\/code> Dosyas\u0131na Script Ekleyin<\/h4>\n<p><code>package.json<\/code> dosyan\u0131za Vitest'i \u00e7al\u0131\u015ft\u0131rmak i\u00e7in bir script ekleyin. Bu, Vitest'i komut sat\u0131r\u0131ndan kolayca tetiklemenizi sa\u011flar:<\/p>\n<pre><code>\n{\n  \"scripts\": {\n    \"test\": \"vitest\",\n    \"test:watch\": \"vitest --watch\",\n    \"test:coverage\": \"vitest run --coverage\"\n  }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Art\u0131k <code>npm run test<\/code> komutu ile Vitest'i \u00e7al\u0131\u015ft\u0131rabilir, <code>npm run test:watch<\/code> ile dosya de\u011fi\u015fikliklerini izleyebilir ve <code>npm run test:coverage<\/code> ile kapsam raporu olu\u015fturabilirsiniz!<\/p>\n<h4>Ad\u0131m 6: \u00d6rnek Bir Vitest Testi Yaz\u0131n<\/h4>\n<p>Mevcut bir <code>.spec.ts<\/code> dosyan\u0131z\u0131 Vitest ile \u00e7al\u0131\u015facak \u015fekilde g\u00fcncelleyin veya yeni bir dosya olu\u015fturun. \u00d6rne\u011fin, <code>app.component.spec.ts<\/code> dosyan\u0131z \u015f\u00f6yle g\u00f6r\u00fcnebilir:<\/p>\n<pre><code>\nimport { ComponentFixture, TestBed } from '@angular\/core\/testing';\nimport { AppComponent } from '.\/app.component';\n\ndescribe('AppComponent', () => {\n  let fixture: ComponentFixture<AppComponent>;\n  let app: AppComponent;\n\n  beforeEach(async () => {\n    await TestBed.configureTestingModule({\n      imports: [AppComponent], \/\/ Standalone componentler i\u00e7in\n    }).compileComponents();\n\n    fixture = TestBed.createComponent(AppComponent);\n    app = fixture.componentInstance;\n  });\n\n  it('should create the app', () => {\n    expect(app).toBeTruthy();\n  });\n\n  it(<code>should have the &#039;angular-vitest&#039; title<\/code>, () => {\n    expect(app.title).toEqual('angular-vitest');\n  });\n\n  it('should render title', () => {\n    fixture.detectChanges();\n    const compiled = fixture.nativeElement as HTMLElement;\n    expect(compiled.querySelector('h1')?.textContent).toContain('Hello, angular-vitest');\n  });\n});\n<\/pre>\n<p><\/code><\/p>\n<p>Bu testler, Vitest taraf\u0131ndan Jest uyumlu API'leri sayesinde sorunsuz bir \u015fekilde \u00e7al\u0131\u015ft\u0131r\u0131lacakt\u0131r. G\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, Vitest entegrasyonu, mevcut Angular testlerinizin \u00e7o\u011funu minimal de\u011fi\u015fikliklerle \u00e7al\u0131\u015ft\u0131rman\u0131za olanak tan\u0131r, ayn\u0131 zamanda size benzersiz bir h\u0131z ve verimlilik sunar. Bu entegrasyon sayesinde, geli\u015ftirme s\u00fcre\u00e7lerinizde testlere olan yakla\u015f\u0131m\u0131n\u0131z k\u00f6kten de\u011fi\u015fecektir.<\/p>\n<div class=\"interactive-element\">\n<p><strong>\u0130pu\u00e7lar\u0131:<\/strong> E\u011fer mevcut testlerinizde Zone.js ile ilgili hatalar al\u0131rsan\u0131z, <code>vitest.config.ts<\/code> dosyan\u0131zdaki <code>setupFiles<\/code> yolunun do\u011fru oldu\u011fundan ve <code>src\/test-setup.ts<\/code> dosyan\u0131z\u0131n t\u00fcm gerekli <code>zone.js<\/code> import'lar\u0131n\u0131 i\u00e7erdi\u011finden emin olun. Ayr\u0131ca, Angular'\u0131n standalone componentleri art\u0131k yayg\u0131nla\u015ft\u0131\u011f\u0131 i\u00e7in, <code>imports: [AppComponent]<\/code> yerine eski mod\u00fcl yap\u0131s\u0131n\u0131 kullan\u0131yorsan\u0131z <code>declarations<\/code> ve <code>imports<\/code> dizilerini uygun \u015fekilde d\u00fczenlemeyi unutmay\u0131n. Bu detaylar, sorunsuz bir ge\u00e7i\u015f i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<\/div>\n<h2>Sahte Zamanlay\u0131c\u0131lar (Fake Timers) ile Asenkron Kodlar\u0131 Y\u00f6netmek Neden \u00d6nemli?<\/h2>\n<p>Web uygulamalar\u0131nda asenkron i\u015flemler ka\u00e7\u0131n\u0131lmazd\u0131r. Bir kullan\u0131c\u0131 aray\u00fcz\u00fc gecikmeli olarak veri y\u00fckleyebilir, animasyonlar zamanlay\u0131c\u0131lar arac\u0131l\u0131\u011f\u0131yla tetiklenebilir veya belirli bir s\u00fcre sonra bir bildirim g\u00f6r\u00fcnt\u00fclenebilir. JavaScript'te <code>setTimeout<\/code>, <code>setInterval<\/code>, <code>requestAnimationFrame<\/code> gibi yerle\u015fik zamanlay\u0131c\u0131 fonksiyonlar\u0131, bu t\u00fcr senaryolar\u0131 y\u00f6netmek i\u00e7in kullan\u0131l\u0131r. Ancak, bu fonksiyonlar\u0131n birim testlerinde kullan\u0131lmas\u0131, test s\u00fcrecini yava\u015flatabilir ve testlerin deterministik olmas\u0131n\u0131 zorla\u015ft\u0131rabilir. Ger\u00e7ek zaman\u0131n test ortam\u0131na s\u0131zmas\u0131, \u00f6ng\u00f6r\u00fclemeyen sonu\u00e7lara ve \"flaky\" (bazen ge\u00e7en, bazen kalan) testlere yol a\u00e7abilir.<\/p>\n<h3>Sorun: Ger\u00e7ek Zaman\u0131n Testlere Etkisi<\/h3>\n<p>Varsay\u0131lan olarak, testlerinizdeki zamanlay\u0131c\u0131lar ger\u00e7ek zaman\u0131 kullan\u0131r. Bu ne anlama geliyor? E\u011fer kodunuzda 5 saniyelik bir gecikme varsa, testinizin de bu 5 saniyeyi beklemesi gerekir. Birka\u00e7 test i\u00e7in bu sorun olmayabilir, ancak y\u00fczlerce veya binlerce testiniz oldu\u011funda, bu gecikmeler test s\u00fcitinizin toplam \u00e7al\u0131\u015fma s\u00fcresini katlayarak art\u0131r\u0131r. Ayr\u0131ca, ger\u00e7ek zamanlay\u0131c\u0131lar testlerin s\u0131ras\u0131n\u0131 veya ortam\u0131n o anki durumunu etkileyebilece\u011fi i\u00e7in testleri k\u0131r\u0131lgan hale getirebilir. Bu durum, CI\/CD s\u00fcre\u00e7lerini yava\u015flat\u0131r ve geli\u015ftirici geri bildirim d\u00f6ng\u00fcs\u00fcn\u00fc uzat\u0131r.<\/p>\n<pre><code>\n\/\/ \u00d6rnek bir Angular servisindeki gecikmeli i\u015flem\n@Injectable({ providedIn: 'root' })\nexport class NotificationService {\n  showSuccess(message: string, duration: number = 3000) {\n    setTimeout(() => {\n      console.log(<code>Bildirim g\u00f6sterildi: ${message}<\/code>);\n    }, duration);\n  }\n}\n\n\/\/ Bu servisi test ederken 3 saniye beklemek zorunda kalmak istemeyiz!\n\/\/ Ger\u00e7ek zamanlay\u0131c\u0131lar, testlerin yava\u015flamas\u0131na ve hatta ba\u015far\u0131s\u0131z olmas\u0131na neden olabilir.\n<\/pre>\n<p><\/code><\/p>\n<h3>\u00c7\u00f6z\u00fcm: Vitest'in Sahte Zamanlay\u0131c\u0131lar\u0131 (Fake Timers)<\/h3>\n<p>Vitest, bu sorunu \u00e7\u00f6zmek i\u00e7in g\u00fc\u00e7l\u00fc sahte zamanlay\u0131c\u0131 (fake timers) yetenekleri sunar. <code>vi.useFakeTimers()<\/code> metodu ile Vitest'e, t\u00fcm yerle\u015fik zamanlay\u0131c\u0131 fonksiyonlar\u0131n\u0131 ele ge\u00e7irmesini ve bunlar\u0131 kontrol edilebilir sahte versiyonlarla de\u011fi\u015ftirmesini s\u00f6ylersiniz. Art\u0131k ger\u00e7ek zaman ak\u0131\u015f\u0131 yerine, siz zaman\u0131 istedi\u011finiz gibi ileri sarabilirsiniz. Bu, asenkron testlerinizi h\u0131zland\u0131r\u0131r ve onlar\u0131 tamamen deterministik hale getirir.<\/p>\n<h4>Sahte Zamanlay\u0131c\u0131lar Nas\u0131l \u00c7al\u0131\u015f\u0131r?<\/h4>\n<p><code>vi.useFakeTimers()<\/code> \u00e7a\u011fr\u0131ld\u0131ktan sonra, Vitest zamanlay\u0131c\u0131lar\u0131 kendi kontrol\u00fc alt\u0131na al\u0131r. Art\u0131k zaman\u0131 ilerletmek i\u00e7in \u015fu y\u00f6ntemleri kullanabilirsiniz:<\/p>\n<ul>\n<li><code>vi.advanceTimersByTime(ms: number)<\/code>: Belirtilen milisaniye kadar zaman\u0131 ileri sarar. Bu, \u00f6zellikle belirli bir gecikmenin dolmas\u0131n\u0131 beklemek i\u00e7in kullan\u0131\u015fl\u0131d\u0131r.<\/li>\n<li><code>vi.runAllTimers()<\/code>: Beklemedeki t\u00fcm zamanlay\u0131c\u0131lar\u0131 an\u0131nda \u00e7al\u0131\u015ft\u0131r\u0131r. E\u011fer bir\u00e7ok zamanlay\u0131c\u0131n\u0131z varsa ve hepsinin bitmesini istiyorsan\u0131z idealdir.<\/li>\n<li><code>vi.runOnlyPendingTimers()<\/code>: Sadece o an beklemede olan zamanlay\u0131c\u0131lar\u0131 \u00e7al\u0131\u015ft\u0131r\u0131r. Yeni zamanlay\u0131c\u0131lar tetiklenirse, onlar i\u00e7in tekrar \u00e7a\u011f\u0131rman\u0131z gerekir.<\/li>\n<li><code>vi.setSystemTime(date: Date | number)<\/code>: Sistemin anl\u0131k zaman\u0131n\u0131 belirledi\u011finiz bir de\u011fere ayarlar. Bu, \u00f6zellikle tarih ve saat ba\u011f\u0131ml\u0131 testler i\u00e7in faydal\u0131d\u0131r.<\/li>\n<\/ul>\n<p>Test tamamland\u0131ktan sonra, <code>vi.useRealTimers()<\/code> \u00e7a\u011f\u0131rarak ger\u00e7ek zamanlay\u0131c\u0131lara geri d\u00f6nmek \u00f6nemlidir, b\u00f6ylece di\u011fer testler veya test ortam\u0131 etkilenmez. Bu temizlik ad\u0131m\u0131, test s\u00fcitinizin kararl\u0131l\u0131\u011f\u0131 i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<h4>Vaka Analizi: Debounce Mekanizmas\u0131n\u0131n Test Edilmesi<\/h4>\n<p>Bir arama kutusuna yazarken, her tu\u015f vuru\u015funda API'ye istek g\u00f6ndermek yerine, kullan\u0131c\u0131n\u0131n duraklamas\u0131n\u0131 bekleyen bir debounce mekanizmas\u0131 yayg\u0131n bir senaryodur. Bu mekanizmay\u0131 sahte zamanlay\u0131c\u0131larla test etmek harika bir \u00f6rnektir ve ger\u00e7ek d\u00fcnya uygulamalar\u0131nda s\u0131kl\u0131kla kar\u015f\u0131m\u0131za \u00e7\u0131kar:<\/p>\n<pre><code>\n\/\/ search.service.ts\nimport { Injectable } from '@angular\/core';\nimport { Subject, timer } from 'rxjs';\nimport { debounce, switchMap } from 'rxjs\/operators';\n\n@Injectable({ providedIn: 'root' })\nexport class SearchService {\n  private searchTerm = new Subject<string>();\n\n  constructor() {\n    this.searchTerm.pipe(\n      debounce(() => timer(300)), \/\/ 300ms gecikme\n      switchMap(term => this.performSearch(term))\n    ).subscribe(result => console.log('Arama sonucu:', result));\n  }\n\n  search(term: string) {\n    this.searchTerm.next(term);\n  }\n\n  private performSearch(term: string): Promise<string[]> {\n    \/\/ Ger\u00e7ek API \u00e7a\u011fr\u0131s\u0131n\u0131 taklit edelim\n    return new Promise(resolve => {\n      setTimeout(() => {\n        resolve([<code>Result for ${term} 1<\/code>, <code>Result for ${term} 2<\/code>]);\n      }, 50); \/\/ API'den yan\u0131t gelme s\u00fcresi\n    });\n  }\n}\n\n\/\/ search.service.spec.ts (Vitest ve Fake Timers ile)\nimport { SearchService } from '.\/search.service';\nimport { TestBed } from '@angular\/core\/testing';\n\ndescribe('SearchService', () => {\n  let service: SearchService;\n\n  beforeEach(() => {\n    TestBed.configureTestingModule({});\n    service = TestBed.inject(SearchService);\n    vi.useFakeTimers(); \/\/ Sahte zamanlay\u0131c\u0131lar\u0131 etkinle\u015ftir\n  });\n\n  afterEach(() => {\n    vi.useRealTimers(); \/\/ Ger\u00e7ek zamanlay\u0131c\u0131lara geri d\u00f6n\n  });\n\n  it('should debounce search calls', async () => {\n    const spy = vi.spyOn(service as any, 'performSearch'); \/\/ private metoda eri\u015fim i\u00e7in\n    \n    service.search('apple');\n    service.search('banana');\n    service.search('cherry');\n\n    \/\/ 200ms ileri sar, debounce s\u00fcresi dolmad\u0131\u011f\u0131 i\u00e7in \u00e7a\u011fr\u0131 yap\u0131lmamal\u0131\n    vi.advanceTimersByTime(200);\n    expect(spy).not.toHaveBeenCalled();\n\n    \/\/ 100ms daha ileri sar (toplam 300ms), debounce s\u00fcresi doldu, \u015fimdi \u00e7a\u011fr\u0131 yap\u0131lmal\u0131\n    vi.advanceTimersByTime(100);\n    expect(spy).toHaveBeenCalledWith('cherry'); \/\/ Sadece son \u00e7a\u011fr\u0131 i\u015flenmeli\n\n    \/\/ performSearch i\u00e7indeki 50ms'lik gecikmeyi de ilerlet\n    await vi.advanceTimersByTime(50); \n    \/\/ Console log'u kontrol etmek i\u00e7in (e\u011fer spy log'u da kaps\u0131yorsa)\n    \/\/ Bu noktada API cevab\u0131n\u0131n i\u015flendi\u011fini varsayabiliriz.\n  });\n\n  it('should call search immediately if enough time passes between calls', async () => {\n    const spy = vi.spyOn(service as any, 'performSearch');\n\n    service.search('first');\n    vi.advanceTimersByTime(300); \/\/ \u0130lk \u00e7a\u011fr\u0131 i\u00e7in debounce s\u00fcresi dolsun\n    expect(spy).toHaveBeenCalledWith('first');\n\n    \/\/ API \u00e7a\u011fr\u0131s\u0131n\u0131n da tamamlanmas\u0131 i\u00e7in\n    await vi.advanceTimersByTime(50);\n    \n    spy.mockClear(); \/\/ Spy'\u0131 temizle\n    service.search('second');\n    vi.advanceTimersByTime(300); \/\/ \u0130kinci \u00e7a\u011fr\u0131 i\u00e7in debounce s\u00fcresi dolsun\n    expect(spy).toHaveBeenCalledWith('second');\n    await vi.advanceTimersByTime(50);\n  });\n});\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>vi.useFakeTimers()<\/code> sayesinde, ger\u00e7ek zaman\u0131n beklemesine gerek kalmadan saniyeler i\u00e7inde debounce mekanizmas\u0131n\u0131 test edebiliyoruz. <code>vi.advanceTimersByTime()<\/code> ile zaman\u0131 kontroll\u00fc bir \u015fekilde ilerleterek, debouncing'in do\u011fru \u00e7al\u0131\u015f\u0131p \u00e7al\u0131\u015fmad\u0131\u011f\u0131n\u0131 deterministik bir \u015fekilde do\u011frulayabiliriz. Bu, asenkron testleri \u00e7ok daha y\u00f6netilebilir ve g\u00fcvenilir hale getirir. Sahte zamanlay\u0131c\u0131lar, sadece debounce de\u011fil, ayn\u0131 zamanda animasyonlar, gecikmeli g\u00f6stergeler veya herhangi bir zaman ba\u011f\u0131ml\u0131 kod blo\u011fu i\u00e7in de hayati \u00f6neme sahiptir, b\u00f6ylece testleriniz daha h\u0131zl\u0131 ve daha \u00f6ng\u00f6r\u00fclebilir olur.<\/p>\n<h2>Testronaut: Angular Component Testlerini Nas\u0131l Kolayla\u015ft\u0131r\u0131yor?<\/h2>\n<p>Angular, g\u00fc\u00e7l\u00fc ve mod\u00fcler bile\u015fenler (components) olu\u015fturmak i\u00e7in harika bir \u00e7er\u00e7evedir. Ancak, bu bile\u015fenleri test etmek, \u00f6zellikle de Karma ve Jasmine'in varsay\u0131lan <code>TestBed<\/code> yakla\u015f\u0131m\u0131yla, bazen tekrarlayan (boilerplate) ve okunmas\u0131 zor kodlara yol a\u00e7abilir. Her bir bile\u015fen testi i\u00e7in <code>TestBed.configureTestingModule<\/code>, <code>TestBed.createComponent<\/code> gibi ad\u0131mlar\u0131 tekrarlamak, geli\u015ftirici deneyimini (DX) olumsuz etkiler ve test yazma h\u0131z\u0131n\u0131 yava\u015flat\u0131r. Bu durum, geli\u015ftiricilerin test yazmaktan ka\u00e7\u0131nmas\u0131na veya sadece y\u00fczeysel testler yazmas\u0131na neden olabilir.<\/p>\n<h3>Sorun: Angular <code>TestBed<\/code>'in Boilerplate Karma\u015fas\u0131<\/h3>\n<p>Angular'\u0131n <code>TestBed<\/code>'i, bir bile\u015fen i\u00e7in test mod\u00fcl\u00fc olu\u015fturman\u0131z\u0131 ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 y\u00f6netmenizi sa\u011flar. G\u00fc\u00e7l\u00fc bir ara\u00e7 olsa da, \u00f6zellikle basit bile\u015fenler i\u00e7in bile, tekrarlayan kod yazma y\u00fck\u00fc getirir:<\/p>\n<ul>\n<li>Her <code>describe<\/code> blo\u011funda veya <code>beforeEach<\/code> i\u00e7inde <code>TestBed<\/code>'i yap\u0131land\u0131rman\u0131z gerekir. Bu, her test dosyas\u0131n\u0131n benzer bir ba\u015flang\u0131\u00e7 \u015fablonuyla ba\u015flamas\u0131na neden olur.<\/li>\n<li>Gerekli <code>imports<\/code>, <code>declarations<\/code>, <code>providers<\/code> listelerini manuel olarak belirtmek zorunludur. Bu listeler b\u00fcy\u00fcd\u00fck\u00e7e y\u00f6netimi zorla\u015f\u0131r ve hata yapma olas\u0131l\u0131\u011f\u0131 artar.<\/li>\n<li>Bile\u015fenin bir \u00f6rne\u011fini almak i\u00e7in <code>TestBed.createComponent<\/code> kullanmak ve ard\u0131ndan <code>fixture.detectChanges()<\/code> \u00e7a\u011f\u0131rmak yayg\u0131n bir tekrard\u0131r. Bu, test kodunun uzunlu\u011funu art\u0131r\u0131r.<\/li>\n<li>\u00c7ocuk bile\u015fenleri veya direktifleri mocklamak (sahte nesnelerle de\u011fi\u015ftirmek) ekstra \u00e7aba gerektirebilir ve test kurulumunu daha karma\u015f\u0131k hale getirir.<\/li>\n<\/ul>\n<p>Bu ad\u0131mlar, test kodunun amac\u0131n\u0131 g\u00f6lgede b\u0131rakabilir ve odak noktan\u0131z\u0131 test etti\u011finiz bile\u015fenden uzakla\u015ft\u0131rarak, testin neyi do\u011frulad\u0131\u011f\u0131n\u0131 anlamay\u0131 zorla\u015ft\u0131rabilir.<\/p>\n<h3>\u00c7\u00f6z\u00fcm: Testronaut ile Testleri Basitle\u015ftirmek<\/h3>\n<p>\u0130\u015fte tam bu noktada Testronaut devreye giriyor! Testronaut, Angular bile\u015fen testlerini basitle\u015ftirmek ve boilerplate kodu azaltmak i\u00e7in tasarlanm\u0131\u015f hafif bir yard\u0131mc\u0131 k\u00fct\u00fcphanedir (yayg\u0131n uygulamalar\u0131ndan biri <code>@ngneat\/spectator<\/code>'dur). Ak\u0131c\u0131 (fluent) bir API sunarak, test kurulumunu daha okunakl\u0131 ve daha az tekrarlayan hale getirir. Amac\u0131, geli\u015ftiricilerin do\u011frudan bile\u015fenin davran\u0131\u015f\u0131n\u0131 test etmeye odaklanmas\u0131n\u0131 sa\u011flamakt\u0131r, b\u00f6ylece daha h\u0131zl\u0131 ve daha etkili testler yazabilirler.<\/p>\n<h4>Testronaut Nas\u0131l \u00c7al\u0131\u015f\u0131r ve Avantajlar\u0131 Nelerdir?<\/h4>\n<p>Testronaut, <code>TestBed<\/code> etraf\u0131nda bir soyutlama katman\u0131 sa\u011flar ve yayg\u0131n test senaryolar\u0131 i\u00e7in kolayla\u015ft\u0131r\u0131lm\u0131\u015f y\u00f6ntemler sunar. Temel avantajlar\u0131 \u015funlard\u0131r:<\/p>\n<ul>\n<li><strong>Boilerplate Azaltma:<\/strong> Tekrar eden <code>TestBed<\/code> kurulum kodunu b\u00fcy\u00fck \u00f6l\u00e7\u00fcde azalt\u0131r. Bu, test dosyalar\u0131n\u0131z\u0131n daha k\u0131sa ve daha \u00f6zl\u00fc olmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Okunabilirlik:<\/strong> Testlerinizi daha \"i\u015fe odakl\u0131\" ve daha az \"kuruluma odakl\u0131\" hale getirir. Ne test edildi\u011fini anlamak \u00e7ok daha kolayla\u015f\u0131r.<\/li>\n<li><strong>Kolay Mocking:<\/strong> Ba\u011f\u0131ml\u0131l\u0131klar\u0131 mocklamak i\u00e7in daha sezgisel bir yol sunar. \u00d6rne\u011fin, servisleri otomatik olarak mock'layabilir veya belirli de\u011ferler d\u00f6nd\u00fcrecek \u015fekilde yap\u0131land\u0131rabilirsiniz.<\/li>\n<li><strong>Esneklik:<\/strong> H\u00e2l\u00e2 <code>TestBed<\/code>'in t\u00fcm g\u00fcc\u00fcne eri\u015fmenizi sa\u011flarken, yayg\u0131n senaryolar\u0131 basitle\u015ftirir. \u0130htiya\u00e7 duydu\u011funuzda alt seviye <code>TestBed<\/code> API'lerini kullanmaya devam edebilirsiniz.<\/li>\n<li><strong>Geli\u015ftirici Deneyimi:<\/strong> Daha az yazarak daha \u00e7ok i\u015f yapman\u0131z\u0131 ve testlerinizi daha h\u0131zl\u0131 yazman\u0131z\u0131 sa\u011flar. Bu da geli\u015ftiricilerin test yazmaktan keyif almas\u0131n\u0131 sa\u011flar.<\/li>\n<\/ul>\n<h4>\u00d6rnek: Testronaut ile Basit Bir Bile\u015feni Test Etmek<\/h4>\n<p>Diyelim ki, kullan\u0131c\u0131dan bir isim alan ve bir \"Merhaba\" mesaj\u0131 g\u00f6steren basit bir <code>GreetingComponent<\/code>'imiz var:<\/p>\n<pre><code>\n\/\/ greeting.component.ts\nimport { Component, Input } from '@angular\/core';\nimport { CommonModule } from '@angular\/common';\nimport { FormsModule } from '@angular\/forms'; \/\/ [(ngModel)] i\u00e7in gerekli\n\n@Component({\n  selector: 'app-greeting',\n  standalone: true,\n  imports: [CommonModule, FormsModule], \/\/ FormsModule'i ekledik\n  template: <code><div>\n      <h2>{{ message }}<\/h2>\n      <input type=\"text\" [(ngModel)]=\"name\" (input)=\"updateMessage()\" data-testid=\"name-input\">\n    <\/div><\/code>,\n  styles: []\n})\nexport class GreetingComponent {\n  @Input() initialName: string = 'World';\n  name: string = '';\n  message: string = '';\n\n  ngOnInit() {\n    this.name = this.initialName;\n    this.updateMessage();\n  }\n\n  updateMessage() {\n    this.message = <code>Merhaba, ${this.name}!<\/code>;\n  }\n}\n\n\/\/ greeting.component.spec.ts (Testronaut (Spectator) ile)\nimport { GreetingComponent } from '.\/greeting.component';\nimport { Spectator, createComponentFactory } from '@ngneat\/spectator';\n\ndescribe('GreetingComponent with Spectator (Testronaut)', () => {\n  let spectator: Spectator<GreetingComponent>;\n\n  const createComponent = createComponentFactory({\n    component: GreetingComponent,\n    imports: [GreetingComponent], \/\/ Standalone bile\u015fenleri test ederken kendisini import etmeliyiz\n    \/\/ Declarations, providers, mocks ve autoSpy gibi di\u011fer se\u00e7enekler de burada kullan\u0131labilir.\n  });\n\n  beforeEach(() => {\n    spectator = createComponent({\n      props: {\n        initialName: 'Spectator User'\n      }\n    });\n  });\n\n  it('should create the component', () => {\n    expect(spectator.component).toBeTruthy();\n  });\n\n  it('should display the initial greeting message', () => {\n    expect(spectator.query('h2')).toHaveText('Merhaba, Spectator User!');\n  });\n\n  it('should update the greeting message when input changes', () => {\n    \/\/ data-testid kullanarak daha sa\u011flam bir se\u00e7ici\n    const input = spectator.query('[data-testid=\"name-input\"]') as HTMLInputElement; \n    spectator.typeInElement('Alice', input); \/\/ Input'a de\u011fer yaz\n    spectator.detectChanges(); \/\/ De\u011fi\u015fiklikleri alg\u0131la\n    expect(spectator.query('h2')).toHaveText('Merhaba, Alice!');\n  });\n});\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>@ngneat\/spectator<\/code> (Angular i\u00e7in Testronaut'\u0131n en yayg\u0131n uygulamalar\u0131ndan biri) kullan\u0131larak bir bile\u015fen testi yaz\u0131ld\u0131. <code>createComponentFactory<\/code> fonksiyonu, <code>TestBed<\/code>'in karma\u015fas\u0131n\u0131 soyutlayarak, bile\u015fenleri olu\u015fturmay\u0131 ve test etmeyi \u00e7ok daha kolay hale getirir. <code>Spectator<\/code> nesnesi, bile\u015fenin \u00f6rne\u011fine, elementine ve \u00e7e\u015fitli yard\u0131mc\u0131 fonksiyonlara (<code>query<\/code>, <code>typeInElement<\/code>, <code>detectChanges<\/code> gibi) tek bir yerden eri\u015fim sa\u011flar. Bu sayede, test kodunuz daha az tekrarlayan, daha okunakl\u0131 ve daha odaklanm\u0131\u015f hale gelir. Testronaut benzeri k\u00fct\u00fcphaneler, \u00f6zellikle karma\u015f\u0131k bile\u015fenler veya b\u00fcy\u00fck projeler i\u00e7in geli\u015ftirici verimlili\u011fini inan\u0131lmaz derecede art\u0131r\u0131r. Test yazma s\u00fcresini k\u0131salt\u0131r ve daha g\u00fcvenilir testler olu\u015fturman\u0131za yard\u0131mc\u0131 olur. Karma\u015f\u0131k ba\u011f\u0131ml\u0131l\u0131klar\u0131 veya interaktif elementleri olan bile\u015fenlerin testini basitle\u015ftirerek, Angular testlerini ger\u00e7ekten devrim niteli\u011finde bir seviyeye ta\u015f\u0131yor ve geli\u015ftiricilere zaman kazand\u0131r\u0131yor.<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Senaryosu: Geli\u015fmi\u015f Bir Angular Uygulamas\u0131n\u0131n Testini H\u0131zland\u0131rmak<\/h2>\n<p>Modern web uygulamalar\u0131, sadece basit bile\u015fenlerden ibaret de\u011fildir; genellikle karma\u015f\u0131k veri ak\u0131\u015flar\u0131, asenkron i\u015flemler ve etkile\u015fimli kullan\u0131c\u0131 aray\u00fczleri i\u00e7erirler. Bir veri tablosu veya grid bile\u015feni, bu karma\u015f\u0131kl\u0131\u011f\u0131n iyi bir \u00f6rne\u011fidir. Bu t\u00fcr bir bile\u015fen, genellikle \u015fu \u00f6zelliklere sahiptir:<\/p>\n<ul>\n<li><strong>Veri \u00c7ekme (Data Fetching):<\/strong> Bir API'den asenkron olarak veri y\u00fckler ve bu s\u00fcre\u00e7 genellikle gecikmeler i\u00e7erir.<\/li>\n<li><strong>Sayfaland\u0131rma (Pagination):<\/strong> B\u00fcy\u00fck veri setlerini k\u00fc\u00e7\u00fck par\u00e7alara ay\u0131r\u0131r, bu da her sayfa ge\u00e7i\u015finde yeni veri \u00e7ekimi anlam\u0131na gelebilir.<\/li>\n<li><strong>Debounce Edilmi\u015f Arama:<\/strong> Kullan\u0131c\u0131n\u0131n arama kutusuna yazd\u0131k\u00e7a, belirli bir gecikmeyle API'ye istek g\u00f6nderir. Bu, sunucu y\u00fck\u00fcn\u00fc azalt\u0131r ancak testlerde zamanlama sorunlar\u0131na yol a\u00e7abilir.<\/li>\n<li><strong>Y\u00fckleme Durumu (Loading State):<\/strong> Veri y\u00fcklenirken bir \"y\u00fckleniyor\" g\u00f6stergesi sunar. Bu g\u00f6rsel geri bildirim, kullan\u0131c\u0131 deneyimi i\u00e7in kritik olsa da test edilmesi zahmetli olabilir.<\/li>\n<li><strong>S\u0131ralama (Sorting):<\/strong> Tablo s\u00fctunlar\u0131n\u0131 artan veya azalan s\u0131rada s\u0131ralar, bu da veri manip\u00fclasyonu ve UI g\u00fcncellemeleri gerektirir.<\/li>\n<\/ul>\n<p>Bu \u00f6zelliklerin her biri, geleneksel test yakla\u015f\u0131mlar\u0131yla test edildi\u011finde \u00f6nemli zorluklar ve yava\u015flamalar yaratabilir. \u0130\u015fte bu noktada Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut'\u0131n birle\u015fimi, test s\u00fcrecini nas\u0131l k\u00f6kten de\u011fi\u015ftirebilece\u011fimize dair g\u00fc\u00e7l\u00fc bir vaka analizi sunar. Bu \u00fc\u00e7l\u00fcn\u00fcn entegrasyonu, hem performans hem de geli\u015ftirici deneyimi a\u00e7\u0131s\u0131ndan kayda de\u011fer iyile\u015ftirmeler sa\u011flar.<\/p>\n<h3>Vaka Analizi: Ak\u0131ll\u0131 Veri Tablosu Bile\u015fenini Test Etmek<\/h3>\n<p>Bir <code>SmartDataTableComponent<\/code>'imiz oldu\u011funu varsayal\u0131m. Bu bile\u015fen, bir <code>DataService<\/code>'ten veri \u00e7eker, bir arama giri\u015fi i\u00e7in debounce kullan\u0131r ve bir y\u00fckleme g\u00f6stergesi ile kullan\u0131c\u0131lara geri bildirim sa\u011flar. Ayr\u0131ca, sayfaland\u0131rma ve s\u0131ralama \u00f6zelliklerine de sahiptir.<\/p>\n<h4>1. Vitest ile Temel Entegrasyon ve H\u0131z<\/h4>\n<p>\u00d6ncelikle, <code>SmartDataTableComponent<\/code>'in temel birim testlerini Vitest ile yazmak, test s\u00fcitinin genel h\u0131z\u0131n\u0131 art\u0131r\u0131r. Mod\u00fcl \u00e7\u00f6zme ve test \u00e7al\u0131\u015ft\u0131rma s\u00fcreleri, Vitest'in Vite tabanl\u0131 mimarisi sayesinde \u00f6nemli \u00f6l\u00e7\u00fcde k\u0131sal\u0131r. Vitest'in HMR yetene\u011fi sayesinde, bile\u015fende veya serviste yapt\u0131\u011f\u0131n\u0131z k\u00fc\u00e7\u00fck bir de\u011fi\u015fiklik, saniyeler i\u00e7inde ilgili testlerin yeniden \u00e7al\u0131\u015fmas\u0131n\u0131 tetikler, bu da \"test yaz-kod yaz\" d\u00f6ng\u00fcs\u00fcn\u00fc \u00e7ok daha ak\u0131c\u0131 hale getirir. Bu h\u0131z, geli\u015ftiricilerin an\u0131nda geri bildirim almas\u0131n\u0131 ve hata ay\u0131klama s\u00fcre\u00e7lerini k\u0131saltmas\u0131n\u0131 sa\u011flar.<\/p>\n<pre><code>\n\/\/ smart-data-table.component.spec.ts (Vitest ile ba\u015flang\u0131\u00e7)\nimport { SmartDataTableComponent } from '.\/smart-data-table.component';\n\/\/ Di\u011fer importlar ve TestBed kurulumu...\ndescribe('SmartDataTableComponent', () => {\n  \/\/ Vitest'in h\u0131zl\u0131 ortam\u0131nda \u00e7al\u0131\u015facak basic testler\n  it('should initialize with no data when service returns empty', () => {\n    \/\/ ... Test logic here, ensuring the component's initial state is correct.\n    \/\/ For example, checking if the table is empty.\n  });\n\n  it('should display loading indicator when data is being fetched', () => {\n    \/\/ Mock the service to return a delayed observable\n    \/\/ Then check if the loading indicator is visible\n  });\n});\n<\/pre>\n<p><\/code><\/p>\n<h4>2. Sahte Zamanlay\u0131c\u0131lar ile Debounce ve Y\u00fckleme Durumlar\u0131n\u0131 Y\u00f6netmek<\/h4>\n<p><code>SmartDataTableComponent<\/code>'teki debounce edilmi\u015f arama \u00f6zelli\u011fi ve y\u00fckleme g\u00f6stergesi, sahte zamanlay\u0131c\u0131lar\u0131n g\u00fcc\u00fcn\u00fc g\u00f6sterir. Ger\u00e7ek API \u00e7a\u011fr\u0131s\u0131n\u0131 mock'larken, debounce gecikmesini manuel olarak ileri sarabiliriz:<\/p>\n<pre><code>\n\/\/ smart-data-table.component.spec.ts (Fake Timers ile debounce ve loading testi)\nimport { Spectator, createComponentFactory } from '@ngneat\/spectator';\nimport { SmartDataTableComponent } from '.\/smart-data-table.component';\nimport { DataService } from '..\/services\/data.service';\nimport { of, delay } from 'rxjs'; \/\/ delay operator\u00fc i\u00e7in\n\n\/\/ Mock DataService\nclass MockDataService {\n  getDataFromApi = vi.fn((term: string, page: number, sort: string) => \n    of([{ id: 1, name: <code>Item ${term} ${page} ${sort}<\/code> }]).pipe(delay(50)) \/\/ 50ms API gecikmesi\n  );\n}\n\ndescribe('SmartDataTableComponent with debounce search', () => {\n  let spectator: Spectator<SmartDataTableComponent>;\n  let dataService: MockDataService;\n\n  const createComponent = createComponentFactory({\n    component: SmartDataTableComponent,\n    imports: [], \/\/ E\u011fer standalone de\u011filse, mod\u00fcl importlar\u0131\n    providers: [\n      { provide: DataService, useClass: MockDataService } \/\/ DataService'i mock'la\n    ],\n    \/\/ autoSpy: true,\n  });\n\n  beforeEach(() => {\n    vi.useFakeTimers(); \/\/ Sahte zamanlay\u0131c\u0131lar\u0131 etkinle\u015ftir\n    spectator = createComponent();\n    dataService = spectator.inject(DataService) as unknown as MockDataService;\n  });\n\n  afterEach(() => {\n    vi.useRealTimers(); \/\/ Ger\u00e7ek zamanlay\u0131c\u0131lara geri d\u00f6n\n  });\n\n  it('should debounce search input and call service after delay', async () => {\n    const searchInput = spectator.query('.search-input') as HTMLInputElement;\n    const getDataSpy = dataService.getDataFromApi;\n\n    spectator.typeInElement('angular', searchInput); \/\/ \u0130lk yaz\u0131m\n    vi.advanceTimersByTime(100); \/\/ K\u0131smi gecikme\n    expect(getDataSpy).not.toHaveBeenCalled(); \/\/ Debounce s\u00fcresi dolmad\u0131\u011f\u0131 i\u00e7in \u00e7a\u011fr\u0131 yap\u0131lmamal\u0131\n\n    spectator.typeInElement('vitest', searchInput); \/\/ Ba\u015fka yaz\u0131m\n    vi.advanceTimersByTime(100); \/\/ K\u0131smi gecikme\n    expect(getDataSpy).not.toHaveBeenCalled(); \/\/ Hala \u00e7a\u011fr\u0131 yap\u0131lmamal\u0131\n\n    vi.advanceTimersByTime(201); \/\/ Debounce s\u00fcresi (\u00f6rn. 300ms) doldu, \u015fimdi \u00e7a\u011fr\u0131 yap\u0131lmal\u0131\n    expect(getDataSpy).toHaveBeenCalledWith('vitest', 1, 'name'); \/\/ Sadece son de\u011ferle \u00e7a\u011fr\u0131lmal\u0131 (varsay\u0131lan sayfa\/s\u0131ralama)\n\n    \/\/ Y\u00fckleme g\u00f6stergesi testi:\n    spectator.detectChanges(); \/\/ UI g\u00fcncellemelerini tetikle\n    expect(spectator.query('.loading-indicator')).toBeTruthy(); \/\/ API \u00e7a\u011fr\u0131s\u0131 s\u0131ras\u0131nda y\u00fckleniyor olmal\u0131\n\n    \/\/ API \u00e7a\u011fr\u0131s\u0131n\u0131n tamamlanmas\u0131 ve y\u00fckleme durumunun bitmesi i\u00e7in:\n    await vi.runAllTimersAsync(); \/\/ T\u00fcm bekleyen async operasyonlar\u0131 ve zamanlay\u0131c\u0131lar\u0131 ilerlet\n    spectator.detectChanges(); \/\/ UI g\u00fcncellemelerini tetikle\n    expect(spectator.query('.loading-indicator')).toBeFalsy(); \/\/ Y\u00fckleme bitmi\u015f olmal\u0131\n  });\n});\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>vi.useFakeTimers()<\/code> ve <code>vi.advanceTimersByTime()<\/code> sayesinde, arama debouncing'ini ve y\u00fckleme durumunu ger\u00e7ek zaman\u0131 beklemeden, milisaniyeler i\u00e7inde test edebiliyoruz. <code>vi.runAllTimersAsync()<\/code>, asenkron Promise'leri ve zamanlay\u0131c\u0131lar\u0131 ayn\u0131 anda \u00e7\u00f6zmek i\u00e7in olduk\u00e7a g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r, bu da testlerinizin daha deterministik olmas\u0131n\u0131 sa\u011flar ve test s\u00fcitinizin h\u0131z\u0131n\u0131 korur.<\/p>\n<h4>3. Testronaut (Spectator) ile Bile\u015fen Testlerini Temiz Tutmak<\/h4>\n<p><code>SmartDataTableComponent<\/code> gibi karma\u015f\u0131k bir bile\u015fen, muhtemelen \u00e7ok say\u0131da ba\u011f\u0131ml\u0131l\u0131\u011fa (<code>DataService<\/code>, <code>Router<\/code>, <code>HttpClient<\/code> vb.) ve karma\u015f\u0131k bir \u015fablona sahip olacakt\u0131r. Testronaut (Spectator), bu bile\u015fenin test kurulumunu b\u00fcy\u00fck \u00f6l\u00e7\u00fcde basitle\u015ftirir:<\/p>\n<ul>\n<li><code>createComponentFactory<\/code>, <code>TestBed<\/code> yap\u0131land\u0131rmas\u0131n\u0131 daha deklaratif ve okunabilir hale getirir. Bu, test kurulum kodunun daha anla\u015f\u0131l\u0131r olmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><code>providers<\/code> dizisinde sahte servisler (mock services) sa\u011flamak, ger\u00e7ek ba\u011f\u0131ml\u0131l\u0131klar\u0131n karma\u015f\u0131kl\u0131\u011f\u0131ndan ka\u00e7\u0131nman\u0131z\u0131 ve testlerinizi izole etmenizi sa\u011flar.<\/li>\n<li><code>autoSpy: true<\/code> \u00f6zelli\u011fi, t\u00fcm servislerinizi otomatik olarak Jest-stili spy'larla sarar, b\u00f6ylece metot \u00e7a\u011fr\u0131lar\u0131n\u0131 kolayca izleyebilir ve do\u011fru parametrelerle \u00e7a\u011fr\u0131l\u0131p \u00e7a\u011fr\u0131lmad\u0131klar\u0131n\u0131 do\u011frulayabilirsiniz.<\/li>\n<li><code>spectator.query()<\/code> ve <code>spectator.typeInElement()<\/code> gibi yard\u0131mc\u0131 fonksiyonlar, DOM ile etkile\u015fimi basitle\u015ftirir ve testleri daha kullan\u0131c\u0131 odakl\u0131 hale getirir.<\/li>\n<\/ul>\n<pre><code>\n\/\/ smart-data-table.component.spec.ts (Testronaut\/Spectator ile)\nimport { Spectator, createComponentFactory } from '@ngneat\/spectator';\nimport { SmartDataTableComponent } from '.\/smart-data-table.component';\nimport { DataService } from '..\/services\/data.service'; \/\/ Ger\u00e7ek servis\nimport { of } from 'rxjs';\n\nclass MockDataService {\n  getDataFromApi = vi.fn((term: string, page: number, sort: string) => \n    of([{ id: 1, name: <code>Mock Item ${term} Page ${page} Sort ${sort}<\/code> }])\n  );\n}\n\ndescribe('SmartDataTableComponent with Spectator', () => {\n  let spectator: Spectator<SmartDataTableComponent>;\n  let dataService: MockDataService;\n\n  const createComponent = createComponentFactory({\n    component: SmartDataTableComponent,\n    imports: [], \/\/ E\u011fer standalone de\u011filse, mod\u00fcl importlar\u0131\n    providers: [\n      { provide: DataService, useClass: MockDataService }\n    ],\n    \/\/ autoSpy: true, \/\/ T\u00fcm servisleri otomatik spy'lamak i\u00e7in etkinle\u015ftirilebilir\n  });\n\n  beforeEach(() => {\n    spectator = createComponent();\n    dataService = spectator.inject(DataService) as unknown as MockDataService;\n  });\n\n  it('should display fetched data after initialization', async () => {\n    \/\/ dataService'in belirli bir de\u011fer d\u00f6nd\u00fcrmesini sa\u011fla\n    dataService.getDataFromApi.mockReturnValue(of([{ id: 1, name: 'Item A' }]));\n    \n    spectator.detectChanges(); \/\/ ngOnInit'i ve veri y\u00fckleme s\u00fcrecini tetikle\n    await spectator.fixture.whenStable(); \/\/ Asenkron i\u015flemlerin bitmesini bekle\n\n    expect(spectator.query('tbody tr')).toHaveLength(1); \/\/ Bir sat\u0131r olmal\u0131\n    expect(spectator.query('tbody tr td:first-child')).toHaveText('Item A');\n    expect(dataService.getDataFromApi).toHaveBeenCalledWith('', 1, 'name'); \/\/ Ba\u015flang\u0131\u00e7ta default de\u011ferlerle \u00e7a\u011fr\u0131lmal\u0131\n  });\n\n  it('should change page and refetch data', async () => {\n    dataService.getDataFromApi.mockReturnValue(of([{ id: 2, name: 'Item B' }]));\n    \n    \/\/ Sayfa de\u011fi\u015ftirme etkile\u015fimini taklit et\n    \/\/ \u00d6rne\u011fin, bir sayfaland\u0131rma bile\u015feninde sayfa 2'ye t\u0131kland\u0131\u011f\u0131n\u0131 varsayal\u0131m\n    \/\/ spectator.click('.pagination-next-button');\n    \/\/ Bu senaryoda do\u011frudan bile\u015fenin metodunu \u00e7a\u011f\u0131rabiliriz\n    spectator.component.changePage(2);\n    spectator.detectChanges();\n    await spectator.fixture.whenStable();\n\n    expect(dataService.getDataFromApi).toHaveBeenCalledWith('', 2, 'name');\n    expect(spectator.query('tbody tr td:first-child')).toHaveText('Item B');\n  });\n});\n<\/pre>\n<p><\/code><\/p>\n<p>Bu entegre yakla\u015f\u0131m, karma\u015f\u0131k bir bile\u015fenin testini hem h\u0131zl\u0131 hem de bak\u0131m\u0131 kolay hale getirir. Vitest, h\u0131zl\u0131 \u00e7al\u0131\u015ft\u0131rma s\u00fcreleriyle genel performans\u0131 art\u0131r\u0131rken; sahte zamanlay\u0131c\u0131lar, asenkron etkile\u015fimleri kontrol alt\u0131na al\u0131r; Testronaut ise test kurulumu ve DOM etkile\u015fimindeki boilerplate'i azaltarak geli\u015ftiricilerin daha verimli testler yazmas\u0131n\u0131 sa\u011flar. Sonu\u00e7 olarak, bu \u00fc\u00e7l\u00fcn\u00fcn birle\u015fimi, Angular test s\u00fcre\u00e7lerinizde ger\u00e7ek bir devrim yarat\u0131r, size daha fazla g\u00fcven ve daha az bekleme s\u00fcresi sunar, b\u00f6ylece daha kaliteli yaz\u0131l\u0131mlar\u0131 daha h\u0131zl\u0131 teslim edebilirsiniz.<\/p>\n<div class=\"uzman-ipucu\">\n  Uzman \u0130pucu: Karma\u015f\u0131k form elemanlar\u0131n\u0131 veya bile\u015fenlerini test ederken, <code>@testing-library\/angular<\/code> ile birlikte Testronaut kullanmak, kullan\u0131c\u0131 odakl\u0131 testler yazman\u0131z\u0131 sa\u011flar. \u00d6rne\u011fin, <code>spectator.query('input[aria-label=\"Arama\"]')<\/code> gibi k\u0131r\u0131lgan CSS se\u00e7icileri yerine <code>spectator.getByLabelText('Arama')<\/code> veya <code>spectator.getByRole('button', { name: 'Kaydet' })<\/code> gibi semantik sorgular\u0131 kullanmak, eri\u015filebilirlik a\u00e7\u0131s\u0131ndan daha g\u00fc\u00e7l\u00fc ve k\u0131r\u0131lgan olmayan testler yazman\u0131za olanak tan\u0131r. Bu teknikle testlerinizin g\u00fcvenilirli\u011fini ve anla\u015f\u0131l\u0131rl\u0131\u011f\u0131n\u0131 %40 art\u0131rabilirsiniz, \u00e7\u00fcnk\u00fc kullan\u0131c\u0131lar\u0131n etkile\u015fim \u015feklini taklit edersiniz.\n<\/div>\n<h3>Mobil Uyumlu Test Raporlamas\u0131 i\u00e7in Medya Sorgular\u0131 Nas\u0131l Kullan\u0131l\u0131r?<\/h3>\n<p>Modern geli\u015ftirme s\u00fcre\u00e7lerinde, test sonu\u00e7lar\u0131n\u0131n ve raporlar\u0131n\u0131n farkl\u0131 cihazlarda (masa\u00fcst\u00fc, tablet, mobil) okunabilir olmas\u0131 da \u00f6nemlidir. Direkt olarak test ko\u015fucular\u0131n\u0131n HTML raporlar\u0131n\u0131n mobil uyumlu olmas\u0131, ekiplerin CI\/CD boru hatlar\u0131ndan gelen sonu\u00e7lar\u0131 hareket halindeyken bile kolayca incelemesini sa\u011flar. Bu, geli\u015ftirici verimlili\u011fini art\u0131ran dolayl\u0131 bir fakt\u00f6rd\u00fcr ve s\u00fcrekli entegrasyon\/s\u00fcrekli da\u011f\u0131t\u0131m s\u00fcre\u00e7lerinin etkinli\u011fini art\u0131r\u0131r.<\/p>\n<p>Kapsam raporlar\u0131 veya test \u00f6zetleri gibi HTML \u00e7\u0131kt\u0131lar\u0131 \u00fcretti\u011finizde, bu \u00e7\u0131kt\u0131lar\u0131n mobil cihazlarda iyi g\u00f6r\u00fcnmesini sa\u011flamak i\u00e7in CSS medya sorgular\u0131n\u0131 kullanabilirsiniz. Bu, tablolar\u0131n dar ekranlarda bile d\u00fczenli ve okunabilir kalmas\u0131n\u0131 sa\u011flar. \u0130\u015fte basit bir \u00f6rnek, tipik bir test raporu tablosunun nas\u0131l mobil uyumlu hale getirilebilece\u011fini g\u00f6stermektedir:<\/p>\n<pre><code class=\"language-html\">\n<!-- test-report.html -->\n<!DOCTYPE html>\n<html lang=\"tr\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Vitest Test Raporu<\/title>\n    <style>\n        body { font-family: Arial, sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; }\n        .container { max-width: 960px; margin: 0 auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }\n        h1 { color: #0056b3; text-align: center; margin-bottom: 20px;}\n        p { text-align: center; }\n        table { width: 100%; border-collapse: collapse; margin-top: 20px; }\n        th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }\n        th { background-color: #007bff; color: white; font-weight: bold; }\n        tbody tr:nth-child(even) { background-color: #f9f9f9; } \/* Her iki sat\u0131rda bir farkl\u0131 renk *\/\n        .pass { color: #28a745; font-weight: bold; } \/* Ge\u00e7en testler i\u00e7in ye\u015fil *\/\n        .fail { color: #dc3545; font-weight: bold; } \/* Kalan testler i\u00e7in k\u0131rm\u0131z\u0131 *\/\n        .skipped { color: #ffc107; } \/* Atlanan testler i\u00e7in sar\u0131 *\/\n\n        \/* Mobil Cihazlar i\u00e7in Medya Sorgusu (768px ve alt\u0131) *\/\n        @media (max-width: 768px) {\n            .container {\n                padding: 15px;\n            }\n            h1 { font-size: 1.8em; }\n            table, thead, tbody, th, td, tr {\n                display: block; \/* Tabloyu blok elemanlara d\u00f6n\u00fc\u015ft\u00fcrerek y\u0131\u011f\u0131lmas\u0131n\u0131 sa\u011fla *\/\n            }\n            thead tr {\n                position: absolute; \/* Ba\u015fl\u0131k sat\u0131r\u0131n\u0131 ekrandan gizle, sadece mobil i\u00e7in *\/\n                top: -9999px;\n                left: -9999px;\n            }\n            tr { \n                border: 1px solid #ccc; \n                margin-bottom: 15px; \n                border-radius: 8px;\n                box-shadow: 0 2px 5px rgba(0,0,0,0.05); \/* Her sat\u0131r i\u00e7in hafif g\u00f6lge *\/\n            }\n            td {\n                border: none; \/* Mobil g\u00f6r\u00fcn\u00fcmde h\u00fccre kenarl\u0131klar\u0131n\u0131 kald\u0131r *\/\n                border-bottom: 1px solid #eee; \/* Alt kenarl\u0131k ekleme *\/\n                position: relative;\n                padding-left: 50%; \/* \u0130\u00e7eri\u011fi ba\u015fl\u0131klar\u0131n yan\u0131na hizala *\/\n                text-align: right;\n                font-size: 0.9em;\n            }\n            td:last-child { border-bottom: none; } \/* Son h\u00fccrede alt kenarl\u0131k olmas\u0131n *\/\n            td:before {\n                position: absolute;\n                top: 12px;\n                left: 12px;\n                width: 40%;\n                padding-right: 10px;\n                white-space: nowrap;\n                text-align: left;\n                font-weight: bold;\n                color: #555;\n            }\n            \/* Her s\u00fctun i\u00e7in ba\u015fl\u0131k etiketi ekleyin *\/\n            td:nth-of-type(1):before { content: \"Test Ad\u0131:\"; }\n            td:nth-of-type(2):before { content: \"Durum:\"; }\n            td:nth-of-type(3):before { content: \"S\u00fcre:\"; }\n            td:nth-of-type(4):before { content: \"Kapsam:\"; }\n        }\n\n        \/* Daha k\u00fc\u00e7\u00fck mobil cihazlar i\u00e7in ekstra optimizasyonlar *\/\n        @media (max-width: 480px) {\n            body { margin: 10px; }\n            .container { padding: 10px; }\n            h1 { font-size: 1.5em; }\n            td { padding-left: 45%; }\n            td:before { width: 40%; left: 8px; top: 10px; }\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"container\">\n        <h1>Vitest Test Raporu<\/h1>\n        <p><strong>Toplam Test Say\u0131s\u0131:<\/strong> 15<\/p>\n        <p><strong class=\"pass\">Ba\u015far\u0131l\u0131:<\/strong> 14 \u00a0 <strong class=\"fail\">Ba\u015far\u0131s\u0131z:<\/strong> 1<\/p>\n        <table>\n            <thead>\n                <tr>\n                    <th>Test Ad\u0131<\/th>\n                    <th>Durum<\/th>\n                    <th>S\u00fcre (ms)<\/th>\n                    <th>Kapsam (%)<\/th>\n                <\/tr>\n            <\/thead>\n            <tbody>\n                <tr>\n                    <td>AppComponent should create the app<\/td>\n                    <td class=\"pass\">BA\u015eARILI<\/td>\n                    <td>12<\/td>\n                    <td>100%<\/td>\n                <\/tr>\n                <tr>\n                    <td>SearchService should debounce search calls<\/td>\n                    <td class=\"pass\">BA\u015eARILI<\/td>\n                    <td>25<\/td>\n                    <td>95%<\/td>\n                <\/tr>\n                <tr>\n                    <td>SmartDataTableComponent should handle pagination error<\/td>\n                    <td class=\"fail\">BA\u015eARISIZ<\/td>\n                    <td>40<\/td>\n                    <td>80%<\/td>\n                <\/tr>\n                <tr>\n                    <td>AuthService should store user token<\/td>\n                    <td class=\"pass\">BA\u015eARILI<\/td>\n                    <td>8<\/td>\n                    <td>100%<\/td>\n                <\/tr>\n                <tr>\n                    <td>UserService should return authenticated user data<\/td>\n                    <td class=\"pass\">BA\u015eARILI<\/td>\n                    <td>18<\/td>\n                    <td>98%<\/td>\n                <\/tr>\n                <!-- Di\u011fer test sonu\u00e7lar\u0131 -->\n            <\/tbody>\n        <\/table>\n    <\/div>\n<\/body>\n<\/html>\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki HTML ve CSS kod blo\u011fu, tipik bir test raporu tablosunun nas\u0131l mobil uyumlu hale getirilebilece\u011fini g\u00f6stermektedir. <code>@media (max-width: 768px)<\/code> sorgusu ile belirli bir ekran geni\u015fli\u011finin alt\u0131nda tablonun davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftiriyoruz. Her bir sat\u0131r bir blok eleman haline gelir ve her h\u00fccre, <code>:before<\/code> pseudo-elementi kullan\u0131larak kendi ba\u015fl\u0131\u011f\u0131n\u0131 g\u00f6sterir. Bu sayede, dar ekranlarda bile test sonu\u00e7lar\u0131 kayd\u0131r\u0131labilir veya okunabilir bir formatta sunulmu\u015f olur. Ayr\u0131ca <code><meta name=\"viewport\"><\/code> etiketi, mobil cihazlar\u0131n sayfay\u0131 do\u011fru \u00f6l\u00e7eklendirmesini sa\u011flar.<\/p>\n<p>Bu, do\u011frudan Vitest veya Testronaut'\u0131n bir \u00f6zelli\u011fi olmasa da, bu t\u00fcr ara\u00e7lar\u0131n \u00fcretti\u011fi HTML raporlar\u0131n\u0131n veya dok\u00fcmantasyonun eri\u015filebilirli\u011fini art\u0131rmak i\u00e7in genel bir web geli\u015ftirme best practice'idir. Test s\u00fcre\u00e7lerinizin her a\u015famas\u0131nda, geli\u015ftirici ve ekip deneyimini iyile\u015ftirmek, modern ve \"devrim niteli\u011finde\" bir test k\u00fclt\u00fcr\u00fc olu\u015fturman\u0131n \u00f6nemli bir par\u00e7as\u0131d\u0131r. Mobil uyumlu raporlar, \u00f6zellikle uzak ekiplerin veya y\u00f6neticilerin test sonu\u00e7lar\u0131n\u0131 h\u0131zl\u0131ca g\u00f6zden ge\u00e7irmesi i\u00e7in b\u00fcy\u00fck kolayl\u0131k sa\u011flar.<\/p>\n<h2>Sonu\u00e7: Angular Testlerinin Gelece\u011fi Daha H\u0131zl\u0131 ve Daha Ak\u0131ll\u0131<\/h2>\n<p>Angular geli\u015ftirme d\u00fcnyas\u0131nda test s\u00fcre\u00e7leri, eskiden oldu\u011fu gibi yava\u015f, zahmetli ve tekrarlayan olmak zorunda de\u011fil. \"Angular's Testing Revolution: Vitest, Fake Timers & Testronaut\" ba\u015fl\u0131\u011f\u0131 alt\u0131nda inceledi\u011fimiz ara\u00e7lar ve teknikler, modern Angular projelerinde test yazma ve \u00e7al\u0131\u015ft\u0131rma \u015feklimizi ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftiriyor. Geleneksel yakla\u015f\u0131mlar\u0131n getirdi\u011fi y\u00fckleri ortadan kald\u0131rarak, geli\u015ftiricilere daha h\u0131zl\u0131 geri bildirim, daha y\u00fcksek verimlilik ve daha keyifli bir geli\u015ftirme deneyimi sunuyor. Bu ara\u00e7lar, sadece test s\u00fcre\u00e7lerini optimize etmekle kalm\u0131yor, ayn\u0131 zamanda genel yaz\u0131l\u0131m kalitesini de art\u0131r\u0131yor.<\/p>\n<p>Vitest'in ultra h\u0131zl\u0131 test \u00e7al\u0131\u015ft\u0131rma s\u00fcreleri, ESM tabanl\u0131 mimarisi ve an\u0131nda HMR yetenekleri, test s\u00fcitlerinin saniyeler i\u00e7inde tamamlanmas\u0131n\u0131 sa\u011flayarak geli\u015ftirme d\u00f6ng\u00fclerini h\u0131zland\u0131r\u0131yor. Art\u0131k k\u00fc\u00e7\u00fck bir de\u011fi\u015fiklik yapt\u0131\u011f\u0131n\u0131zda dakikalarca testlerin bitmesini beklemek zorunda kalm\u0131yorsunuz. Bu, geli\u015ftiricilerin kodlar\u0131na olan g\u00fcvenini art\u0131r\u0131rken, hata ay\u0131klama s\u00fcre\u00e7lerini de \u00f6nemli \u00f6l\u00e7\u00fcde k\u0131salt\u0131r ve \"test-driven development\" (TDD) gibi yakla\u015f\u0131mlar\u0131n daha uygulanabilir hale gelmesini sa\u011flar.<\/p>\n<p>Sahte zamanlay\u0131c\u0131lar (fake timers), asenkron kodlar\u0131 test etmenin kar\u015f\u0131 konulmaz zorluklar\u0131na zarif bir \u00e7\u00f6z\u00fcm sunuyor. <code>setTimeout<\/code>, <code>setInterval<\/code> gibi zaman ba\u011f\u0131ml\u0131 fonksiyonlar\u0131n kontrol\u00fcn\u00fc ele alarak, testlerinizi ger\u00e7ek zaman\u0131 beklemek zorunda kalmadan deterministik ve h\u0131zl\u0131 bir \u015fekilde \u00e7al\u0131\u015ft\u0131rman\u0131za olanak tan\u0131yor. Debounce edilmi\u015f aramalar, animasyonlar veya gecikmeli bildirimler gibi senaryolar\u0131 test etmek art\u0131k bir kabus olmaktan \u00e7\u0131k\u0131yor ve \u00e7ok daha g\u00fcvenilir hale geliyor.<\/p>\n<p>Testronaut (<code>@ngneat\/spectator<\/code> gibi k\u00fct\u00fcphaneler arac\u0131l\u0131\u011f\u0131yla), Angular bile\u015fen testlerinin getirdi\u011fi boilerplate y\u00fck\u00fcn\u00fc ortadan kald\u0131rarak geli\u015ftirici deneyimini zirveye ta\u015f\u0131yor. Daha az kodla daha anlaml\u0131 testler yazmak, bile\u015fenlerinizin davran\u0131\u015f\u0131na odaklanman\u0131z\u0131 sa\u011fl\u0131yor. Bu, test yazma h\u0131z\u0131n\u0131z\u0131 art\u0131r\u0131rken, testlerinizin okunabilirli\u011fini ve bak\u0131m\u0131n\u0131 da kolayla\u015ft\u0131r\u0131yor, b\u00f6ylece ekipler daha s\u00fcrd\u00fcr\u00fclebilir bir test altyap\u0131s\u0131 olu\u015fturabiliyor.<\/p>\n<p>Bu \u00fc\u00e7l\u00fcn\u00fcn birle\u015fimi, sadece testlerinizi h\u0131zland\u0131rmakla kalm\u0131yor, ayn\u0131 zamanda daha g\u00fcvenilir, daha anla\u015f\u0131l\u0131r ve daha s\u00fcrd\u00fcr\u00fclebilir bir test altyap\u0131s\u0131 kurman\u0131za yard\u0131mc\u0131 oluyor. Angular toplulu\u011fu, daha iyi ve daha h\u0131zl\u0131 test s\u00fcre\u00e7leri aray\u0131\u015f\u0131nda s\u00fcrekli olarak yenilikler yap\u0131yor ve bu ara\u00e7lar, bu yeniliklerin en parlak \u00f6rneklerinden baz\u0131lar\u0131d\u0131r. Sonu\u00e7 olarak, bu entegrasyonlar, modern Angular geli\u015ftirme ekosisteminde vazge\u00e7ilmez bir yer edinmeye ba\u015flam\u0131\u015ft\u0131r.<\/p>\n<p>E\u011fer Angular test s\u00fcre\u00e7lerinizde verimlilik ar\u0131yor ve geli\u015ftirici deneyiminizi iyile\u015ftirmek istiyorsan\u0131z, Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut'\u0131 projenize entegre etmeyi kesinlikle d\u00fc\u015f\u00fcnmelisiniz. Gelece\u011fin Angular testleri, \u015fimdiden parmaklar\u0131n\u0131z\u0131n ucunda ve projelerinize de\u011fer katmay\u0131 bekliyor!<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<dl>\n<dt>Vitest, Jest'in yerini tamamen alabilir mi?<\/dt>\n<dd>Evet, Vitest, Jest ile b\u00fcy\u00fck \u00f6l\u00e7\u00fcde uyumlu bir API sunar ve \u00e7o\u011fu Jest testini do\u011frudan \u00e7al\u0131\u015ft\u0131rabilir. Daha h\u0131zl\u0131 \u00e7al\u0131\u015ft\u0131rma s\u00fcreleri ve daha hafif bir kurulum sunarak bir\u00e7ok senaryoda Jest'in yerini alabilir. Ancak, Jest'in baz\u0131 \u00f6zel ekosistem ara\u00e7lar\u0131 veya eklentileri (\u00f6rne\u011fin, \u00f6zel Jest transformat\u00f6rleri veya snapshot testleri i\u00e7in ileri d\u00fczey \u00f6zelle\u015ftirmeler) varsa, Vitest'e ge\u00e7i\u015f yapmadan \u00f6nce uyumlulu\u011fu kontrol etmek \u00f6nemlidir. Genel olarak, \u00e7o\u011fu Angular projesi i\u00e7in g\u00fc\u00e7l\u00fc bir alternatiftir.<\/dd>\n<dt>Sahte zamanlay\u0131c\u0131lar sadece <code>setTimeout<\/code> ve <code>setInterval<\/code> i\u00e7in mi ge\u00e7erli?<\/dt>\n<dd>Hay\u0131r, Vitest'in sahte zamanlay\u0131c\u0131lar\u0131 <code>setTimeout<\/code>, <code>setInterval<\/code>, <code>setImmediate<\/code>, <code>clearTimeout<\/code>, <code>clearInterval<\/code>, <code>clearImmediate<\/code>, <code>requestAnimationFrame<\/code>, <code>cancelAnimationFrame<\/code>, <code>Date<\/code> gibi yerle\u015fik zamanlay\u0131c\u0131 ve tarih API'lerini de kapsar. Bu, zamanla ilgili hemen hemen t\u00fcm asenkron i\u015flemleri kontrol etmenizi ve testlerinizin tamamen deterministik olmas\u0131n\u0131 sa\u011flaman\u0131z\u0131 m\u00fcmk\u00fcn k\u0131lar. Bu sayede, UI animasyonlar\u0131 veya gecikmeli veri y\u00fckleme gibi karma\u015f\u0131k senaryolar\u0131 bile kolayca test edebilirsiniz.<\/dd>\n<dt>Testronaut'\u0131 (Spectator) kullanmak <code>TestBed<\/code>'i tamamen devre d\u0131\u015f\u0131 m\u0131 b\u0131rak\u0131r?<\/dt>\n<dd>Hay\u0131r, Testronaut\/Spectator, Angular'\u0131n <code>TestBed<\/code>'i etraf\u0131nda ak\u0131ll\u0131 bir soyutlama katman\u0131 sa\u011flar. Temelde, <code>TestBed<\/code>'i sizin i\u00e7in daha az boilerplate ile yap\u0131land\u0131r\u0131r ve kullan\u0131m\u0131n\u0131 kolayla\u015ft\u0131r\u0131r. Yani, <code>TestBed<\/code> hala arka planda \u00e7al\u0131\u015f\u0131r, ancak sizin do\u011frudan onunla u\u011fra\u015fman\u0131z\u0131 gerektiren kod miktar\u0131n\u0131 azalt\u0131r. Bu sayede hem <code>TestBed<\/code>'in g\u00fcc\u00fcnden faydalanmaya devam eder hem de daha temiz ve okunakl\u0131 testler yazars\u0131n\u0131z.<\/dd>\n<dt>Bu ara\u00e7lar\u0131 mevcut bir Angular projesine entegre etmek ne kadar zor?<\/dt>\n<dd>Makaledeki ad\u0131mlar\u0131 takip ederek, Vitest ve Testronaut'\u0131 mevcut bir Angular projesine entegre etmek olduk\u00e7a y\u00f6netilebilirdir. Ancak, projenizin b\u00fcy\u00fckl\u00fc\u011f\u00fcne, karma\u015f\u0131kl\u0131\u011f\u0131na ve mevcut test altyap\u0131s\u0131na ba\u011fl\u0131 olarak baz\u0131 ince ayarlar gerekebilir. \u00d6zellikle <code>tsconfig.spec.json<\/code> ve <code>vitest.config.ts<\/code> dosyalar\u0131n\u0131n do\u011fru \u015fekilde yap\u0131land\u0131r\u0131lmas\u0131 \u00f6nemlidir. Genel olarak, iyi belgelenmi\u015f ve ad\u0131m ad\u0131m ilerleyen bir s\u00fcre\u00e7tir.<\/dd>\n<dt>Vitest kullanmak Angular CLI'\u0131n varsay\u0131lan test komutunu de\u011fi\u015ftirir mi?<\/dt>\n<dd>Evet, <code>package.json<\/code> dosyas\u0131ndaki <code>\"test\": \"vitest\"<\/code> script'i ile Angular CLI'\u0131n varsay\u0131lan <code>ng test<\/code> komutu yerine do\u011frudan Vitest'i \u00e7a\u011f\u0131r\u0131rs\u0131n\u0131z. Bu, testlerinizi Vitest ortam\u0131nda \u00e7al\u0131\u015ft\u0131raca\u011f\u0131n\u0131z anlam\u0131na gelir ve Karma\/Jasmine gibi varsay\u0131lan ko\u015fucular\u0131 kullanmayaca\u011f\u0131n\u0131z\u0131 g\u00f6sterir. Angular CLI'\u0131n test komutunu de\u011fi\u015ftirmek yerine, farkl\u0131 bir script ad\u0131 (\u00f6rne\u011fin <code>\"vitest:run\": \"vitest\"<\/code>) kullanarak her iki test ko\u015fucusunu da projenizde tutman\u0131z da m\u00fcmk\u00fcnd\u00fcr.<\/dd>\n<\/dl>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1488],"tags":[],"class_list":{"0":"post-32964","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-angular","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Angular&#039;da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut<\/title>\n<meta name=\"description\" content=\"Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular test s\u00fcre\u00e7lerinizi nas\u0131l ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftirebilece\u011finizi ke\u015ffedin. Performans, h\u0131z ve g\u00fcvenilirli\u011fi art\u0131rarak geli\u015ftirici deneyiminizi zirveye ta\u015f\u0131y\u0131n.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular&#039;da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut\" \/>\n<meta property=\"og:description\" content=\"Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular test s\u00fcre\u00e7lerinizi nas\u0131l ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftirebilece\u011finizi ke\u015ffedin. Performans, h\u0131z ve g\u00fcvenilirli\u011fi art\u0131rarak geli\u015ftirici deneyiminizi zirveye ta\u015f\u0131y\u0131n.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-27T20:03:15+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"34 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Angular&#8217;da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut\",\"datePublished\":\"2025-10-27T20:03:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/\"},\"wordCount\":4908,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Angular\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/\",\"name\":\"Angular'da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-27T20:03:15+00:00\",\"description\":\"Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular test s\u00fcre\u00e7lerinizi nas\u0131l ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftirebilece\u011finizi ke\u015ffedin. Performans, h\u0131z ve g\u00fcvenilirli\u011fi art\u0131rarak geli\u015ftirici deneyiminizi zirveye ta\u015f\u0131y\u0131n.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular&#8217;da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Angular'da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut","description":"Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular test s\u00fcre\u00e7lerinizi nas\u0131l ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftirebilece\u011finizi ke\u015ffedin. Performans, h\u0131z ve g\u00fcvenilirli\u011fi art\u0131rarak geli\u015ftirici deneyiminizi zirveye ta\u015f\u0131y\u0131n.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/","og_locale":"tr_TR","og_type":"article","og_title":"Angular'da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut","og_description":"Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular test s\u00fcre\u00e7lerinizi nas\u0131l ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftirebilece\u011finizi ke\u015ffedin. Performans, h\u0131z ve g\u00fcvenilirli\u011fi art\u0131rarak geli\u015ftirici deneyiminizi zirveye ta\u015f\u0131y\u0131n.","og_url":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-27T20:03:15+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"34 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Angular&#8217;da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut","datePublished":"2025-10-27T20:03:15+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/"},"wordCount":4908,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Angular"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/","url":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/","name":"Angular'da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-27T20:03:15+00:00","description":"Angular uygulamalar\u0131n\u0131z\u0131 test etmek hi\u00e7 bu kadar h\u0131zl\u0131 ve verimli olmam\u0131\u015ft\u0131! Vitest, sahte zamanlay\u0131c\u0131lar ve Testronaut ile Angular test s\u00fcre\u00e7lerinizi nas\u0131l ba\u015ftan a\u015fa\u011f\u0131 de\u011fi\u015ftirebilece\u011finizi ke\u015ffedin. Performans, h\u0131z ve g\u00fcvenilirli\u011fi art\u0131rarak geli\u015ftirici deneyiminizi zirveye ta\u015f\u0131y\u0131n.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/angularda-test-devrimi-vitest-sahte-zamanlayicilar-ve-testronaut\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Angular&#8217;da Test Devrimi: Vitest, Sahte Zamanlay\u0131c\u0131lar ve Testronaut"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32964","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=32964"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32964\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=32964"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=32964"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=32964"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}