Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[quality-improver] AssertSourceCompatibilityTests.SpanAndMemoryCalls tests only half of the Span/Memory × comparer overload combinations

Open Beginner friendly
#11,504 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
84/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
csharp
Domain
testing

Research direction

Open test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssertSourceCompatibilityTests.cs and start with SpanAndMemoryCalls. Add the missing comparer and no-comparer combinations for Contains, DoesNotContain, ContainsAll, and DoesNotContainAll described in the issue. Run the acceptance integration tests and confirm every specified Span/Memory overload shape is represented.

Written by the indexing model from the issue text.

Description

type/automation type/tech-debt
🎯 Repository Quality Improvement Report — Assert Span/Memory Overload Coverage Gap

Analysis Date: 2026-09-24
Focus Area: Assert Span/Memory Overload Resolution Test Coverage
Strategy Type: Custom

Executive Summary

AssertSourceCompatibilityTests.cs exists specifically to "compile manually maintained consumer call shapes" and catch overload-resolution regressions across Span<T>, ReadOnlySpan<T>, arrays, and IEnumerable<T> implicit conversions — a documented concern in this repo because adding overloads can silently make previously-unambiguous calls ambiguous for consumers. Its own VerifyEveryPublicAssertMethodFamilyHasAConsumerCall guard explicitly warns: "It cannot detect a new overload in an existing family, so every overload change must also add representative implicit consumer call shapes."

However, the SpanAndMemoryCalls scenario in that file does not follow its own rule for four heavily-overloaded method families: Assert.Contains, Assert.DoesNotContain, Assert.ContainsAll, and Assert.DoesNotContainAll. Each of these has Span<T>, ReadOnlySpan<T>, Memory<T>, and ReadOnlyMemory<T> overloads in both a "no comparer" and an "IEqualityComparer<T>" shape (8 combinations per family for the value/collection forms), but the test only ever exercises 4 of those 8 combinations per family — and always the same 4, systematically skipping the Span<T>+comparer and Memory<T>+comparer shapes, plus predicate overloads over Span<T>/ReadOnlyMemory<T>. A future overload addition or refactor in this specific slice (e.g. a new Span<T> overload with a different comparer constraint) could introduce an ambiguity for consumers today's suite would not detect.

Full Analysis Report
Focus Area: Assert Span/Memory Overload Resolution Test Coverage
Current State Assessment

Untested combinations (source has the overload; SpanAndMemoryCalls never calls it):

Method Missing combination(s)
Assert.Contains Span<T> value+comparer; Memory<T> value+comparer; predicate over Span<T>; predicate over ReadOnlySpan<T>; predicate over ReadOnlyMemory<T>
Assert.DoesNotContain Same pattern as Contains
Assert.ContainsAll Span<T>+comparer; ReadOnlySpan<T> no-comparer; Memory<T>+comparer; ReadOnlyMemory<T> no-comparer
Assert.DoesNotContainAll Same pattern as ContainsAll

Concretely, in test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssertSourceCompatibilityTests.cs (SpanAndMemoryCalls, ~lines 526–541):

Assert.Contains(1, span);                              // Span, no comparer — tested
Assert.Contains(1, readOnlySpan, comparer);             // ReadOnlySpan, comparer — tested
Assert.Contains((int value) => value > 0, memory);      // Memory, predicate — tested
Assert.Contains(1, readOnlyMemory);                     // ReadOnlyMemory, no comparer — tested
// Never called: Contains(1, span, comparer), Contains(1, memory, comparer),
//               Contains(predicate, span/readOnlySpan/readOnlyMemory)

Assert.ContainsAll(span, span);                         // Span, no comparer — tested
Assert.ContainsAll(readOnlySpan, readOnlySpan, comparer); // ReadOnlySpan, comparer — tested
Assert.ContainsAll(memory, memory);                     // Memory, no comparer — tested
Assert.ContainsAll(readOnlyMemory, readOnlyMemory, comparer); // ReadOnlyMemory, comparer — tested
// Never called: ContainsAll(span, span, comparer), ContainsAll(readOnlySpan, readOnlySpan),
//               ContainsAll(memory, memory, comparer), ContainsAll(readOnlyMemory, readOnlyMemory)

