diff --git a/src/Verify.XunitV3.Tests/AttachmentTests.cs b/src/Verify.XunitV3.Tests/AttachmentTests.cs index 60e245760..983357fec 100644 --- a/src/Verify.XunitV3.Tests/AttachmentTests.cs +++ b/src/Verify.XunitV3.Tests/AttachmentTests.cs @@ -42,5 +42,27 @@ void Delete() Assert.EndsWith(".received.txt", key); Assert.DoesNotContain(':', key); } + + [Fact] + public async Task DuplicateAttachmentName() + { + DiffEngine.BuildServerDetector.Detected = true; + var verified = Path.GetFullPath(CurrentFile.Relative("AttachmentTests.DuplicateAttachmentName.verified.txt")); + File.Delete(verified); + await File.WriteAllTextAsync(verified, "expected"); + var settings = new VerifySettings(); + settings.DisableRequireUniquePrefix(); + + // Both failing verifies share one received file name, so it is added as an attachment + // twice. Without the dedup guard in AddFile the second add throws ArgumentException + // instead of the expected VerifyException. + await Assert.ThrowsAsync(() => Verify("one", settings)); + await Assert.ThrowsAsync(() => Verify("two", settings)); + + File.Delete(verified); + + var key = Assert.Single(TestContext.Current.Attachments!).Key; + Assert.EndsWith(".received.txt", key); + } #endif } \ No newline at end of file diff --git a/src/Verify.XunitV3/Verifier.cs b/src/Verify.XunitV3/Verifier.cs index 3e87dbaad..1965d714e 100644 --- a/src/Verify.XunitV3/Verifier.cs +++ b/src/Verify.XunitV3/Verifier.cs @@ -3,10 +3,20 @@ namespace VerifyXunit; public static partial class Verifier { - static async Task AddFile(string path) => - TestContext.Current.AddAttachment( - GetAttachmentName(path), - await File.ReadAllBytesAsync(path)); + static async Task AddFile(string path) + { + var name = GetAttachmentName(path); + var context = TestContext.Current; + // A single test can produce the same received file name from multiple failing + // Verify calls (e.g. when DisableRequireUniquePrefix is used). xunit throws on a + // duplicate attachment name, so skip if it has already been added. + if (context.Attachments?.ContainsKey(name) == true) + { + return; + } + + context.AddAttachment(name, await File.ReadAllBytesAsync(path)); + } internal static string GetAttachmentName(string path) {