Repository navigation
Document SetUpFixture inheritance and sharing setup across projects - #1298
Merged
Merged
Conversation
Adds an Inheritance section to the SetUpFixture page covering the attribute being inherited, the concrete class's namespace setting the scope, and derived-class attribute precedence (TestFixture wins; Test-only derived classes become setup fixtures and their tests are not discovered). Adds a Sharing setup across projects section with the plain-class-plus-per-project-SetUpFixture pattern and the static Lazy<T> alternative. All examples are executable snippets, and a verification test builds the assembly's test tree to confirm the precedence rules. Cross-links added from the OneTimeSetUp page and the setup guide. Closes #1293 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
📖 Docs preview removed because this PR was closed. |
SeanKilleen
requested review from
a team and
OsirisTerje
and
a balanced review from Copilot
October 23, 2026 18:04
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The article and published snippet incorrectly promise per-run initialization for a static Lazy<T>, which follows the loaded type's lifetime instead.
1 open issue
What changed in this PR
Addresses #1293 by documenting SetUpFixture inheritance and patterns for sharing setup logic across test projects.
Changes:
- Explains inherited namespace scope and fixture-attribute precedence.
- Adds shared-package and static
Lazy<T>examples. - Adds discovery-verification tests and cross-links from related setup documentation.
| File | Description |
|---|---|
docs/snippets/Snippets.NUnit/Attributes/SetUpFixtureAttributeExamples.cs |
Adds inheritance and sharing examples, plus discovery-verification tests. |
docs/articles/nunit/writing-tests/setup-and-teardown.md |
Links to the inheritance and shared-setup guidance. |
docs/articles/nunit/writing-tests/attributes/setupfixture.md |
Documents inheritance rules and cross-project setup patterns. |
docs/articles/nunit/writing-tests/attributes/onetimesetup.md |
Links to the shared-package setup pattern. |
Review effort: Balanced
| [!code-csharp[SetUpFixtureSharingConsumer](~/snippets/Snippets.NUnit/Attributes/SetUpFixtureAttributeExamples.cs#SetUpFixtureSharingConsumer)] | ||
|
|
||
| If you cannot ask consumers to add a class, start the resource on first use from a static `Lazy<T>` in the base test | ||
| class. It starts once per test run, but NUnit offers no hook to stop it at the end of the run, so use this only for |
OsirisTerje
approved these changes
Oct 23, 2026
OsirisTerje
left a comment
Member
There was a problem hiding this comment.
Very good to have this described. We talk about typical patterns for usage. This is one of them. Hope we can reach more of these.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Addresses Copilot review feedback on PR #1298. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Oct 23, 2026
…1298) * Document SetUpFixture inheritance and sharing setup across projects Adds an Inheritance section to the SetUpFixture page covering the attribute being inherited, the concrete class's namespace setting the scope, and derived-class attribute precedence (TestFixture wins; Test-only derived classes become setup fixtures and their tests are not discovered). Adds a Sharing setup across projects section with the plain-class-plus-per-project-SetUpFixture pattern and the static Lazy<T> alternative. All examples are executable snippets, and a verification test builds the assembly's test tree to confirm the precedence rules. Cross-links added from the OneTimeSetUp page and the setup guide. Closes #1293 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Say SetUpFixture can be inherited rather than is inherited Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Describe the static Lazy<T> lifetime as per loaded type, not per run Addresses Copilot review feedback on PR #1298. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> 7f62c2b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Closes #1293
What changed
setupfixture.mdgains two sections:[SetUpFixture]is inherited; the concrete class's namespace sets the scope; an abstract base is not a setup fixture by itself; and fixture attributes are resolved one inheritance level at a time, so[TestFixture]on the derived class wins over the inherited[SetUpFixture], while a derived class with only[Test]methods becomes a setup fixture and its tests are not discovered. Ends with the tip to put[SetUpFixture]on the concrete class anyway.[SetUpFixture]in each consuming test project, and the staticLazy<T>alternative for when consumers cannot be asked to add a class.onetimesetup.mdandsetup-and-teardown.mdget a one-line cross-link each to the new sections.Executable snippets
Every example on the page is a region in
SetUpFixtureAttributeExamples.csand runs as part of the snippets test suite. The file also containsSetUpFixtureInheritanceVerification, which builds this assembly's test tree withDefaultTestAssemblyBuilder(the same path the framework uses at discovery) and asserts:SetUpFixtureunder its own namespace and contains the consumer tests[TestFixture]is built as aTestFixturewith one test[Test]method is built as aSetUpFixtureand the test is absentThis confirms the third rule from the issue, which @OsirisTerje had flagged as "need to check it". The undiscovered test asserts
Assert.Fail, so it would also break the suite if NUnit ever started discovering it.dotnet test --list-testslikewise does not list it. The rules match theGetFixtureBuilderAttributesloop inDefaultSuiteBuilder, which walks the inheritance chain one level at a time and stops at the first level with any fixture attribute.Verification
dotnet test docs/snippets/Snippets.slnx: 608 passed, 0 failed (NUnit), 2 passed (NUnitLite)docfx docs/docfx.jsonbuilds; all six snippet references and the three anchor cross-links render🤖 Generated with Claude Code