The corresponding overloads do exist in src/TestFramework/TestFramework/Assertions/Assert.Contains.cs, Assert.DoesNotContain.cs, Assert.ContainsAll.cs, and Assert.DoesNotContainAll.cs — this is a test-coverage gap, not a missing-API gap.

Strengths
  • Every other Span/Memory overload family in the same test (AreAllDistinct, AreAllNotNull, AreAllOfType, AreEquivalent, AreSequenceEqual, HasCount, IsEmpty, IsNotEmpty, ContainsSingle) exercises both the comparer and no-comparer, and both value and predicate shapes, across all four span/memory types.
  • The method-family-level guard (VerifyEveryPublicAssertMethodFamilyHasAConsumerCall) correctly prevents an entirely new Assert family from shipping without any consumer call.
Areas for Improvement
  • ⚠️ Medium — Contains/DoesNotContain/ContainsAll/DoesNotContainAll systematically skip half of their Span/Memory × comparer combinations in SpanAndMemoryCalls, contrary to the pattern used for every sibling method family in the same test and contrary to the file's stated purpose.

🤖 Suggested Improvement Tasks
Task 1: Add missing Contains/DoesNotContain Span/Memory combinations

Priority: Medium
Estimated Effort: Small

In SpanAndMemoryCalls, add calls for Assert.Contains(1, span, comparer), Assert.Contains(1, memory, comparer), Assert.Contains(predicate, span) (or readOnlySpan), Assert.Contains(predicate, readOnlyMemory), and the equivalent DoesNotContain shapes, mirroring the existing pattern used for AreAllDistinct/ContainsSingle in the same method (all four collection types × both comparer/no-comparer × value/predicate exercised at least once).

Relevant file: test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssertSourceCompatibilityTests.cs


Task 2: Add missing ContainsAll/DoesNotContainAll Span/Memory combinations

Priority: Medium
Estimated Effort: Small

Add Assert.ContainsAll(span, span, comparer), Assert.ContainsAll(readOnlySpan, readOnlySpan) (no comparer), Assert.ContainsAll(memory, memory, comparer), Assert.ContainsAll(readOnlyMemory, readOnlyMemory) (no comparer), and the equivalent DoesNotContainAll calls, so all four collection types are exercised with and without a comparer.

Relevant file: test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssertSourceCompatibilityTests.cs


Task 3: Add a lightweight combinatorial coverage assertion

Priority: Low
Estimated Effort: Medium

Consider a small reflection-based helper (scoped to just Contains/DoesNotContain/ContainsAll/DoesNotContainAll, since these are the families with the most overload combinations) that asserts every distinct (collectionType, hasComparer, isPredicate) shape found in the public API surface has at least one matching call in ConsumerSource. This would make the gap self-detecting instead of relying on manual review, without expanding VerifyEveryPublicAssertMethodFamilyHasAConsumerCall's scope beyond family names.

Relevant file: test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssertSourceCompatibilityTests.cs


📊 Historical Context
Previous Focus Areas
Date Focus Area Type
2026-09-19 opentelemetry-platformservice-metrics-and-tracestate-coverage-gap Custom
2026-09-18 msbuild-namespace-sanitization-coverage-gap Custom
2026-09-16 extension-self-registration-acceptance-coverage Custom
2026-09-12 noncooperative-parent-process-listener-untested Custom
2026-09-10 ci-run-summary-provenance-guard-coverage-gap Custom

🎯 Recommendations
Immediate Actions (This Week)
  1. Add the missing Contains/DoesNotContain combinations to SpanAndMemoryCalls — Priority: Medium
Short-term Actions (This Month)
  1. Add the missing ContainsAll/DoesNotContainAll combinations — Priority: Medium
  2. Evaluate a reflection-based combinatorial coverage check for these four families — Priority: Low

Next analysis: 2026-09-25 — Focus area selected based on diversity algorithm

🤖 Automated content by GitHub Copilot. Generated by the Repository Quality Improver workflow. · copilot · auto · 211.8 AIC · ⌖ 8 AIC · ⊞ 17.2K · [◷]( · ◷)

Add this agentic workflow to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repository-quality-improver.md@main
  • expires on Sep 26, 2026, 10:36 PM UTC
Dominant language
C#
Stars
1k
Forks
312
Avg merge
8h 14m
Merged PRs (30d)
497

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/testfx

All issues in microsoft/testfx

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.