[tests] show only diff in test failures when comparing long multi-line strings#3205
Merged
Conversation
This comment has been minimized.
This comment has been minimized.
lucaspimentel
marked this pull request as ready for review
September 12, 2022 20:43
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
andrewlock
approved these changes
Sep 13, 2022
This comment has been minimized.
This comment has been minimized.
pierotibou
approved these changes
Sep 14, 2022
lucaspimentel
force-pushed
the
lpimentel/string-diffs-in-tests
branch
from
September 14, 2022 17:02
9f1f978 to
e8af5d6
Compare
Member
Code Coverage Report 📊✔️ Merging #3205 into master will not change line coverage
View the full report for further details: Datadog.Trace Breakdown ✔️
The following classes have significant coverage changes.
View the full reports for further details: |
Member
Benchmarks Report 🐌Benchmarks for #3205 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AppSecBodyBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.ElasticsearchBenchmark - Slower
|
| Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearch‑netcoreapp3.1 | 1.187 | 1,565.35 | 1,858.41 | several? |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | CallElasticsearch |
net472 | 2.57μs | 1.41ns | 5.47ns | 0.183 | 0 | 0 | 1.16 KB |
| master | CallElasticsearch |
netcoreapp3.1 | 1.57μs | 0.685ns | 2.65ns | 0.0149 | 0 | 0 | 1.1 KB |
| master | CallElasticsearchAsync |
net472 | 2.77μs | 1.32ns | 5.11ns | 0.204 | 0 | 0 | 1.29 KB |
| master | CallElasticsearchAsync |
netcoreapp3.1 | 1.61μs | 0.577ns | 2.16ns | 0.0162 | 0 | 0 | 1.22 KB |
| #3205 | CallElasticsearch |
net472 | 2.9μs | 16.1ns | 102ns | 0.182 | 0 | 0 | 1.16 KB |
| #3205 | CallElasticsearch |
netcoreapp3.1 | 1.85μs | 18.5ns | 184ns | 0.0146 | 0.000861 | 0 | 1.1 KB |
| #3205 | CallElasticsearchAsync |
net472 | 2.95μs | 16.5ns | 103ns | 0.205 | 0 | 0 | 1.29 KB |
| #3205 | CallElasticsearchAsync |
netcoreapp3.1 | 1.62μs | 1.05ns | 4.06ns | 0.0164 | 0 | 0 | 1.22 KB |
Benchmarks.Trace.GraphQLBenchmark - Slower ⚠️ Same allocations ✔️
Slower ⚠️ in #3205
Benchmark
diff/base
Base Median (ns)
Diff Median (ns)
Modality
Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync‑netcoreapp3.1
1.240
1,702.70
2,112.13
| Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync‑netcoreapp3.1 | 1.240 | 1,702.70 | 2,112.13 |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | ExecuteAsync |
net472 | 2.82μs | 8.46ns | 32.8ns | 0.225 | 0 | 0 | 1.42 KB |
| master | ExecuteAsync |
netcoreapp3.1 | 1.7μs | 0.893ns | 3.34ns | 0.0186 | 0 | 0 | 1.34 KB |
| #3205 | ExecuteAsync |
net472 | 3.16μs | 18.4ns | 160ns | 0.225 | 0 | 0 | 1.42 KB |
| #3205 | ExecuteAsync |
netcoreapp3.1 | 2.12μs | 14.9ns | 146ns | 0.0179 | 0 | 0 | 1.34 KB |
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | SendAsync |
net472 | 5.88μs | 2.65ns | 10.3ns | 0.438 | 0 | 0 | 2.77 KB |
| master | SendAsync |
netcoreapp3.1 | 3.73μs | 0.904ns | 3.38ns | 0.0355 | 0 | 0 | 2.6 KB |
| #3205 | SendAsync |
net472 | 5.62μs | 6.63ns | 25.7ns | 0.438 | 0 | 0 | 2.77 KB |
| #3205 | SendAsync |
netcoreapp3.1 | 3.55μs | 4.63ns | 17.3ns | 0.0359 | 0 | 0 | 2.6 KB |
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net472 | 3.16μs | 3.56ns | 13.3ns | 0.287 | 0.00157 | 0 | 1.81 KB |
| master | EnrichedLog |
netcoreapp3.1 | 2.5μs | 1.3ns | 4.68ns | 0.025 | 0 | 0 | 1.85 KB |
| #3205 | EnrichedLog |
net472 | 3.17μs | 3.07ns | 11.5ns | 0.288 | 0 | 0 | 1.81 KB |
| #3205 | EnrichedLog |
netcoreapp3.1 | 2.51μs | 1.47ns | 5.5ns | 0.0253 | 0 | 0 | 1.85 KB |
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net472 | 152μs | 136ns | 528ns | 0.679 | 0.226 | 0 | 4.66 KB |
| master | EnrichedLog |
netcoreapp3.1 | 119μs | 131ns | 506ns | 0.0596 | 0 | 0 | 4.49 KB |
| #3205 | EnrichedLog |
net472 | 153μs | 242ns | 939ns | 0.682 | 0.227 | 0 | 4.67 KB |
| #3205 | EnrichedLog |
netcoreapp3.1 | 115μs | 127ns | 475ns | 0 | 0 | 0 | 4.49 KB |
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net472 | 5.96μs | 3.16ns | 12.2ns | 0.568 | 0.00297 | 0 | 3.59 KB |
| master | EnrichedLog |
netcoreapp3.1 | 4.48μs | 2.72ns | 10.2ns | 0.053 | 0 | 0 | 3.91 KB |
| #3205 | EnrichedLog |
net472 | 5.62μs | 9.87ns | 38.2ns | 0.569 | 0.0028 | 0 | 3.59 KB |
| #3205 | EnrichedLog |
netcoreapp3.1 | 4.28μs | 7.84ns | 30.4ns | 0.0527 | 0.00211 | 0 | 3.91 KB |
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | SendReceive |
net472 | 2.35μs | 3.64ns | 13.6ns | 0.217 | 0 | 0 | 1.37 KB |
| master | SendReceive |
netcoreapp3.1 | 1.85μs | 1.06ns | 4.1ns | 0.0184 | 0 | 0 | 1.32 KB |
| #3205 | SendReceive |
net472 | 2.43μs | 2.29ns | 8.25ns | 0.217 | 0 | 0 | 1.37 KB |
| #3205 | SendReceive |
netcoreapp3.1 | 1.79μs | 1.88ns | 7.29ns | 0.0179 | 0 | 0 | 1.32 KB |
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | EnrichedLog |
net472 | 5.14μs | 2.41ns | 9.35ns | 0.354 | 0 | 0 | 2.23 KB |
| master | EnrichedLog |
netcoreapp3.1 | 4.37μs | 2.88ns | 11.2ns | 0.024 | 0 | 0 | 1.8 KB |
| #3205 | EnrichedLog |
net472 | 4.96μs | 2.99ns | 11.6ns | 0.354 | 0 | 0 | 2.23 KB |
| #3205 | EnrichedLog |
netcoreapp3.1 | 4.49μs | 2.35ns | 8.15ns | 0.0224 | 0 | 0 | 1.8 KB |
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StartFinishSpan |
net472 | 1.18μs | 0.559ns | 2.17ns | 0.128 | 0 | 0 | 810 B |
| master | StartFinishSpan |
netcoreapp3.1 | 949ns | 0.417ns | 1.56ns | 0.0104 | 0 | 0 | 760 B |
| master | StartFinishScope |
net472 | 1.49μs | 0.667ns | 2.58ns | 0.141 | 0 | 0 | 891 B |
| master | StartFinishScope |
netcoreapp3.1 | 1.06μs | 0.331ns | 1.24ns | 0.0117 | 0 | 0 | 880 B |
| #3205 | StartFinishSpan |
net472 | 1.18μs | 0.392ns | 1.47ns | 0.128 | 0 | 0 | 810 B |
| #3205 | StartFinishSpan |
netcoreapp3.1 | 931ns | 0.492ns | 1.9ns | 0.0103 | 0 | 0 | 760 B |
| #3205 | StartFinishScope |
net472 | 1.43μs | 0.738ns | 2.86ns | 0.141 | 0 | 0 | 891 B |
| #3205 | StartFinishScope |
netcoreapp3.1 | 1.11μs | 0.466ns | 1.8ns | 0.0117 | 0 | 0 | 880 B |
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | RunOnMethodBegin |
net472 | 1.51μs | 0.899ns | 3.48ns | 0.141 | 0 | 0 | 891 B |
| master | RunOnMethodBegin |
netcoreapp3.1 | 1.17μs | 0.528ns | 1.98ns | 0.0117 | 0 | 0 | 880 B |
| #3205 | RunOnMethodBegin |
net472 | 1.53μs | 0.525ns | 2.03ns | 0.141 | 0 | 0 | 891 B |
| #3205 | RunOnMethodBegin |
netcoreapp3.1 | 1.22μs | 0.602ns | 2.33ns | 0.0115 | 0 | 0 | 880 B |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of changes
Add an extension for Fluent Assertions that compares strings for equality but only outputs a diff between the strings. Useful when working with very long multi-line strings.
For example, adding one assembly references causes the test
AssemblyReferencesHaveNotChangedto fail with the following message:The message above includes the full text of both strings, but does not indicate what the differences are between the strings. After this PR, the message shows only the differences between the two strings, including their line number. In the example below it is clear that a single line was added at line 20 and the new assembly is
System.Diagnostics.Tools:Reason for change
This change should make it easier to diagnose failing test that compare long multi-line strings.
Implementation details
DiffPlexlibrary to perform the actual diff between stringsStringAssertions.Be()extension method overload with additionalbool outputDiffOnlyparameterDiffPaneModelFormatter : IValueFormatterto convert theDiffPaneModelto output string used by Fluent AssertionsPublicApiHasNotChangedandAssemblyReferencesHaveNotChangedUsage:
Currently this only performs a line-by-line diff, but it would be trivial to add a parameter to the extension method to use different
DiffPlex"chunkers" (e.g. word-by-word, char-by-char).Test coverage
:inception: