Library / SDK
bUnit-dev/bUnit avatar
bUnit-dev/bUnit

bUnit tests Blazor components without a browser, and the comparer is why

bUnit is a testing library for Blazor components that make tests look, feel, and runs like regular unit tests. bUnit makes it easy to render and control a component under test’s life-cycle, pass parameter and inject services into it, trigger event handlers, and verify the rendered markup from the component using a built-in semantic HTML comparer.

1,307 stars125 forksC#MIT

At a glance

What is it?
bUnit renders a Blazor component inside the test process, drives its life-cycle, passes parameters and injected services, triggers event handlers and checks the resulting markup with a semantic HTML comparer instead of string matching. It runs inside xUnit, NUnit, MSTest or TUnit, so a component test is an ordinary unit test that finishes in milliseconds.
Who is it for?
Adopt bUnit if you write Blazor components and want component-level tests that run in milliseconds rather than browser tests that take seconds. Do not adopt it expecting to cover everything a browser test covers, since it does not execute CSS, real layout or browser APIs.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the library actually does

bUnit is a testing library for Blazor components whose goal is to make it easy to write stable unit tests. The listed capabilities are the whole API surface, and each maps to something a component genuinely needs.

You can set up and define components under test using C# or Razor syntax. You can pass parameters, cascading values and inject services into the component under test. You can interact with and inspect components and trigger event handlers, which means a click handler can be invoked directly rather than simulated. And you verify outcomes using the semantic HTML comparer.

The rendering happens in the test process. There is no browser, no WebDriver and no test host to start. That is the reason for the speed claim in the README: a test runs in milliseconds, compared with browser-based UI tests which usually take seconds.

The speed is not the interesting part on its own. The interesting part is that a component test becomes an ordinary unit test in your existing framework. bUnit builds on top of xUnit, NUnit, MSTest and TUnit, and the Blazor component tests run in just the same way as any normal unit test. There is no separate test project type, no runner configuration and no second CI job.

That matters for adoption more than the timing. A test suite that takes 40 seconds because of a browser is a test suite people stop running.

The semantic comparer is the part that makes tests stable

A component test almost always ends with an assertion about markup. The usual approach is to compare a string, which produces a test that breaks when someone reformats a tag, changes attribute order, or the framework renders an extra attribute, and nobody knows whether the change matters.

The semantic HTML comparer is bUnit's answer. It compares the rendered markup in a way that understands the structure of the HTML rather than its literal text, so a formatting difference is not a failure and a structural difference is.

That is what the word stable in the README's goal refers to. A semantic assertion expresses intent: that a button exists with this text and that clicking it raised the expected event, rather than that a particular sequence of characters appeared.

The repository topics also include snapshot-testing, so both approaches are in play. Snapshots are useful when you want a full record of the output and do not mind reviewing diffs, and the comparer is useful when you want assertions that survive harmless changes. A library supporting both is being realistic about the fact that teams differ here.

The other capability worth singling out is mocking `IJSRuntime`, which is the interface Blazor components use to call into JavaScript.

Four packages, and one that is not what you expect

bUnit ships as several NuGet packages, and the README says most people should just take the main one.

`bUnit` adds support for testing Blazor components, and that is the default choice.

`bUnit.template` is a project template, and the README notes it currently creates xUnit-based bUnit test projects only. So if your test suite is on NUnit or MSTest, the template does not help you and you add the package by hand.

`bUnit.generators` provides source code generators to minimise code setup in various situations. This is the package that removes the boilerplate bUnit otherwise requires around the test context setup.

`bUnit.web.query` is the most interesting one, because it is an implementation of testing-library.com's query APIs for bUnit. That means the querying vocabulary from the JavaScript testing ecosystem, getByRole and its relatives, is available in C# tests.

That package exists because Blazor components have accessibility semantics baked into their markup through ARIA attributes, and a query API built on roles rather than CSS selectors is a better fit for testing what a user perceives than a CSS selector would be. Porting a familiar API also means documentation and Stack Overflow answers transfer between the two ecosystems.

The trade is an extra dependency for a specific style of test. Not every team wants it, which is why it is separate.

Version support is the thing to plan around

The README publishes a compatibility matrix, which is more useful than it sounds.

bUnit 1.x supports .NET Core 3.1 through .NET 9, and bUnit 2.x requires .NET 8 or newer.

That is a real decision point rather than trivia. If you are on .NET 6 or .NET 7, only the 1.x line works, and staying there means the project has stopped supporting your target. If you are on .NET 8 or newer you can move to 2.x, and there is a migration guide under the documentation.

The release history shows the 2.x line is where the activity is: v2.9.0 on 2026-08-03, v2.10.3 on 2026-09-08 and v2.11.3 on 2026-09-13, with the last push on 2026-09-18. Patch releases within days of each other is the pattern of a project with an active issue list rather than one in maintenance.

There is also a `.NET Foundation` line in the README, stating that the project is supported by the .NET Foundation. For a testing library that many teams will end up depending on in their build, that is a governance signal rather than a technical one.

The repository shows a modern .NET project layout: `bunit.slnx`, which is the newer solution file format, `Directory.Build.props` and `Directory.Packages.props` for central package management, `global.json` pinning the SDK, `version.json` for versioning, and `key.snk` for strong naming. There is also a `.devcontainer/` directory and a `docs/` site whose published form is bunit.dev.

Editorial conclusion

Adopt bUnit if you write Blazor components and want component-level tests that run in milliseconds rather than browser tests that take seconds. Do not adopt it expecting to cover everything a browser test covers, since it does not execute CSS, real layout or browser APIs. Verify first which bUnit major version matches your .NET target, since 1.x supports .NET Core 3.1 through .NET 9 while 2.x requires .NET 8 or newer, and plan for the migration if you are on 1.x.

Frequently asked questions

What does bUnit do that a browser test does not?

It renders the Blazor component inside the test process, so you can drive its life-cycle, pass parameters and injected services, trigger event handlers and inspect the resulting markup without a browser. Tests run in milliseconds rather than the seconds a browser-based UI test takes.

Which test frameworks does bUnit work with?

It builds on xUnit, NUnit, MSTest and TUnit, running Blazor component tests the same way as any other unit test. Note that the bUnit.template project template currently creates xUnit-based test projects only.

Which .NET versions does bUnit support?

bUnit 1.x supports .NET Core 3.1 through .NET 9, and bUnit 2.x requires .NET 8 or newer. The 2.x line is where the recent releases are, so teams below .NET 8 are limited to the older line.

What is bUnit.web.query for?

It is an implementation of testing-library.com's query APIs for bUnit, so tests can select elements by role and other semantic queries in C# rather than relying on CSS selectors. It is a separate optional package.

Official sources

  1. bUnit-dev/bUnit on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bunit-dev-bunit.svg)](https://hysenlabs.com/projects/bunit-dev-bunit)

Was this useful?