Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityUbuntu 26.10 adds a Windows-style window snapping panel(25.09.2026 um 00:01 Uhr)
•
AI & KI NachrichtenJulian Goldie SEO: OpenAI Just Dropped Two New GPT-6 Models(25.09.2026 um 01:00 Uhr)
•
KI & AI VideosPatrick Collison on Claude Code at Stripe(25.09.2026 um 00:57 Uhr)
••
AI & KI Nachrichtendeleting-the-trace(24.09.2026 um 23:28 Uhr)
•
IT Security ToolsAjar(25.09.2026 um 00:29 Uhr)
•••
AI & KI NachrichtenGitHub Release: openai/codex vrust-v0.158.0-alpha.11 (25.09.2026)(25.09.2026 um 01:32 Uhr)
••
Windows Tipps & SecurityUbuntu 26.10 adds a Windows-style window snapping panel(25.09.2026 um 00:01 Uhr)
•
AI & KI NachrichtenJulian Goldie SEO: OpenAI Just Dropped Two New GPT-6 Models(25.09.2026 um 01:00 Uhr)
•
KI & AI VideosPatrick Collison on Claude Code at Stripe(25.09.2026 um 00:57 Uhr)
••
AI & KI Nachrichtendeleting-the-trace(24.09.2026 um 23:28 Uhr)
•
IT Security ToolsAjar(25.09.2026 um 00:29 Uhr)
•••
AI & KI NachrichtenGitHub Release: openai/codex vrust-v0.158.0-alpha.11 (25.09.2026)(25.09.2026 um 01:32 Uhr)
••
Intelligence View
⚡ tsecurity.de Intelligence

Angular's Testing Revolution: Vitest, Fake Timers & Testronaut

