diff --git a/TUnit.Assertions.Should.Tests/CollectionTests.cs b/TUnit.Assertions.Should.Tests/CollectionTests.cs
index e99e28abef..48104e3a64 100644
--- a/TUnit.Assertions.Should.Tests/CollectionTests.cs
+++ b/TUnit.Assertions.Should.Tests/CollectionTests.cs
@@ -108,6 +108,45 @@ public async Task Dictionary_ContainKeyWithValue()
         await dict.Should().ContainKeyWithValue("one", 1);
     }
 
+    [Test]
+    public async Task Dictionary_size_and_count_methods()
+    {
+        IReadOnlyDictionary<string, int> dict = new Dictionary<string, int>
+        {
+            ["one"] = 1,
+            ["two"] = 2,
+        };
+
+        await dict.Should().NotBeEmpty();
+        await dict.Should().HaveAtLeast(1);
+        await dict.Should().HaveAtMost(5);
+        await dict.Should().HaveCountBetween(1, 3);
+
+        IReadOnlyDictionary<string, int> empty = new Dictionary<string, int>();
+        await empty.Should().BeEmpty();
+
+        IReadOnlyDictionary<string, int> single = new Dictionary<string, int> { ["only"] = 1 };
+        await single.Should().HaveSingleItem();
+    }
+
+    [Test]
+    public async Task MutableDictionary_size_and_count_methods()
+    {
+        IDictionary<string, int> dict = new Dictionary<string, int>
+        {
+            ["one"] = 1,
+            ["two"] = 2,
+        };
+
+        await dict.Should().NotBeEmpty();
+        await dict.Should().HaveAtLeast(1);
+        await dict.Should().HaveAtMost(5);
+        await dict.Should().HaveCountBetween(1, 3);
+
+        IDictionary<string, int> single = new Dictionary<string, int> { ["only"] = 1 };
+        await single.Should().HaveSingleItem();
+    }
+
     [Test]
     public async Task HashSet_BeSupersetOf()
     {
diff --git a/TUnit.Assertions.Should/Core/ShouldDictionarySource.cs b/TUnit.Assertions.Should/Core/ShouldDictionarySource.cs
index c058bc04b0..2954b2d9bb 100644
--- a/TUnit.Assertions.Should/Core/ShouldDictionarySource.cs
+++ b/TUnit.Assertions.Should/Core/ShouldDictionarySource.cs
@@ -117,6 +117,61 @@ public ShouldAssertion<IReadOnlyDictionary<TKey, TValue>> AnyValue(
         var inner = ApplyBecause(new DictionaryAnyValueAssertion<IReadOnlyDictionary<TKey, TValue>, TKey, TValue>(Context, predicate));
         return new ShouldAssertion<IReadOnlyDictionary<TKey, TValue>>(Context, inner);
     }
+
+    // The count/size methods below are hand-written because the source DictionaryAssertion shadows the
+    // inherited collection methods (IsEmpty, HasSingleItem, ...) with dictionary-typed `public new`
+    // overloads whose abstract return type the Should generator can't construct. Without these the
+    // generated Be/Have counterparts would silently disappear from the dictionary Should surface.
+
+    public ShouldAssertion<IReadOnlyDictionary<TKey, TValue>> BeEmpty()
+    {
+        Context.ExpressionBuilder.Append(".BeEmpty()");
+        var inner = ApplyBecause(new CollectionIsEmptyAssertion<IReadOnlyDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context));
+        return new ShouldAssertion<IReadOnlyDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IReadOnlyDictionary<TKey, TValue>> NotBeEmpty()
+    {
+        Context.ExpressionBuilder.Append(".NotBeEmpty()");
+        var inner = ApplyBecause(new CollectionIsNotEmptyAssertion<IReadOnlyDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context));
+        return new ShouldAssertion<IReadOnlyDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IReadOnlyDictionary<TKey, TValue>> HaveSingleItem()
+    {
+        Context.ExpressionBuilder.Append(".HaveSingleItem()");
+        var inner = ApplyBecause(new HasSingleItemAssertion<IReadOnlyDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context));
+        return new ShouldAssertion<IReadOnlyDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IReadOnlyDictionary<TKey, TValue>> HaveAtLeast(
+        int minCount,
+        [CallerArgumentExpression(nameof(minCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append(".HaveAtLeast(").Append(expression).Append(')');
+        var inner = ApplyBecause(new CollectionHasAtLeastAssertion<IReadOnlyDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context, minCount));
+        return new ShouldAssertion<IReadOnlyDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IReadOnlyDictionary<TKey, TValue>> HaveAtMost(
+        int maxCount,
+        [CallerArgumentExpression(nameof(maxCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append(".HaveAtMost(").Append(expression).Append(')');
+        var inner = ApplyBecause(new CollectionHasAtMostAssertion<IReadOnlyDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context, maxCount));
+        return new ShouldAssertion<IReadOnlyDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IReadOnlyDictionary<TKey, TValue>> HaveCountBetween(
+        int min,
+        int max,
+        [CallerArgumentExpression(nameof(min))] string? minExpression = null,
+        [CallerArgumentExpression(nameof(max))] string? maxExpression = null)
+    {
+        Context.ExpressionBuilder.Append($".HaveCountBetween({minExpression}, {maxExpression})");
+        var inner = ApplyBecause(new CollectionHasCountBetweenAssertion<IReadOnlyDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context, min, max));
+        return new ShouldAssertion<IReadOnlyDictionary<TKey, TValue>>(Context, inner);
+    }
 }
 
 [ShouldGeneratePartial(typeof(MutableDictionaryAssertion<,>))]
@@ -228,4 +283,57 @@ public ShouldAssertion<IDictionary<TKey, TValue>> AnyValue(
         var inner = ApplyBecause(new MutableDictionaryAnyValueAssertion<IDictionary<TKey, TValue>, TKey, TValue>(Context, predicate));
         return new ShouldAssertion<IDictionary<TKey, TValue>>(Context, inner);
     }
+
+    // See ShouldDictionarySource: hand-written because MutableDictionaryAssertion shadows the inherited
+    // collection methods with dictionary-typed `public new` overloads the Should generator can't construct.
+
+    public ShouldAssertion<IDictionary<TKey, TValue>> BeEmpty()
+    {
+        Context.ExpressionBuilder.Append(".BeEmpty()");
+        var inner = ApplyBecause(new CollectionIsEmptyAssertion<IDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context));
+        return new ShouldAssertion<IDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IDictionary<TKey, TValue>> NotBeEmpty()
+    {
+        Context.ExpressionBuilder.Append(".NotBeEmpty()");
+        var inner = ApplyBecause(new CollectionIsNotEmptyAssertion<IDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context));
+        return new ShouldAssertion<IDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IDictionary<TKey, TValue>> HaveSingleItem()
+    {
+        Context.ExpressionBuilder.Append(".HaveSingleItem()");
+        var inner = ApplyBecause(new HasSingleItemAssertion<IDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context));
+        return new ShouldAssertion<IDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IDictionary<TKey, TValue>> HaveAtLeast(
+        int minCount,
+        [CallerArgumentExpression(nameof(minCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append(".HaveAtLeast(").Append(expression).Append(')');
+        var inner = ApplyBecause(new CollectionHasAtLeastAssertion<IDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context, minCount));
+        return new ShouldAssertion<IDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IDictionary<TKey, TValue>> HaveAtMost(
+        int maxCount,
+        [CallerArgumentExpression(nameof(maxCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append(".HaveAtMost(").Append(expression).Append(')');
+        var inner = ApplyBecause(new CollectionHasAtMostAssertion<IDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context, maxCount));
+        return new ShouldAssertion<IDictionary<TKey, TValue>>(Context, inner);
+    }
+
+    public ShouldAssertion<IDictionary<TKey, TValue>> HaveCountBetween(
+        int min,
+        int max,
+        [CallerArgumentExpression(nameof(min))] string? minExpression = null,
+        [CallerArgumentExpression(nameof(max))] string? maxExpression = null)
+    {
+        Context.ExpressionBuilder.Append($".HaveCountBetween({minExpression}, {maxExpression})");
+        var inner = ApplyBecause(new CollectionHasCountBetweenAssertion<IDictionary<TKey, TValue>, KeyValuePair<TKey, TValue>>(Context, min, max));
+        return new ShouldAssertion<IDictionary<TKey, TValue>>(Context, inner);
+    }
 }
diff --git a/TUnit.Assertions.Tests/DictionaryCollectionTests.cs b/TUnit.Assertions.Tests/DictionaryCollectionTests.cs
index cc29f16a0b..7efa8333b9 100644
--- a/TUnit.Assertions.Tests/DictionaryCollectionTests.cs
+++ b/TUnit.Assertions.Tests/DictionaryCollectionTests.cs
@@ -626,4 +626,288 @@ public async Task IDictionary_ContainsKey_With_Custom_Comparer()
         await Assert.That(dictionary)
             .ContainsKey("HELLO", StringComparer.OrdinalIgnoreCase);
     }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_And_Value_IsEqualTo_Passes()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(dictionary).ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_And_Value_IsEqualTo_Fails_When_Value_Different()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        var exception = await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
+            async () => await Assert.That(dictionary).ContainsKey("Key").And.Value.IsEqualTo(9999L));
+
+        await Assert.That(exception.Message).Contains("1234");
+    }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_And_Value_Fails_When_Key_Missing()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        var exception = await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
+            async () => await Assert.That(dictionary).ContainsKey("Missing").And.Value.IsEqualTo(1234L));
+
+        // The ContainsKey check runs first (pre-work), so a missing key fails with the
+        // standard "contain key" message rather than a raw KeyNotFoundException.
+        await Assert.That(exception.Message).Contains("contain key");
+    }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_And_Value_Member()
+    {
+        var dictionary = new Dictionary<string, Holder>
+        {
+            ["Key"] = new Holder(1234L)
+        };
+
+        await Assert.That(dictionary)
+            .ContainsKey("Key").And.Value.Member(x => x.Inner, p => p.IsEqualTo(1234L));
+    }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_And_Value_Supports_Other_Assertions()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(dictionary).ContainsKey("Key").And.Value.IsGreaterThan(1000L);
+        await Assert.That(dictionary).ContainsKey("Key").And.Value.IsNotEqualTo(0L);
+    }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_And_Value_Then_Value_Level_And()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(dictionary)
+            .ContainsKey("Key").And.Value.IsGreaterThan(1000L).And.IsLessThan(2000L);
+    }
+
+    [Test]
+    public async Task Dictionary_And_Value_Still_Allows_Dictionary_Chaining()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L,
+            ["Other"] = 1L
+        };
+
+        // The And continuation still exposes the regular dictionary methods.
+        await Assert.That(dictionary).ContainsKey("Key").And.ContainsKey("Other");
+    }
+
+    [Test]
+    public async Task Dictionary_LongerChain_Then_Value()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["First"] = 1L,
+            ["Key"] = 1234L
+        };
+
+        // Earlier assertions in the chain run as pre-work before the value is read.
+        await Assert.That(dictionary)
+            .ContainsKey("First").And.ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_With_Comparer_And_Value()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Hello"] = 1234L
+        };
+
+        await Assert.That(dictionary)
+            .ContainsKey("HELLO", StringComparer.OrdinalIgnoreCase).And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task IReadOnlyDictionary_ContainsKey_And_Value_IsEqualTo()
+    {
+        IReadOnlyDictionary<string, long> dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(dictionary).ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task IDictionary_ContainsKey_And_Value_IsEqualTo()
+    {
+        IDictionary<string, long> dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(dictionary).ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task Dictionary_IsNotEmpty_Preserves_Dictionary_Continuation()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        // IsNotEmpty now keeps the dictionary continuation, so ContainsKey/.Value remain available.
+        await Assert.That(dictionary)
+            .IsNotEmpty()
+            .And.ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task Dictionary_IsEmpty_Preserves_Dictionary_Continuation()
+    {
+        var nonEmpty = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(nonEmpty)
+            .IsEmpty()
+            .Or.ContainsKey("Key");
+    }
+
+    [Test]
+    public async Task IDictionary_IsNotEmpty_Preserves_Dictionary_Continuation()
+    {
+        IDictionary<string, long> dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(dictionary)
+            .IsNotEmpty()
+            .And.ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task Dictionary_Count_Preserves_Dictionary_Continuation()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L,
+            ["Other"] = 1L
+        };
+
+        await Assert.That(dictionary)
+            .Count().IsEqualTo(2).And.ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task Dictionary_Count_Comparison_Methods_Work()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["a"] = 1L,
+            ["b"] = 2L,
+            ["c"] = 3L
+        };
+
+        await Assert.That(dictionary).Count().IsGreaterThan(2);
+        await Assert.That(dictionary).Count().IsLessThanOrEqualTo(3).And.ContainsKey("a");
+        await Assert.That(dictionary).Count().IsNotEqualTo(0).And.IsNotEmpty();
+        await Assert.That(dictionary).Count().IsPositive();
+    }
+
+    [Test]
+    public async Task Dictionary_Count_Fails_With_Count_Message()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["a"] = 1L
+        };
+
+        var exception = await Assert.ThrowsAsync<TUnit.Assertions.Exceptions.AssertionException>(
+            async () => await Assert.That(dictionary).Count().IsEqualTo(5));
+
+        await Assert.That(exception.Message).Contains("count");
+    }
+
+    [Test]
+    public async Task Dictionary_ContainsKey_And_Count()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L,
+            ["Other"] = 1L
+        };
+
+        await Assert.That(dictionary)
+            .ContainsKey("Key").And.Count().IsEqualTo(2);
+    }
+
+    [Test]
+    public async Task Dictionary_HasSingleItem_Preserves_Dictionary_Continuation()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(dictionary)
+            .HasSingleItem().And.ContainsKey("Key").And.Value.IsEqualTo(1234L);
+    }
+
+    [Test]
+    public async Task Dictionary_Size_Methods_Preserve_Dictionary_Continuation()
+    {
+        var dictionary = new Dictionary<string, long>
+        {
+            ["a"] = 1L,
+            ["b"] = 2L,
+            ["c"] = 3L
+        };
+
+        await Assert.That(dictionary).HasAtLeast(2).And.ContainsKey("a");
+        await Assert.That(dictionary).HasAtMost(5).And.ContainsKey("b");
+        await Assert.That(dictionary).HasCountBetween(1, 5).And.ContainsKey("c");
+    }
+
+    [Test]
+    public async Task IDictionary_Count_And_HasSingleItem_Preserve_Continuation()
+    {
+        IDictionary<string, long> single = new Dictionary<string, long>
+        {
+            ["Key"] = 1234L
+        };
+
+        await Assert.That(single)
+            .HasSingleItem().And.ContainsKey("Key").And.Value.IsEqualTo(1234L);
+
+        IDictionary<string, long> many = new Dictionary<string, long>
+        {
+            ["a"] = 1L,
+            ["b"] = 2L
+        };
+
+        await Assert.That(many)
+            .Count().IsEqualTo(2).And.ContainsKey("a");
+    }
+
+    private sealed record Holder(long Inner);
 }
