Benchmarks
These benchmarks compare the happy-path overhead of aweXpect.Reflection (passing assertions, the dominant case in a healthy test suite) against the equivalent FluentAssertions calls.
- Suite:
HappyCaseBenchmarksdriven by BenchmarkDotNet. - Job:
MediumRunwith the in-process toolchain. - Runner:
ubuntu-latestGitHub Actions agent, refreshed on every push tomain. - FluentAssertions has no expectations on nullability or dependencies. For these, its benchmark does what a FluentAssertions user writes instead, which does not cover everything aweXpect.Reflection verifies.
- Each tab shows the latest measured time and allocated memory; bars are scaled within the row so length corresponds to magnitude. Lower is better.
- Attribute
- Not static
- Nullability
- Sealed types
- Async methods
- Dependencies
Verifies that a type is decorated with an attribute.
await That(_entityType).Has<EntityAttribute>();
_entityType.Should().BeDecoratedWith<EntityAttribute>();
Verifies that a type is not static.
await That(_type).IsNotStatic();
_type.Should().NotBeStatic();
Verifies that all members of a type are non-nullable.
FluentAssertions reads the nullability of the declared properties with a NullabilityInfoContext and verifies that none of them is nullable. As the type only has auto-properties, this covers the same members.
await That(_trackType).OnlyHasNonNullableMembers();
NullabilityInfoContext context = new();
_trackType.GetProperties(DeclaredMembers).Select(property => context.Create(property).ReadState)
.Should().NotContain(NullabilityState.Nullable);
Verifies the convention that all types in a namespace of an assembly are sealed, as an architecture test does.
await That(In.AssemblyContaining<HappyCaseBenchmarks>().Types().WhichAreWithinNamespace(_namespace))
.AreSealed();
AllTypes.From(_assembly).ThatAreUnderNamespace(_namespace).Should().BeSealed();
Verifies the convention that all methods returning a Task in a namespace of an assembly are async, as an architecture test does.
await That(In.AssemblyContaining<HappyCaseBenchmarks>().Types().WhichAreWithinNamespace(_namespace)
.Methods().WhichReturn<Task>())
.AreAsync();
AllTypes.From(_assembly).ThatAreUnderNamespace(_namespace).Methods().ThatReturn<Task>().Should().BeAsync();
Verifies the architecture rule that no type in a namespace of an assembly depends on the System.Net namespace.
FluentAssertions collects the types of the fields, properties, method return values and method parameters and verifies that none of them is in the namespace. This is not equivalent: it ignores e.g. base types, interfaces, generic arguments and attributes.
await That(In.AssemblyContaining<HappyCaseBenchmarks>().Types().WhichAreWithinNamespace(_namespace))
.DoNotDependOn("System.Net");
AllTypes.From(_assembly).ThatAreUnderNamespace(_namespace).SelectMany(GetSignatureTypes).Should()
.NotContain(type => type.Namespace != null &&
(type.Namespace == "System.Net" || type.Namespace.StartsWith("System.Net.")));