惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyberwarzone
Cyberwarzone
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
The Hacker News
The Hacker News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
D
Docker
H
Hacker News: Front Page
Recent Announcements
Recent Announcements
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Proofpoint News Feed
Security Latest
Security Latest
AI
AI
I
InfoQ
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
S
Secure Thoughts
Attack and Defense Labs
Attack and Defense Labs
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Scott Helme
Scott Helme
N
News | PayPal Newsroom
Y
Y Combinator Blog
V
Visual Studio Blog
Latest news
Latest news
大猫的无限游戏
大猫的无限游戏
Microsoft Security Blog
Microsoft Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学
V
Vulnerabilities – Threatpost
C
Cyber Attacks, Cyber Crime and Cyber Security
TaoSecurity Blog
TaoSecurity Blog
S
Security @ Cisco Blogs
D
DataBreaches.Net
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
T
Troy Hunt's Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
H
Heimdal Security Blog
美团技术团队
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Security Affairs
T
Threat Research - Cisco Blogs
Webroot Blog
Webroot Blog
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏

Duende Software Official Site

Duende Software Duende Software Duende Software Duende Software Duende Software Stop AI Bots from Wasting Your Server How Duende IdentityServer Filters Claims (And Why It Matters) Core vs Extended Protocols in Duende IdentityServer v8: What You Get and When You Need More Your IdentityServer v8 Upgrade Checklist: A Quick Pre-Flight Guide Setting Up SAML Single Sign-On in ASP.NET with Duende IdentityServer Your Identity, Your Terms: Duende's Modular Identity Infrastructure and v8.x Release Duende Spring Launch '26: Identity Infrastructure That Expands With You SAML and OpenID Connect (OIDC): Coexistence, Not Competition The 9 Components of SAML You Need to Know, Ranked by Importance The Cost of NOT Implementing Financial-Grade Security Token Issuer Isolation: Why It Matters for Security and Compliance The Composable Identity Pattern: Build What You Need, Skip What You Don't Multi-Brand Identity: When Your Company Needs More Than One Face Post-Quantum Cryptography in .NET 10: A Practical Guide The field Keyword in C# 14: Write Less, Validate More The Real Cost of Build vs. Buy for Identity OAuth 2.1 Made Simple: The Only Flows You Need Beyond localhost: Multi-Instance ASP.NET Core Deployment with .NET 10 Harden Your .NET JSON Deserialization with System.Text.Json and JsonSerializerOptions.Strict ASP.NET Core Cookie Size Limits in Production: Causes and Fixes The Emergency Stop Button - Implementing Immediate Token Revocation in .NET 10 The 2025 OWASP Top 10 and IdentityServer Update Guidance for CVE-2026-40372 - ASP.NET Data Protection Why a Standard JWT Access Token Matters The Identity Governance Checklist You Wish You Had Six Months Ago The History and Future of SAML: Why a 20-Year-Old Protocol Still Matters The Cookie Apocalypse Already Happened Verify - Open Source Sponsorship Why Identity Is Infrastructure, Not a Feature Extending Duende IdentityServer Server-Side Sessions with Dynamic User Metadata Give Your AI Coding Assistant Duende Expertise with Agent Skills and MCP Server Triggering User Registration via OpenID Connect with Duende IdentityServer Improving .NET Security Code with C# 14 Property Extensions Developing Audit Logs with Duende IdentityServer Events Patch Releases: Addressing CVE-2026-26127 in Microsoft.BCL.Memory Client-Initiated Backchannel Authentication (CIBA) in ASP.NET Core 10 with Duende Identity Server Rate Limiting IdentityServer Endpoints It's Probably DNS - Can You Dig It? Security Lingo Explained: Encode vs Encrypt vs Hash Implementing Zero Trust with Resource Isolation Security Lingo Explained: JWT DPoP Security for .NET APIs with JwtBearer Extensions v1.0.0 Announcing the Duende IdentityServer4 Migration Analysis Tool BenchmarkDotNet - Open Source Sponsorship Security Lingo Explained: PAR Why Signing Key Rotation Matters in OpenID Connect and Duende IdentityServer Security Lingo Explained: OP Duende Year-End Review 2025 Security Lingo Explained: BCP Security Lingo Explained: DPoP Security Lingo Explained: Auth Secure frontend apps with the BFF Pattern Scaling with Duende IdentityServer, MCP, and AI Duende IdentityServer v7.4 is now available Duende BFFv4 is now available Securing OpenAPI and Swagger UI with OAuth in .NET 10 Building a Federation Gateway with Duende IdentityServer: Strategies and Considerations for Identity Orchestration
Duende Software
Khalid Abuhakmeh, Maarten Balliauw · 2026-07-09 · via Duende Software Official Site

