Document Assert.That custom assertions and de-emphasize StringAssert/CollectionAssert#54185
Document Assert.That custom assertions and de-emphasize StringAssert/CollectionAssert#54185Evangelink wants to merge 3 commits into
Conversation
…lectionAssert guidance - Add 'Create custom assertions with Assert.That' section explaining the singleton extensibility hook with a worked extension method example. - Note that StringAssert.That and CollectionAssert.That exist for the same pattern but recommend Assert.That for new code. - Disambiguate the singleton property from the MSTest 3.8 Assert.That(() => condition) expression-tree method. - Strengthen messaging that StringAssert and CollectionAssert are likely to be deprecated and aren't recommended due to discoverability issues. - Add ai-usage: ai-assisted and bump ms.date. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates the MSTest assertions documentation to explain the *.That extensibility hook for custom assertions and to steer new code away from StringAssert/CollectionAssert due to discoverability and likely future deprecation.
Changes:
- Replaces the top callout with stronger guidance to prefer
Assertand warns about likely deprecation ofStringAssert/CollectionAssert. - Adds a new section documenting custom assertions via
Assert.That(and mentionsStringAssert.That/CollectionAssert.That). - Updates best-practices guidance to recommend extending
Assert.That, and addsai-usageplus an updatedms.date.
Show a summary per file
| File | Description |
|---|---|
| docs/core/testing/unit-testing-mstest-writing-tests-assertions.md | Adds Assert.That extensibility documentation and strengthens guidance away from StringAssert/CollectionAssert. |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 2
…e disambiguation NOTE Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@meaghanlewis @gewarren could you please review? |
| ### `Assert.That` property versus `Assert.That(...)` method | ||
|
|
||
| > [!NOTE] | ||
| > Don't confuse the `Assert.That` singleton *property*—used as an extensibility hook—with the `Assert.That(() => condition)` *method* added in MSTest 3.8. The latter accepts a boolean expression and produces detailed failure messages by analyzing the expression tree (for example, `Assert.That(() => order.Total > 0)`). The two APIs share a name but serve different purposes. |
There was a problem hiding this comment.
| > Don't confuse the `Assert.That` singleton *property*—used as an extensibility hook—with the `Assert.That(() => condition)` *method* added in MSTest 3.8. The latter accepts a boolean expression and produces detailed failure messages by analyzing the expression tree (for example, `Assert.That(() => order.Total > 0)`). The two APIs share a name but serve different purposes. | |
| > Don't confuse the `Assert.That` singleton *property*—used as an extensibility hook—with the `Assert.That(() => condition)` *method* added in MSTest 3.8. The latter accepts a Boolean expression and produces detailed failure messages by analyzing the expression tree (for example, `Assert.That(() => order.Total > 0)`). The two APIs share a name but serve different purposes. |
| 1. **Use `Throws`/`ThrowsExactly` for exceptions**: In MSTest v3.8+, prefer `Assert.Throws`, `Assert.ThrowsExactly`, and their async counterparts (`ThrowsAsync`, `ThrowsExactlyAsync`) over the `ExpectedException` attribute. | ||
|
|
||
| 1. **Prefer `Assert` over `StringAssert`/`CollectionAssert`**: When functionality exists in both classes, use the `Assert` class for better discoverability and consistency. | ||
| 1. **Prefer `Assert` over `StringAssert`/`CollectionAssert`**: For better discoverability and consistency, use the `Assert` class. The `StringAssert` and `CollectionAssert` classes are likely to be deprecated in a future release. |
There was a problem hiding this comment.
This should be an unordered (bullet) list.
There was a problem hiding this comment.
Changed the best practices section to an unordered list in da34c0b.
| > [!TIP] | ||
| > When functionality exists in both `Assert` and `StringAssert`/`CollectionAssert`, prefer the `Assert` class. The `Assert` class provides better discoverability and is the recommended choice for new code. `StringAssert` and `CollectionAssert` are maintained for backward compatibility. | ||
| > [!IMPORTANT] | ||
| > For new code, always use the `Assert` class. The `StringAssert` and `CollectionAssert` classes are likely to be deprecated in a future release. They're maintained primarily for backward compatibility, but they're not recommended because splitting assertions across three types hurts discoverability—you can't see all available checks in a single IntelliSense list. |
There was a problem hiding this comment.
| > For new code, always use the `Assert` class. The `StringAssert` and `CollectionAssert` classes are likely to be deprecated in a future release. They're maintained primarily for backward compatibility, but they're not recommended because splitting assertions across three types hurts discoverability—you can't see all available checks in a single IntelliSense list. | |
| > For new code, always use the `Assert` class. The `StringAssert` and `CollectionAssert` classes are likely to be deprecated in a future release. They're maintained primarily for backward compatibility, but they're not recommended because splitting assertions across three types hurts discoverability. |
There was a problem hiding this comment.
I don't think we need to say more than that it hurts discoverability.
There was a problem hiding this comment.
Trimmed the guidance to just the discoverability concern in da34c0b.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Updates the MSTest assertions article to:
Assert.That,StringAssert.That, andCollectionAssert.Thatextensibility hook (the singleton property used as a target for user-authored extension methods, per testfx RFC 002).StringAssertandCollectionAssertare not recommended for new code and are likely to be deprecated. The main reason is discoverability: splitting assertions across three types means you can't see all available checks in a single IntelliSense list.Contributes to microsoft/testfx#8818
Changes
Create custom assertions with Assert.Thatwith:IsPrime) that targets theAssertinstance type.Assert.That.IsPrime(result).StringAssert.ThatandCollectionAssert.Thatexist for the same pattern, but recommendingAssert.Thatfor new code.Assert.That.MyAssertion(...)) is distinct from the MSTest 3.8 expression-tree method (Assert.That(() => condition)).StringAssertandCollectionAssert(NOTE → WARNING), and updated the top-of-doc callout from TIP → IMPORTANT explaining the discoverability problem.Assert.That(notStringAssert.That/CollectionAssert.That).ai-usage: ai-assistedand bumpedms.date.Verification
npx markdownlint-cli2passes with 0 errors.<xref:...>API IDs (Assert.That,StringAssert.That,CollectionAssert.That) resolve against the Microsoft Learn API browser.Content source
Assert.cs,StringAssert.cs,CollectionAssert.cs,Assert.That.cs) and RFC 002 — Framework Extensibility for Custom Assertions.[Obsolete]attribute is shipped yet.Internal previews