As we wrap up the year, the Angular world has been abuzz with big topics like Signal Forms. But quietly, and quite unexpectedly, a testing revolution is arriving with Angular version 21 - just two weeks away (at the time of this…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

As we wrap up the year, the Angular world has been abuzz with big topics like Signal Forms. But quietly, and quite unexpectedly, a testing revolution is arriving with Angular version 21 - just two weeks away (at the time of this writing).



In this article, we’ll explore how Vitest is stepping in as the new default testing framework, how async testing will change for new zoneless Angular applications, and how Testronaut will make its debut as the community version of Playwright Component Testing for Angular.



Table of Contents




  1. Vitest

  2. Fake Timers

  3. Testronaut






🧪 Vitest



The most important thing about Vitest is not Vitest itself 🙃.



For nearly two years, Angular developers have been in a kind of testing limbo.



With Karma’s deprecation in 2023, teams were left wondering which direction to go. Should they hold on to the old tools - sticking with Jasmine and hoping for a replacement in the form of the Modern Web Test Runner? Others had already switched to Jest - especially in Nx monorepos - but weren’t sure whether to stay or move on to Vitest (which was also available in Nx).



This lack of a clear choice made it very tough to plan for the future, especially for new projects 🤷.



Now, with the announcement that Vitest will be available as a testing framework starting with Angular 21, there's relief.



Developers finally have a decision and know what to pick.



The uncertainty is gone, and that's the most important aspect!



Announcement by Matthieu Riegler






Vitest was the right decision.



Compared to Jasmine - and even Jest - Vitest brings a powerful API, a rich, forward-looking ecosystem that’s TypeScript-first and fully supports ESM. It also includes a browser mode, which means tests can run in a real browser environment.



That was one key point for the Angular team. They want to move forward - but not force everyone to rewrite. So it was crucial to choose a testing framework that, like Jasmine/Karma, runs tests in the browser.



Even though the APIs differ - especially around async testing and mocking - the environment stays the same.



Vitest is powered by Vite. And while Angular’s implementation doesn’t go all-in on Vitest (Angular builds the tests instead of Vite), it still closes the gap to the Vite ecosystem.



In the end, Angular doesn’t want to be an outsider anymore. It wants to become part of the broader JavaScript ecosystem - and Vite is the key for that.



Vitest on the rise, Jest starting to decline



The image shows that Jest is still dominating but Vitest has the momentum






Here's just a selection of Vitest's powerful API:



Polling Feature



expect.poll accepts a function which will return a value. Vitest will continue executing the assertion until it runs into a timeout or the matches is successful.




import { expect, test } from 'vitest';

test('wait for the asynchronous tasks to end', async () => {
let a = 1;

setTimeout(() => a++);
Promise.resolve().then(() => a++);

await expect.poll(() => a).toBe(3);
});






Soft Assertions



Soft Assertions execute all expects within a test, even if one fails. In case, one expect fails, the whole test is marked failed.




test('resource', () => {
const todoResource = getSomeResource();

expect.soft(resource.status()).toBe('resolved');
expect.soft(resource.error()).toBeUndefined();
expect.soft(resource.hasValue()).toBe(true);
})






Test Context



Test context allows us to add different functionality to a test. See it as some kind of "dependency injection" for tests.



In the example below, we add a wait function, which is then available as a parameter within the test.



context.ts




import { test as base } from 'vitest';

interface Fixtures {
wait: (timeout?: number) => Promise<void>;
}

export const test = base.extend<Fixtures>({
wait: async ({}, use) => {
await use(
(timeout = 0) =>
new Promise<void>((resolve) => setTimeout(resolve, timeout)),
);
},
});






async.spec.ts




import { test } from './context';
import { expect } from 'vitest';

test('wait for the asynchronous task', async ({ wait }) => {
let a = 1;

setTimeout(() => a++);
Promise.resolve().then(() => a++);

expect(a).toBe(1);
await wait();
expect(a).toBe(3);
});










You can already use Vitest in Angular 20. For example, this repository already uses it. Just run ng test - just like you would with Jasmine/Karma - and it will execute the tests.



Starting with Angular 21, when you run ng new, you’ll be prompted to choose between Vitest and Jasmine, with Vitest being the default.



Migration schematics will also be available to help you migrate from Jasmine.



Vitest in action

Vitest running behind ng test in Angular 20





For more information, check out Matthieu Riegler’s LinkedIn post - and I’m pretty sure more resources will follow.



And of course, check out the official Vitest website: https://vitest.dev





👋 Farewell waitForAsync() & fakeAsync()



Until now, Zone.js has played a central role in how Angular handles asynchronous behavior.





How Zone.js-testing "worked"



Zone.js patches timing functions like setTimeout and setInterval. This allows it to observe and track async tasks across the framework. However, one thing Zone.js could never patch was the native JavaScript Promise - since it's a language-level construct, not just a method.



In Angular testing, two functions built on Zone.js helped manage async behavior: fakeAsync() and waitForAsync().



waitForAsync() waits for all scheduled asynchronous tasks to finish before continuing with the test.




it('should wait for async tasks to end', waitForAsync(() => {
let a = 1;
setTimeout(() => {
a++;
expect(a).toBe(2);
});
}));






This worked in most cases, but had limitations - especially when assertions were made after async tasks, or if a setTimeout was scheduled far into the future (e.g. 1 second or more). In such cases, the test would simply wait.




it('should wait for too long', waitForAsync(() => {
let a = 1;
setTimeout(() => {
a++;
expect(a).toBe(2);
}, 10_000);
}));

it('should fail to assert an asynchronous task', waitForAsync(() => {
let a = 1;
setTimeout(() => {
a++;
});

expect(a).toBe(2);
}));






fakeAsync() became the preferred solution. It gives developers full control over the async queue via tick() and flush(). tick() simulates the passage of time, while flush() executes all pending timers except for periodic ones like setInterval.




it('runs all asynchronous tasks immediately (synchronously) after flush', fakeAsync(() => {
let a = 1;
setTimeout(() => {
a++;
}, 5_000);

setTimeout(() => {
a++;
}, 5_000);

flush();

expect(a).toBe(3);
}));

it('runs asynchronous tasks tick by tick 😉', fakeAsync(() => {
let a = 1;
setTimeout(() => {
a++;
}, 5_000);

setTimeout(() => {
a++;
}, 5_000);

tick(5_000);
expect(a).toBe(2);

tick(5_000);
expect(a).toBe(3);
}));










Zoneless testing



Starting with Angular 20.2, the zoneless mode became stable. In Angular 21, it's the new default.



That also means fakeAsync() and waitForAsync() will stop working unless you explicitly enable Zone.js.



As unfortunate as it is, this means tests relying on these two utilities will have to be rewritten — not entirely, but at least the parts that manage asynchronous tasks.









⏱ Alternatives in Vitest (and Jest)



Luckily, the testing frameworks offer their own mechanisms for async control.



In Vitest and Jest, this feature is called fake timers.



Fake timers mock async APIs like setTimeout, setInterval, and more. They work very similar to waitForAsync and fakeAsync but are not exactly the same.





  • runAllTimers(): Runs all asynchronous tasks, even periodic ones. Also asynchronous tasks triggered by other asynchronous tasks are covered. This is what we know from flush() with the addition, that runAllTimers also covers setInterval.


  • advanceTimersByTime(ms): Runs all asynchronous tasks within a period of time. Close to tick() in fakeAsync().


  • runOnlyPendingTimers() - runs only currently scheduled timers



We have to enable fake timers explicitly, so that the testing framework can create the mocks first.



Since this is done in a beforeEach, we also need to disable them in afterEach.





describe('async tasks', () => {
beforeEach(() => {
vitest.useFakeTimers();
});

afterEach(() => {
vitest.resetAllMocks();
});

it('runs all asynchronous tasks immediately (synchronously)', () => {
let a = 1;
setTimeout(() => {
a++;
}, 5_000);

setTimeout(() => {
a++;
}, 10_000);

vitest.runAllTimers();
expect(a).toBe(3);
});

it('runs asynchronous tasks tick by tick 😉', () => {
let a = 1;
setTimeout(() => {
a++;
}, 5_000);

setTimeout(() => {
a++;
}, 10_000);

vitest.advanceTimersByTime(5_000);
expect(a).toBe(2);

vitest.advanceTimersByTime(5_000);
expect(a).toBe(3);
});
});






Not too bad, right?






Careful with Promises



There was one catch though. As mentioned above, Zone.js didn't compile down to native Promises, because they cannot be mocked. Fake Timers don't do any compilation. So if there is a native Promise, the fakes can't cover them.




it('fails on Promises', () => {
let a = 1;
Promise.resolve().then(() => a++);
vitest.runAllTimers();
expect(a).toBe(2); // this will fail
});






There's also another variation where both Promise and "mockable" timers come together.




it('fails on Promises 1', () => {
let a = 1;
setTimeout(() => Promise.resolve().then(() => a++));
vitest.runAllTimers();
expect(a).toBe(2);
});

it('fails on Promises 2', () => {
let a = 1;
Promise.resolve().then(() => setTimeout(() => a++));
vitest.runAllTimers();
expect(a).toBe(2);
});






What to do? We can fallback to the polling or use our wait function from the test fixtures example above. But there is also a solution for fake timers.



To handle this, fake timers can queue an additional Promise after the real one. Our test can then await that second Promise to ensure all async behavior completes.



Since this is quite common, Vitest provides us fakes for that. They are very easy to remember. In fact, they are the same fakes we had before, just with an Async suffix.




describe('async tasks', () => {
beforeEach(() => {
vitest.useFakeTimers();
});

afterEach(() => {
vitest.resetAllMocks();
});

it('succeeds on Promises', async () => {
let a = 1;
Promise.resolve().then(() => a++);
await vitest.runAllTimersAsync();
expect(a).toBe(2);
});

it('succeeds on Promises 1', async () => {
let a = 1;
setTimeout(() => Promise.resolve().then(() => a++));
await vitest.runAllTimersAsync();
expect(a).toBe(2);
});

it('succeeds on Promises 2', async () => {
let a = 1;
Promise.resolve().then(() => setTimeout(() => a++));
await vitest.runAllTimersAsync();
expect(a).toBe(2);
});
});









Even if you are using Zone.js, whenever you write a new test, use the fake timers.






🧑‍🚀 Testronaut



Let's face it: regardless of whether we use Vitest, Jest, or something else - nothing beats an E2E test. Why?




  • Developers can watch tests run live in the browser.

  • E2E frameworks handle asynchronous behavior automatically. Whether a component is still rendering or waiting on the browser - no problem, the framework’s got you covered.

  • Tools like testing-library rely on plugins to simulate real user events. With E2E frameworks, that's built-in.

  • E2E tests don’t just interact with elements because they exist in the DOM - they ensure the element is actually usable: visible, not overlapped, enabled, etc. for real users.



But there’s a downside: E2E frameworks require the whole application to be up and running. Reaching the feature under test often means navigating through the app, which can be cumbersome and slow.






A Better Way



Cypress Component Testing showed us a better approach. It could compile Angular components, mount them in the browser, and run a full E2E test - but focused on just the component.



That was in 2022. Today, the E2E framework of choice is Playwright. It supports component testing (CT) - but only for frameworks that fully support Vite.



There was a huge community effort to get Playwright CT working with Angular via Vite. It was fully implemented, working, and promising. But in November 2023, the PR was closed by the Playwright team. They had doubts about the long-term viability of CT in general - and a desire to reduce framework-specific maintenance.




👉 Playwright PR comment







Playwright CT Reloaded



Out of the ashes came Testronaut.



Testronaut is led by Younes Jaaidi (and the author of this article). Younes was part of the original effort to bring Angular CT to Playwright and previously contributed heavily to Cypress CT for Angular.



Testronaut is a community-driven Playwright Component Testing runner for Angular - but without forcing Angular to compile via Vite. Instead, it leverages the Angular CLI. That means the same build setup and speed you’re used to from ng serve, and no awkward workarounds.



Testronaut mounts a component and lets Playwright do what it does best: run a full, browser-based test with all the realism and async handling you'd expect from a real E2E framework.



And yes - the test code is straightforward. Here’s an example:




test('should emit an event on click', async ({ mount, page }) => {
await mount(ClickMeComponent, { inputs: { clickMeLabel: 'Press me' } });
await page.getByRole('button', { name: 'Press me' }).click();
await expect(page.getByText('Lift Off!')).toBeVisible();
});






Testronaut is already available, though we recommend waiting until the schematics (ng add @testronaut/angular) are released for a smoother experience.



More info: https://testronaut.dev

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
SOC Incident Playbook: Remote Code Execution (RCE) Defense
1 Warnungen
title: Detect Exploitation - Angular's Testing Revolution: Vitest, Fake Timers & Testronaut
id: 5115660c-d8f0-4471-92c0-8f5b7f76432f
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-25
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-25"
        description = "YARA Signature for "
    strings:
        $str = "Angular\'s Testing Revolution: " ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("Angulars Testing Revolution Vitest Fake ")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*Angulars Testing Revolution Vitest Fake *"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "Angulars Testing Revolution Vitest Fake "
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich Angular&#039;s Testing Revolution: Vitest, Fa.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Angular's Testing Revolution: Vitest, Fake Timers & Testronaut

Thematisch verwandte Begriffe: Angulars, Testing, Revolution, Vitest · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY Kritische Sicherheitsmeldung
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel • Rechts: nächster Artikel • unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...
↗ Original-Quelle