Every test you write needs a place to run. Before the assertions fire, before the snapshots compare, before a single line of application code gets exercised, something has to discover your tests, spin up the runtime, manage parallelism, and report results. For most .NET developers, that something is xUnit.net, and it’s so good at its job that you probably never think about it.

That invisible reliability is exactly why we’re sponsoring it. Let’s hear from the current maintainer as to what motivated them to build such a foundational project:

"I have been a developer using Test Driven Development for more than 20 years, and xUnit.net represents the codified guidance that Jim Newkirk and I would frequently give at development conferences to teach others how to get the most out of unit testing. Now that I’m retired, sponsorships like this help keep xUnit.net moving forward."
– Brad Wilson

Join us in congratulating our sixth open-source sponsorship, xUnit.net.

What is xUnit.net?

xUnit.net is a free, open-source, community-focused unit testing tool for .NET. Created by Brad Wilson and James Newkirk (the original author of NUnit), xUnit.net was built from the ground up to incorporate the lessons learned from earlier testing frameworks. The result is a lean, extensible, opinionated framework that trusts developers to write tests the way they want.

Developers commonly refer to the project as “xUnit,” though the official name is xUnit.net. Either is perfectly acceptable in conversation.

xUnit.net v3 is the current major release, supporting .NET 8.0 or later and .NET Framework 4.7.2 or later. It runs everywhere you’d expect: the .NET SDK command line, Visual Studio, Visual Studio Code, JetBrains Rider, and NCrunch. The project is part of the .NET Foundation, licensed under Apache 2.0, and has earned over 4,500 stars on GitHub with 27,400+ projects depending on it. Brad Wilson alone has made over 2,600 contributions to the repository.

The framework’s philosophy rests on a few core principles: simplicity (tests are just classes with methods), extensibility (almost everything can be overridden or replaced), and sensible defaults (parallelism is on by default, test class isolation is the norm). These design decisions make xUnit.net feel less like a framework you fight and more like one that stays out of your way.

What sets xUnit.net apart from earlier frameworks is how it handles the test lifecycle. There’s no [SetUp] or [TearDown]. Instead, constructors and IDisposable handle per-test setup and cleanup. Shared state across tests uses IClassFixture<T> or ICollectionFixture<T>, making resource lifetimes explicit rather than hidden behind attribute conventions. This approach makes tests easier to reason about and reduces the surprises that come from shared mutable state between test methods.

Getting Started

To add xUnit.net to an existing test project, install the NuGet package:

Shell

dotnet add package xunit.v3

That’s it. No runner packages to install separately, no additional configuration files. xUnit.net v3 includes a built-in runner, so you execute your tests with dotnet run rather than dotnet test (though dotnet test still works via the Visual Studio adapter).

Here’s a simple test class showing both [Fact] (a single test case) and [Theory] (a parameterized test):

Csharp

namespace MyProject.Tests;

public class CalculatorTests
{
    [Fact]
    public void Adding_two_and_two_returns_four()
    {
        var result = 2 + 2;
        Assert.Equal(4, result);
    }

    [Theory]
    [InlineData(1, 1, 2)]
    [InlineData(5, 3, 8)]
    [InlineData(0, 0, 0)]
    public void Addition_is_correct(int a, int b, int expected)
    {
        var result = a + b;
        Assert.Equal(expected, result);
    }
}

Run the tests:

xUnit.net v3 In-Process Runner v3.2.2 (64-bit .NET 10.0.8)
  Discovering: MyProject.Tests
  Discovered:  MyProject.Tests
  Starting:    MyProject.Tests
  Finished:    MyProject.Tests
=== TEST EXECUTION SUMMARY ===
   MyProject.Tests  Total: 4, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0, Time: 0.032s

xUnit.net at Duende