diff --git a/TUnit.Assertions/Conditions/DictionaryAssertions.cs b/TUnit.Assertions/Conditions/DictionaryAssertions.cs
index 7d8a883fe2..1b850c454b 100644
--- a/TUnit.Assertions/Conditions/DictionaryAssertions.cs
+++ b/TUnit.Assertions/Conditions/DictionaryAssertions.cs
@@ -39,6 +39,22 @@ public DictionaryContainsKeyAssertion<TDictionary, TKey, TValue> Using(Func<TKey
             Context, _expectedKey, new FuncEqualityComparer<TKey>(equalityPredicate));
     }
 
+    /// <summary>
+    /// Returns an And continuation that, in addition to the usual dictionary chaining, exposes
+    /// <see cref="DictionaryContainsKeyAndContinuation{TDictionary,TKey,TValue}.Value"/> to drill
+    /// into the value stored at the asserted key.
+    /// Example: <c>await Assert.That(dict).ContainsKey("key").And.Value.IsEqualTo(123);</c>
+    /// </summary>
+    public new DictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> And
+    {
+        get
+        {
+            ThrowIfMixingCombiner<Chaining.OrAssertion<TDictionary>>();
+            return new DictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue>(
+                Context, InternalWrappedExecution ?? this, _expectedKey, _comparer);
+        }
+    }
+
     protected override Task<AssertionResult> CheckAsync(EvaluationMetadata<TDictionary> metadata)
     {
         var value = metadata.Value;
diff --git a/TUnit.Assertions/Conditions/DictionaryCollectionContinuations.cs b/TUnit.Assertions/Conditions/DictionaryCollectionContinuations.cs
new file mode 100644
index 0000000000..d30d20b188
--- /dev/null
+++ b/TUnit.Assertions/Conditions/DictionaryCollectionContinuations.cs
@@ -0,0 +1,158 @@
+using System.Runtime.CompilerServices;
+using TUnit.Assertions.Core;
+
+namespace TUnit.Assertions.Conditions;
+
+/// <summary>
+/// Dictionary-typed assertion that delegates its check to an inner collection assertion while
+/// preserving dictionary-specific chaining (ContainsKey, Value, ...).
+/// The inner assertion is built on a detached context so its construction does not consume the
+/// And/Or pending link that must stay wired to this (dictionary-typed) assertion.
+/// </summary>
+internal sealed class DictionaryDelegatingAssertion<TDictionary, TKey, TValue>
+    : Sources.DictionaryAssertionBase<TDictionary, TKey, TValue>
+    where TDictionary : IReadOnlyDictionary<TKey, TValue>
+    where TKey : notnull
+{
+    private readonly Assertion<TDictionary> _inner;
+
+    internal DictionaryDelegatingAssertion(AssertionContext<TDictionary> context, Assertion<TDictionary> inner)
+        : base(context)
+    {
+        _inner = inner;
+    }
+
+    protected override Task<AssertionResult> CheckAsync(EvaluationMetadata<TDictionary> metadata)
+        => _inner.InternalCheckAsync(metadata);
+
+    protected override string GetExpectation() => _inner.InternalGetExpectation();
+}
+
+/// <summary>
+/// Mutable-dictionary twin of <see cref="DictionaryDelegatingAssertion{TDictionary,TKey,TValue}"/>.
+/// </summary>
+internal sealed class MutableDictionaryDelegatingAssertion<TDictionary, TKey, TValue>
+    : Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue>
+    where TDictionary : IDictionary<TKey, TValue>
+    where TKey : notnull
+{
+    private readonly Assertion<TDictionary> _inner;
+
+    internal MutableDictionaryDelegatingAssertion(AssertionContext<TDictionary> context, Assertion<TDictionary> inner)
+        : base(context)
+    {
+        _inner = inner;
+    }
+
+    protected override Task<AssertionResult> CheckAsync(EvaluationMetadata<TDictionary> metadata)
+        => _inner.InternalCheckAsync(metadata);
+
+    protected override string GetExpectation() => _inner.InternalGetExpectation();
+}
+
+/// <summary>
+/// Count source for read-only dictionaries that preserves dictionary-specific chaining.
+/// Mirrors <see cref="CollectionCountSource{TCollection,TItem}"/> but returns dictionary-typed
+/// assertions so chains like <c>Count().IsEqualTo(2).And.ContainsKey("k")</c> keep working.
+/// NOTE: keep the method set in sync with <see cref="MutableDictionaryCountSource{TDictionary,TKey,TValue}"/>
+/// (separate classes are required by the IReadOnlyDictionary vs IDictionary constraint).
+/// </summary>
+public sealed class DictionaryCountSource<TDictionary, TKey, TValue>
+    where TDictionary : IReadOnlyDictionary<TKey, TValue>
+    where TKey : notnull
+{
+    private readonly AssertionContext<TDictionary> _context;
+
+    internal DictionaryCountSource(AssertionContext<TDictionary> context) => _context = context;
+
+    private Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> Compare(
+        int expected, CountComparison comparison, string expressionFragment)
+    {
+        _context.ExpressionBuilder.Append(expressionFragment);
+        var inner = new CollectionCountEqualsAssertion<TDictionary, KeyValuePair<TKey, TValue>>(
+            _context.CreateDetached(), null, expected, comparison);
+        return new DictionaryDelegatingAssertion<TDictionary, TKey, TValue>(_context, inner);
+    }
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.Equal, $".IsEqualTo({expression})");
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsNotEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.NotEqual, $".IsNotEqualTo({expression})");
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsGreaterThan(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.GreaterThan, $".IsGreaterThan({expression})");
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.GreaterThanOrEqual, $".IsGreaterThanOrEqualTo({expression})");
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsLessThan(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.LessThan, $".IsLessThan({expression})");
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsLessThanOrEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.LessThanOrEqual, $".IsLessThanOrEqualTo({expression})");
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsZero()
+        => Compare(0, CountComparison.Equal, ".IsZero()");
+
+    public Sources.DictionaryAssertionBase<TDictionary, TKey, TValue> IsPositive()
+        => Compare(0, CountComparison.GreaterThan, ".IsPositive()");
+}
+
+/// <summary>
+/// Mutable-dictionary twin of <see cref="DictionaryCountSource{TDictionary,TKey,TValue}"/>.
+/// NOTE: keep the method set in sync with <see cref="DictionaryCountSource{TDictionary,TKey,TValue}"/>.
+/// </summary>
+public sealed class MutableDictionaryCountSource<TDictionary, TKey, TValue>
+    where TDictionary : IDictionary<TKey, TValue>
+    where TKey : notnull
+{
+    private readonly AssertionContext<TDictionary> _context;
+
+    internal MutableDictionaryCountSource(AssertionContext<TDictionary> context) => _context = context;
+
+    private Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> Compare(
+        int expected, CountComparison comparison, string expressionFragment)
+    {
+        _context.ExpressionBuilder.Append(expressionFragment);
+        var inner = new CollectionCountEqualsAssertion<TDictionary, KeyValuePair<TKey, TValue>>(
+            _context.CreateDetached(), null, expected, comparison);
+        return new MutableDictionaryDelegatingAssertion<TDictionary, TKey, TValue>(_context, inner);
+    }
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.Equal, $".IsEqualTo({expression})");
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsNotEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.NotEqual, $".IsNotEqualTo({expression})");
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsGreaterThan(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.GreaterThan, $".IsGreaterThan({expression})");
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.GreaterThanOrEqual, $".IsGreaterThanOrEqualTo({expression})");
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsLessThan(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.LessThan, $".IsLessThan({expression})");
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsLessThanOrEqualTo(
+        int expected, [CallerArgumentExpression(nameof(expected))] string? expression = null)
+        => Compare(expected, CountComparison.LessThanOrEqual, $".IsLessThanOrEqualTo({expression})");
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsZero()
+        => Compare(0, CountComparison.Equal, ".IsZero()");
+
+    public Sources.MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsPositive()
+        => Compare(0, CountComparison.GreaterThan, ".IsPositive()");
+}
diff --git a/TUnit.Assertions/Conditions/DictionaryValueSource.cs b/TUnit.Assertions/Conditions/DictionaryValueSource.cs
new file mode 100644
index 0000000000..8bee287439
--- /dev/null
+++ b/TUnit.Assertions/Conditions/DictionaryValueSource.cs
@@ -0,0 +1,153 @@
+using TUnit.Assertions.Core;
+using TUnit.Assertions.Sources;
+
+namespace TUnit.Assertions.Conditions;
+
+/// <summary>
+/// Assertion source for the value stored at a dictionary key.
+/// Exposes the full value-assertion surface (IsEqualTo, IsNotNull, Member, Satisfies, …)
+/// by virtue of being an <see cref="IAssertionSource{TValue}"/>.
+/// Created via <c>ContainsKey(key).And.Value</c>.
+/// </summary>
+/// <typeparam name="TValue">The dictionary value type.</typeparam>
+public sealed class DictionaryValueSource<TValue> : ValueAssertion<TValue>
+{
+    internal DictionaryValueSource(AssertionContext<TValue> context)
+        : base(context)
+    {
+    }
+}
+
+/// <summary>
+/// Shared value lookup for the <c>ContainsKey(key).And.Value</c> drill-in, used by both the read-only
+/// and mutable continuations (which cannot share a base due to the IReadOnlyDictionary vs IDictionary
+/// constraint). Existence/null is already validated by the ContainsKey pre-work, so a miss returns
+/// default rather than throwing — letting the pre-work's clean failure surface.
+/// </summary>
+internal static class DictionaryValueLookup
+{
+    internal static TValue? Extract<TKey, TValue>(
+        IEnumerable<KeyValuePair<TKey, TValue>>? dictionary, TKey key, IEqualityComparer<TKey>? comparer)
+        where TKey : notnull
+    {
+        if (dictionary is null)
+        {
+            return default;
+        }
+
+        if (comparer is not null)
+        {
+            foreach (var pair in dictionary)
+            {
+                if (comparer.Equals(pair.Key, key))
+                {
+                    return pair.Value;
+                }
+            }
+
+            return default;
+        }
+
+        // No custom comparer: use the dictionary's own TryGetValue (O(1), and it honours the
+        // dictionary's internal comparer — which a default-equality scan would not).
+        if (dictionary is IReadOnlyDictionary<TKey, TValue> readOnly)
+        {
+            return readOnly.TryGetValue(key, out var value) ? value : default;
+        }
+
+        if (dictionary is IDictionary<TKey, TValue> mutable)
+        {
+            return mutable.TryGetValue(key, out var value) ? value : default;
+        }
+
+        foreach (var pair in dictionary)
+        {
+            if (EqualityComparer<TKey>.Default.Equals(pair.Key, key))
+            {
+                return pair.Value;
+            }
+        }
+
+        return default;
+    }
+}
+
+/// <summary>
+/// And continuation returned by <c>ContainsKey(key).And</c> on a read-only dictionary.
+/// Behaves like the standard <see cref="DictionaryAndContinuation{TDictionary,TKey,TValue}"/>
+/// but additionally carries the asserted key so the entry's value can be drilled into via
+/// <see cref="Value"/>.
+/// Example: <c>await Assert.That(dict).ContainsKey("key").And.Value.IsEqualTo(123);</c>
+/// </summary>
+public sealed class DictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue>
+    : DictionaryAndContinuation<TDictionary, TKey, TValue>
+    where TDictionary : IReadOnlyDictionary<TKey, TValue>
+    where TKey : notnull
+{
+    private readonly TKey _expectedKey;
+    private readonly IEqualityComparer<TKey>? _comparer;
+
+    internal DictionaryContainsKeyAndContinuation(
+        AssertionContext<TDictionary> context,
+        Assertion<TDictionary> previousAssertion,
+        TKey expectedKey,
+        IEqualityComparer<TKey>? comparer)
+        : base(context, previousAssertion)
+    {
+        _expectedKey = expectedKey;
+        _comparer = comparer;
+    }
+
+    /// <summary>
+    /// Drills into the value stored at the key asserted by the preceding <c>ContainsKey</c>,
+    /// allowing assertions to be made directly against the value.
+    /// The <c>ContainsKey</c> check runs first (as pre-work transferred by the <c>.And</c> link),
+    /// so a missing key fails with the standard "to contain key" message before the value is read.
+    /// </summary>
+    public DictionaryValueSource<TValue> Value
+    {
+        get
+        {
+            Context.ExpressionBuilder.Append(".Value");
+            var valueContext = Context.Map<TValue>(
+                dictionary => DictionaryValueLookup.Extract<TKey, TValue>(dictionary, _expectedKey, _comparer));
+            return new DictionaryValueSource<TValue>(valueContext);
+        }
+    }
+}
+
+/// <summary>
+/// And continuation returned by <c>ContainsKey(key).And</c> on a mutable dictionary (IDictionary).
+/// Mutable twin of <see cref="DictionaryContainsKeyAndContinuation{TDictionary,TKey,TValue}"/>.
+/// </summary>
+public sealed class MutableDictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue>
+    : MutableDictionaryAndContinuation<TDictionary, TKey, TValue>
+    where TDictionary : IDictionary<TKey, TValue>
+    where TKey : notnull
+{
+    private readonly TKey _expectedKey;
+    private readonly IEqualityComparer<TKey>? _comparer;
+
+    internal MutableDictionaryContainsKeyAndContinuation(
+        AssertionContext<TDictionary> context,
+        Assertion<TDictionary> previousAssertion,
+        TKey expectedKey,
+        IEqualityComparer<TKey>? comparer)
+        : base(context, previousAssertion)
+    {
+        _expectedKey = expectedKey;
+        _comparer = comparer;
+    }
+
+    /// <inheritdoc cref="DictionaryContainsKeyAndContinuation{TDictionary,TKey,TValue}.Value"/>
+    public DictionaryValueSource<TValue> Value
+    {
+        get
+        {
+            Context.ExpressionBuilder.Append(".Value");
+            var valueContext = Context.Map<TValue>(
+                dictionary => DictionaryValueLookup.Extract<TKey, TValue>(dictionary, _expectedKey, _comparer));
+            return new DictionaryValueSource<TValue>(valueContext);
+        }
+    }
+}
diff --git a/TUnit.Assertions/Conditions/MutableDictionaryAssertions.cs b/TUnit.Assertions/Conditions/MutableDictionaryAssertions.cs
index 1550aa5d30..95c3270106 100644
--- a/TUnit.Assertions/Conditions/MutableDictionaryAssertions.cs
+++ b/TUnit.Assertions/Conditions/MutableDictionaryAssertions.cs
@@ -33,6 +33,22 @@ public MutableDictionaryContainsKeyAssertion<TDictionary, TKey, TValue> Using(Fu
             Context, _expectedKey, new FuncEqualityComparer<TKey>(equalityPredicate));
     }
 
