<!-- GENERATED FILE - DO NOT EDIT This file was generated by [MarkdownSnippets](https://github.com/SimonCropp/MarkdownSnippets). Source File: /docs/mdsource/recording.source.md To change this file edit the source file and then run MarkdownSnippets. --> # Recording Recording allows information to be statically captured and then (optionally) verified. The main value of this feature is to simplify addition of information to a snapshot from extensions to Verify. Before to this feature, for an extension to supply information to a snapshot, that extension had to return the information up the stack, and the calling test had to explicitly add that information to the `Verify()` call. Using this feature an extension can `Recording.Add()` in any context, and the information will be added to the snapshot. ## Usage <!-- snippet: Recording --> <a id='snippet-Recording'></a> ```cs [Fact] public Task Usage() { Recording.Start(); Recording.Add("name", "value"); return Verify("TheValue"); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L23-L33' title='Snippet source file'>snippet source</a> | <a href='#snippet-Recording' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.Usage.verified.txt --> <a id='snippet-RecordingTests.Usage.verified.txt'></a> ```txt { target: TheValue, name: value } ``` <sup><a href='/src/Verify.Tests/RecordingTests.Usage.verified.txt#L1-L4' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.Usage.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## TryAdd If `Recording.Add()` is called before `Recording.Start` an exception will be called. `Recording.TryAdd()` will add an item only if `Recording.IsRecording` is true. <!-- snippet: RecordingTryAdd --> <a id='snippet-RecordingTryAdd'></a> ```cs [Fact] public Task TryAdd() { //using Recording.Add here would throw since Recording.Start has not been called Recording.TryAdd("name1", "value1"); Recording.Start(); Recording.TryAdd("name2", "value2"); return Verify("TheValue"); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L59-L71' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTryAdd' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Scoped Recording can be scoped via a `using`: <!-- snippet: RecordingScoped --> <a id='snippet-RecordingScoped'></a> ```cs [Fact] public Task RecordingScoped() { using (Recording.Start()) { Recording.Add("name1", "value1"); } // Recording.Add is ignored here Recording.Add("name2", "value2"); return Verify(); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L82-L97' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingScoped' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.RecordingScoped.verified.txt --> <a id='snippet-RecordingTests.RecordingScoped.verified.txt'></a> ```txt { name1: value1 } ``` <sup><a href='/src/Verify.Tests/RecordingTests.RecordingScoped.verified.txt#L1-L3' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.RecordingScoped.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Grouping Values are grouped by key: <!-- snippet: RecordingSameKey --> <a id='snippet-RecordingSameKey'></a> ```cs [Fact] public Task SameKey() { Recording.Start(); Recording.Add("name", "value1"); Recording.Add("name", "value2"); return Verify("TheValue"); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L281-L292' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingSameKey' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.SameKey.verified.txt --> <a id='snippet-RecordingTests.SameKey.verified.txt'></a> ```txt { target: TheValue, name: [ value1, value2 ] } ``` <sup><a href='/src/Verify.Tests/RecordingTests.SameKey.verified.txt#L1-L7' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.SameKey.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> To avoid grouping use [Stop](#stop). ## Identifier Recording can be grouped by an identifier. The identifier should be statically unique. For example a fully qualified test name or a GUID. <!-- snippet: RecordingIdentifier --> <a id='snippet-RecordingIdentifier'></a> ```cs [Fact] public Task Identifier() { Recording.Start("identifier"); Recording.Add("identifier", "name", "value"); return Verify(Recording.Stop("identifier")); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L99-L109' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingIdentifier' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.Identifier.verified.txt --> <a id='snippet-RecordingTests.Identifier.verified.txt'></a> ```txt [ { name: value } ] ``` <sup><a href='/src/Verify.Tests/RecordingTests.Identifier.verified.txt#L1-L5' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.Identifier.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Case is ignored <!-- snippet: RecordingIgnoreCase --> <a id='snippet-RecordingIgnoreCase'></a> ```cs [Fact] public Task Case() { Recording.Start(); Recording.Add("name", "value1"); Recording.Add("Name", "value2"); return Verify("TheValue"); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L303-L314' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingIgnoreCase' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.Case.verified.txt --> <a id='snippet-RecordingTests.Case.verified.txt'></a> ```txt { target: TheValue, name: value1, Name: value2 } ``` <sup><a href='/src/Verify.Tests/RecordingTests.Case.verified.txt#L1-L5' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.Case.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Stop Recording can be stopped and the resulting data can be manually verified: <!-- snippet: RecordingStop --> <a id='snippet-RecordingStop'></a> ```cs [Fact] public Task Stop() { Recording.Start(); Recording.Add("name1", "value1"); Recording.Add("name2", "value2"); var appends = Recording.Stop(); return Verify(appends.Where(_ => _.Name != "name1")); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L141-L153' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingStop' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.Stop.verified.txt --> <a id='snippet-RecordingTests.Stop.verified.txt'></a> ```txt [ { name2: value2 } ] ``` <sup><a href='/src/Verify.Tests/RecordingTests.Stop.verified.txt#L1-L5' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.Stop.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> If Stop is called, the results are not automatically verified: <!-- snippet: RecordingStopNotInResult --> <a id='snippet-RecordingStopNotInResult'></a> ```cs [Fact] public Task StopNotInResult() { Recording.Start(); Recording.Add("name1", "value1"); Recording.Add("name2", "value2"); Recording.Stop(); return Verify("other data"); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L155-L167' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingStopNotInResult' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.StopNotInResult.verified.txt --> <a id='snippet-RecordingTests.StopNotInResult.verified.txt'></a> ```txt other data ``` <sup><a href='/src/Verify.Tests/RecordingTests.StopNotInResult.verified.txt#L1-L1' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.StopNotInResult.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## IsRecording The status of Recording can be checked. <!-- snippet: IsRecording --> <a id='snippet-IsRecording'></a> ```cs [Fact] public void IsRecording() { Assert.False(Recording.IsRecording()); Recording.Start(); Assert.True(Recording.IsRecording()); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L111-L121' title='Snippet source file'>snippet source</a> | <a href='#snippet-IsRecording' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> This can be helpful if the cost of capturing data, to add to recording, is high. ## Clear The current recorded items can be cleared: <!-- snippet: RecordingClear --> <a id='snippet-RecordingClear'></a> ```cs [Fact] public Task Clear() { Recording.Start(); Recording.Add("name1", "value1"); Recording.Clear(); Recording.Add("name2", "value2"); return Verify(); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L201-L213' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingClear' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.Clear.verified.txt --> <a id='snippet-RecordingTests.Clear.verified.txt'></a> ```txt { name2: value2 } ``` <sup><a href='/src/Verify.Tests/RecordingTests.Clear.verified.txt#L1-L3' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.Clear.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Pause and Resume Recording can be paused and resumed: <!-- snippet: RecordingPauseResume --> <a id='snippet-RecordingPauseResume'></a> ```cs [Fact] public Task PauseResume() { Recording.Start(); Recording.Pause(); Recording.Add("name1", "value1"); Recording.Resume(); Recording.Add("name2", "value2"); Recording.Pause(); Recording.Add("name3", "value3"); return Verify(); } ``` <sup><a href='/src/Verify.Tests/RecordingTests.cs#L225-L240' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingPauseResume' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> Results in: <!-- snippet: RecordingTests.PauseResume.verified.txt --> <a id='snippet-RecordingTests.PauseResume.verified.txt'></a> ```txt { name2: value2 } ``` <sup><a href='/src/Verify.Tests/RecordingTests.PauseResume.verified.txt#L1-L3' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingTests.PauseResume.verified.txt' title='Start of snippet'>anchor</a></sup> <!-- endSnippet --> ## Extensions that leverage Recording * [Verify.EntityFramework](https://github.com/VerifyTests/Verify.EntityFramework#recording) * [Verify.Http](https://github.com/VerifyTests/Verify.Http) * [Verify.MicrosoftLogging](https://github.com/VerifyTests/Verify.MicrosoftLogging) * [Verify.NServiceBus](https://github.com/VerifyTests/Verify.NServiceBus#recording) * [Verify.Serilog](https://github.com/VerifyTests/Verify.Serilog) * [Verify.SqlServer](https://github.com/VerifyTests/Verify.SqlServer#recording) * [Verify.ZeroLog](https://github.com/VerifyTests/Verify.ZeroLog)