xUnit.net runs under every test we write at Duende Software. Every Shouldly assertion and every Verify snapshot across our products executes on xUnit.net. It powers our IdentityServer tests, our BFF Security Framework integration tests, our open-source library tests, and our end-to-end Playwright tests. When we say we care about testing, xUnit.net is where that commitment lives in code.

Here’s an example of how we use xUnit.net’s IClassFixture<> with WebApplicationFactory to integration test IdentityServer endpoints. This pattern works just as well for anyone testing their own IdentityServer deployment.

First, a minimal IdentityServer host:

Csharp

// Program.cs
using Duende.IdentityServer.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddIdentityServer()
    .AddInMemoryApiScopes([
        new ApiScope("api1", "My API")
    ])
    .AddInMemoryClients([
        new Client
        {
            ClientId = "client",
            AllowedGrantTypes = GrantTypes.ClientCredentials,
            ClientSecrets = { new Secret("secret".Sha256()) },
            AllowedScopes = { "api1" }
        }
    ]);

var app = builder.Build();

app.UseIdentityServer();

app.Run();

public partial class Program;

Then, integration tests that verify the discovery document:

Csharp

using System.Net;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc.Testing;

namespace IdentityServerHost.Tests;

public class DiscoveryEndpointTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly HttpClient _client;

    public DiscoveryEndpointTests(WebApplicationFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task Discovery_endpoint_returns_success()
    {
        var response = await _client.GetAsync("/.well-known/openid-configuration");
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }

    [Fact]
    public async Task Discovery_endpoint_contains_expected_issuer()
    {
        var response = await _client.GetAsync("/.well-known/openid-configuration");
        var content = await response.Content.ReadAsStringAsync();
        var document = JsonDocument.Parse(content);

        Assert.True(document.RootElement.TryGetProperty("issuer", out var issuer));
        Assert.NotNull(issuer.GetString());
    }

    [Fact]
    public async Task Discovery_endpoint_lists_supported_scopes()
    {
        var response = await _client.GetAsync("/.well-known/openid-configuration");
        var content = await response.Content.ReadAsStringAsync();
        var document = JsonDocument.Parse(content);

        Assert.True(document.RootElement.TryGetProperty("scopes_supported", out var scopes));
        var scopeList = scopes.EnumerateArray()
            .Select(s => s.GetString())
            .ToList();
        Assert.Contains("api1", scopeList);
    }

    [Fact]
    public async Task Discovery_endpoint_lists_supported_grant_types()
    {
        var response = await _client.GetAsync("/.well-known/openid-configuration");
        var content = await response.Content.ReadAsStringAsync();
        var document = JsonDocument.Parse(content);

        Assert.True(
            document.RootElement.TryGetProperty("grant_types_supported", out var grantTypes));
        var grantTypeList = grantTypes.EnumerateArray()
            .Select(g => g.GetString())
            .ToList();
        Assert.Contains("client_credentials", grantTypeList);
    }
}

This test class uses IClassFixture<WebApplicationFactory<Program>> to share a single test server across all four tests. xUnit.net manages the fixture’s lifecycle: it creates the factory once before the first test runs and disposes it after the last test finishes. The tests themselves verify that the IdentityServer discovery document is accessible, contains a valid issuer, advertises the api1 scope, and supports the client_credentials grant type.

You can adapt this pattern to test any aspect of your IdentityServer configuration: token endpoint responses, introspection behavior, CORS headers, or custom endpoints.

The test project only needs two package references:

Shell

dotnet add package xunit.v3
dotnet add package Microsoft.AspNetCore.Mvc.Testing

And a project reference to your IdentityServer host. That’s all you need to start testing your identity infrastructure.

Sponsorship Details

Duende Software is sponsoring xUnit.net for the next 12 months at $250 per month (totaling $3,000 for the year).

If you benefit from xUnit.net, consider sponsoring xUnit.net on GitHub or contributing code, docs, or bug reports.

We’d like to thank Brad Wilson for his work on xUnit.net and its role in shaping how an entire generation of .NET developers write tests. This award is our third sponsorship in the testing space, following Shouldly and Verify, and it’s no coincidence. Testing is foundational to how we build secure identity software at Duende Software, and xUnit.net is the foundation under all of it.

Try It Out

If you haven’t tried xUnit.net v3 yet, now’s a good time. Check out the getting started guide and the official documentation to dive in.