+    /// <summary>
+    /// Returns an And continuation that, in addition to the usual dictionary chaining, exposes
+    /// <see cref="MutableDictionaryContainsKeyAndContinuation{TDictionary,TKey,TValue}.Value"/> to
+    /// drill into the value stored at the asserted key.
+    /// Example: <c>await Assert.That(dict).ContainsKey("key").And.Value.IsEqualTo(123);</c>
+    /// </summary>
+    public new MutableDictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> And
+    {
+        get
+        {
+            ThrowIfMixingCombiner<Chaining.OrAssertion<TDictionary>>();
+            return new MutableDictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue>(
+                Context, InternalWrappedExecution ?? this, _expectedKey, _comparer);
+        }
+    }
+
     protected override string GetExpectation() => $"to contain key {_expectedKey}";
 
     protected override Task<AssertionResult> CheckAsync(EvaluationMetadata<TDictionary> metadata)
diff --git a/TUnit.Assertions/Core/Assertion.cs b/TUnit.Assertions/Core/Assertion.cs
index 68f58ea0c6..4374a8f57b 100644
--- a/TUnit.Assertions/Core/Assertion.cs
+++ b/TUnit.Assertions/Core/Assertion.cs
@@ -82,6 +82,13 @@ protected virtual Task<AssertionResult> CheckAsync(EvaluationMetadata<TValue> me
     /// </summary>
     internal string InternalGetExpectation() => GetExpectation();
 
+    /// <summary>
+    /// Internal accessor for CheckAsync(), allowing one assertion to delegate its check to another
+    /// (e.g. dictionary assertions that reuse the collection assertion logic while preserving
+    /// dictionary-specific chaining).
+    /// </summary>
+    internal Task<AssertionResult> InternalCheckAsync(EvaluationMetadata<TValue> metadata) => CheckAsync(metadata);
+
     /// <summary>
     /// Internal accessor for the because message, used by And/OrAssertion to build combined error messages.
     /// </summary>
diff --git a/TUnit.Assertions/Core/AssertionContext.cs b/TUnit.Assertions/Core/AssertionContext.cs
index c70a11c514..12a5147006 100644
--- a/TUnit.Assertions/Core/AssertionContext.cs
+++ b/TUnit.Assertions/Core/AssertionContext.cs
@@ -89,6 +89,13 @@ public AssertionContext<TNew> Map<TNew>(Func<TValue?, Task<TNew?>> asyncMapper)
         return Map(evalContext => evalContext.Map(asyncMapper));
     }
 
+    /// <summary>
+    /// Creates a detached context that shares this context's evaluation (so it sees the same value)
+    /// but has its own expression builder and no pending link. Used to construct an inner assertion
+    /// whose construction must NOT consume this context's And/Or pending link.
+    /// </summary>
+    internal AssertionContext<TValue> CreateDetached() => new(Evaluation, new StringBuilder());
+
     public AssertionContext<TException> MapException<TException>() where TException : Exception
     {
         return new AssertionContext<TException>(
diff --git a/TUnit.Assertions/Sources/DictionaryAssertionBase.cs b/TUnit.Assertions/Sources/DictionaryAssertionBase.cs
index aea85145de..d7b64d6a1d 100644
--- a/TUnit.Assertions/Sources/DictionaryAssertionBase.cs
+++ b/TUnit.Assertions/Sources/DictionaryAssertionBase.cs
@@ -58,6 +58,99 @@ private protected DictionaryAssertionBase(
         return new DictionaryNullAssertion<TDictionary, TKey, TValue>(Context, expectNull: false);
     }
 
+    // The collection methods below (IsEmpty, Count, HasSingleItem, size checks) are hidden with
+    // `public new` so they return a dictionary-typed assertion instead of the collection-typed one
+    // from CollectionAssertionBase, keeping dictionary chaining (.And.ContainsKey, etc.) available.
+    // Each reuses the existing collection assertion's check logic via a delegating wrapper; the inner
+    // assertion is built on Context.CreateDetached() so its construction doesn't consume our pending link.
+
+    private DictionaryAssertionBase<TDictionary, TKey, TValue> Delegate(Assertion<TDictionary> inner)
+        => new DictionaryDelegatingAssertion<TDictionary, TKey, TValue>(Context, inner);
+
+    /// <summary>
+    /// Asserts that the dictionary is empty while preserving dictionary-specific chaining.
+    /// </summary>
+    public new DictionaryAssertionBase<TDictionary, TKey, TValue> IsEmpty()
+    {
+        Context.ExpressionBuilder.Append(".IsEmpty()");
+        return Delegate(new CollectionIsEmptyAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached()));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary is not empty while preserving dictionary-specific chaining.
+    /// </summary>
+    public new DictionaryAssertionBase<TDictionary, TKey, TValue> IsNotEmpty()
+    {
+        Context.ExpressionBuilder.Append(".IsNotEmpty()");
+        return Delegate(new CollectionIsNotEmptyAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached()));
+    }
+
+    /// <summary>
+    /// Gets the entry count for numeric assertions while preserving dictionary-specific chaining.
+    /// Example: await Assert.That(dict).Count().IsEqualTo(2).And.ContainsKey("key");
+    /// </summary>
+    public new DictionaryCountSource<TDictionary, TKey, TValue> Count()
+    {
+        Context.ExpressionBuilder.Append(".Count()");
+        return new DictionaryCountSource<TDictionary, TKey, TValue>(Context);
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary contains exactly one entry while preserving dictionary-specific chaining.
+    /// </summary>
+    public new DictionaryAssertionBase<TDictionary, TKey, TValue> HasSingleItem()
+    {
+        Context.ExpressionBuilder.Append(".HasSingleItem()");
+        return Delegate(new HasSingleItemAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached()));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary contains exactly one entry matching the predicate while preserving chaining.
+    /// </summary>
+    public new DictionaryAssertionBase<TDictionary, TKey, TValue> HasSingleItem(
+        Func<KeyValuePair<TKey, TValue>, bool> predicate,
+        [CallerArgumentExpression(nameof(predicate))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasSingleItem({expression})");
+        return Delegate(new HasSingleItemPredicateAssertion<TDictionary, KeyValuePair<TKey, TValue>>(
+            Context.CreateDetached(), predicate, expression ?? "predicate"));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary has at least the specified number of entries while preserving chaining.
+    /// </summary>
+    public new DictionaryAssertionBase<TDictionary, TKey, TValue> HasAtLeast(
+        int minCount,
+        [CallerArgumentExpression(nameof(minCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasAtLeast({expression})");
+        return Delegate(new CollectionHasAtLeastAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached(), minCount));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary has at most the specified number of entries while preserving chaining.
+    /// </summary>
+    public new DictionaryAssertionBase<TDictionary, TKey, TValue> HasAtMost(
+        int maxCount,
+        [CallerArgumentExpression(nameof(maxCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasAtMost({expression})");
+        return Delegate(new CollectionHasAtMostAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached(), maxCount));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary entry count is between min and max (inclusive) while preserving chaining.
+    /// </summary>
+    public new DictionaryAssertionBase<TDictionary, TKey, TValue> HasCountBetween(
+        int min,
+        int max,
+        [CallerArgumentExpression(nameof(min))] string? minExpression = null,
+        [CallerArgumentExpression(nameof(max))] string? maxExpression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasCountBetween({minExpression}, {maxExpression})");
+        return Delegate(new CollectionHasCountBetweenAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached(), min, max));
+    }
+
     /// <summary>
     /// Asserts that the dictionary contains the specified key.
     /// This instance method enables calling ContainsKey with proper type inference.
diff --git a/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs b/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs
index c94d8a73ba..8b6bb75922 100644
--- a/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs
+++ b/TUnit.Assertions/Sources/MutableDictionaryAssertionBase.cs
@@ -56,6 +56,97 @@ private protected MutableDictionaryAssertionBase(
         return new MutableDictionaryNullAssertion<TDictionary, TKey, TValue>(Context, expectNull: false);
     }
 
+    // See DictionaryAssertionBase for the rationale: these `public new` collection methods return a
+    // mutable-dictionary-typed assertion (preserving .And.ContainsKey, etc.) and reuse the existing
+    // collection check logic via a delegating wrapper built on a detached context.
+
+    private MutableDictionaryAssertionBase<TDictionary, TKey, TValue> Delegate(Assertion<TDictionary> inner)
+        => new MutableDictionaryDelegatingAssertion<TDictionary, TKey, TValue>(Context, inner);
+
+    /// <summary>
+    /// Asserts that the dictionary is empty while preserving mutable-dictionary-specific chaining.
+    /// </summary>
+    public new MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsEmpty()
+    {
+        Context.ExpressionBuilder.Append(".IsEmpty()");
+        return Delegate(new CollectionIsEmptyAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached()));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary is not empty while preserving mutable-dictionary-specific chaining.
+    /// </summary>
+    public new MutableDictionaryAssertionBase<TDictionary, TKey, TValue> IsNotEmpty()
+    {
+        Context.ExpressionBuilder.Append(".IsNotEmpty()");
+        return Delegate(new CollectionIsNotEmptyAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached()));
+    }
+
+    /// <summary>
+    /// Gets the entry count for numeric assertions while preserving mutable-dictionary-specific chaining.
+    /// Example: await Assert.That(dict).Count().IsEqualTo(2).And.ContainsKey("key");
+    /// </summary>
+    public new MutableDictionaryCountSource<TDictionary, TKey, TValue> Count()
+    {
+        Context.ExpressionBuilder.Append(".Count()");
+        return new MutableDictionaryCountSource<TDictionary, TKey, TValue>(Context);
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary contains exactly one entry while preserving mutable-dictionary chaining.
+    /// </summary>
+    public new MutableDictionaryAssertionBase<TDictionary, TKey, TValue> HasSingleItem()
+    {
+        Context.ExpressionBuilder.Append(".HasSingleItem()");
+        return Delegate(new HasSingleItemAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached()));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary contains exactly one entry matching the predicate while preserving chaining.
+    /// </summary>
+    public new MutableDictionaryAssertionBase<TDictionary, TKey, TValue> HasSingleItem(
+        Func<KeyValuePair<TKey, TValue>, bool> predicate,
+        [CallerArgumentExpression(nameof(predicate))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasSingleItem({expression})");
+        return Delegate(new HasSingleItemPredicateAssertion<TDictionary, KeyValuePair<TKey, TValue>>(
+            Context.CreateDetached(), predicate, expression ?? "predicate"));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary has at least the specified number of entries while preserving chaining.
+    /// </summary>
+    public new MutableDictionaryAssertionBase<TDictionary, TKey, TValue> HasAtLeast(
+        int minCount,
+        [CallerArgumentExpression(nameof(minCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasAtLeast({expression})");
+        return Delegate(new CollectionHasAtLeastAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached(), minCount));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary has at most the specified number of entries while preserving chaining.
+    /// </summary>
+    public new MutableDictionaryAssertionBase<TDictionary, TKey, TValue> HasAtMost(
+        int maxCount,
+        [CallerArgumentExpression(nameof(maxCount))] string? expression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasAtMost({expression})");
+        return Delegate(new CollectionHasAtMostAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached(), maxCount));
+    }
+
+    /// <summary>
+    /// Asserts that the dictionary entry count is between min and max (inclusive) while preserving chaining.
+    /// </summary>
+    public new MutableDictionaryAssertionBase<TDictionary, TKey, TValue> HasCountBetween(
+        int min,
+        int max,
+        [CallerArgumentExpression(nameof(min))] string? minExpression = null,
+        [CallerArgumentExpression(nameof(max))] string? maxExpression = null)
+    {
+        Context.ExpressionBuilder.Append($".HasCountBetween({minExpression}, {maxExpression})");
+        return Delegate(new CollectionHasCountBetweenAssertion<TDictionary, KeyValuePair<TKey, TValue>>(Context.CreateDetached(), min, max));
+    }
+
     /// <summary>
     /// Asserts that the dictionary contains the specified key.
     /// Example: await Assert.That(dictionary).ContainsKey("key1");
diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt
index 25a10902ac..c3c67b371c 100644
--- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt
+++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet10_0.verified.txt
@@ -1052,11 +1052,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class DictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public DictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -1078,6 +1085,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class DictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -1097,6 +1117,7 @@ namespace .Conditions
     public class DictionaryMemberAssertionAdapter<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull { }
+    public sealed class DictionaryValueSource<TValue> : .<TValue> { }
     [.("HasFiles")]
     public class DirectoryHasFilesAssertion : .<.DirectoryInfo>
     {
@@ -1656,11 +1677,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class MutableDictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public MutableDictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -1682,6 +1710,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class MutableDictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -6296,9 +6337,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
@@ -6415,9 +6464,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt
index d26f0e59c7..e8d5b32487 100644
--- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt
+++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet8_0.verified.txt
@@ -1035,11 +1035,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class DictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public DictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -1061,6 +1068,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class DictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -1080,6 +1100,7 @@ namespace .Conditions
     public class DictionaryMemberAssertionAdapter<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull { }
+    public sealed class DictionaryValueSource<TValue> : .<TValue> { }
     [.("HasFiles")]
     public class DirectoryHasFilesAssertion : .<.DirectoryInfo>
     {
@@ -1639,11 +1660,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class MutableDictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public MutableDictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -1665,6 +1693,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class MutableDictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -6218,9 +6259,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
@@ -6337,9 +6386,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt
index 6906a4914f..81abde7ca6 100644
--- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt
+++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.DotNet9_0.verified.txt
@@ -1052,11 +1052,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class DictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public DictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -1078,6 +1085,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class DictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -1097,6 +1117,7 @@ namespace .Conditions
     public class DictionaryMemberAssertionAdapter<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull { }
+    public sealed class DictionaryValueSource<TValue> : .<TValue> { }
     [.("HasFiles")]
     public class DirectoryHasFilesAssertion : .<.DirectoryInfo>
     {
@@ -1656,11 +1677,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class MutableDictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public MutableDictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -1682,6 +1710,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class MutableDictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -6296,9 +6337,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
@@ -6415,9 +6464,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
diff --git a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt
index 171550131d..ea85ff13c7 100644
--- a/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt
+++ b/TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.Net4_7.verified.txt
@@ -880,11 +880,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class DictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public DictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -906,6 +913,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class DictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class DictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -925,6 +945,7 @@ namespace .Conditions
     public class DictionaryMemberAssertionAdapter<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull { }
+    public sealed class DictionaryValueSource<TValue> : .<TValue> { }
     [.("HasFiles")]
     public class DirectoryHasFilesAssertion : .<.DirectoryInfo>
     {
@@ -1469,11 +1490,18 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryContainsKeyAndContinuation<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TValue> Value { get; }
+    }
     public class MutableDictionaryContainsKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
     {
         public MutableDictionaryContainsKeyAssertion(.<TDictionary> context, TKey expectedKey, .<TKey>? comparer = null) { }
+        public new .<TDictionary, TKey, TValue> And { get; }
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
         public .<TDictionary, TKey, TValue> Using(.<TKey> comparer) { }
@@ -1495,6 +1523,19 @@ namespace .Conditions
         protected override .<.> CheckAsync(.<TDictionary> metadata) { }
         protected override string GetExpectation() { }
     }
+    public sealed class MutableDictionaryCountSource<TDictionary, TKey, TValue>
+        where TDictionary : .<TKey, TValue>
+        where TKey :  notnull
+    {
+        public .<TDictionary, TKey, TValue> IsEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsGreaterThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThan(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsLessThanOrEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsNotEqualTo(int expected, [.("expected")] string? expression = null) { }
+        public .<TDictionary, TKey, TValue> IsPositive() { }
+        public .<TDictionary, TKey, TValue> IsZero() { }
+    }
     public class MutableDictionaryDoesNotContainKeyAssertion<TDictionary, TKey, TValue> : .<TDictionary, TKey, TValue>
         where TDictionary : .<TKey, TValue>
         where TKey :  notnull
@@ -5412,9 +5453,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
@@ -5483,9 +5532,17 @@ namespace .Sources
         public .<TDictionary, TKey, TValue> ContainsKey(TKey expectedKey, .<TKey>? comparer, [.("expectedKey")] string? keyExpression = null, [.("comparer")] string? comparerExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsKeyWithValue(TKey expectedKey, TValue expectedValue, [.("expectedKey")] string? keyExpression = null, [.("expectedValue")] string? valueExpression = null) { }
         public .<TDictionary, TKey, TValue> ContainsValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> Count() { }
         public .<TDictionary, TKey, TValue> DoesNotContainKey(TKey expectedKey, [.("expectedKey")] string? expression = null) { }
         public .<TDictionary, TKey, TValue> DoesNotContainValue(TValue expectedValue, [.("expectedValue")] string? expression = null) { }
         protected override string GetExpectation() { }
+        public new .<TDictionary, TKey, TValue> HasAtLeast(int minCount, [.("minCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasAtMost(int maxCount, [.("maxCount")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> HasCountBetween(int min, int max, [.("min")] string? minExpression = null, [.("max")] string? maxExpression = null) { }
+        public new .<TDictionary, TKey, TValue> HasSingleItem() { }
+        public .<TDictionary, TKey, TValue> HasSingleItem(<.<TKey, TValue>, bool> predicate, [.("predicate")] string? expression = null) { }
+        public new .<TDictionary, TKey, TValue> IsEmpty() { }
+        public new .<TDictionary, TKey, TValue> IsNotEmpty() { }
         public new .<TDictionary, TKey, TValue> IsNotNull() { }
         public new .<TDictionary, TKey, TValue> IsNull() { }
     }
