2012-10-10 2 views
5

Kann ich ApprovalTests mit PDFs verwenden? Ich habe versucht, den FileLauncher zu verwenden, aber es scheint, dass die identischen PDFs auf Datei (Bit) Ebene etwas anders sind. Oder habe ich es falsch benutzt?Genehmigungstests und PDF

[TestMethod] 
[UseReporter(typeof(FileLauncherReporter))] 
public void TestPdf() 
{ 
    var createSomePdf = PdfCreate(); 

    ApprovalTests.Approvals.Verify(new FileInfo(createSomePdf.FileName)); 

} 

Antwort

6

Das Pdf wird höchstwahrscheinlich mit einem Zeitstempel erstellt. Abhängig von der Methode, die zum Erstellen der PDF-Datei verwendet wird, können Sie möglicherweise die erstellte Zeit nachstellen. aber ich musste es schrubben.

Hier ist der Code, den ich verwendet habe, um das zu tun.

public static void VerifyPdf(string coverFile) 
    { 
     ScrubPdf(coverFile); 
     Approvals.Verify(new ExistingFileWriter(coverFile)); 
    } 

    private static void ScrubPdf(string coverFile) 
    { 
     long location; 
     using (var pdf = File.OpenRead(coverFile)) 
     { 
      location = Find("/CreationDate (", pdf); 

     } 
     using (var pdf = File.OpenWrite(coverFile)) 
     { 
      pdf.Seek(location, SeekOrigin.Begin); 

      var original = "/CreationDate (D:20110426104115-07'00')"; 
      var desired = new System.Text.ASCIIEncoding().GetBytes(original); 

      pdf.Write(desired, 0, desired.Length); 
      pdf.Flush(); 
     } 
    } 
+0

Brilliant dank Llewellyn, gab es auch ein geändertes Datum und Dokument-ID von meinem pdf-Generator (iTextSharp) erstellt, hatte sie hinzufügen auch. – joeriks

5

fand ich ein Werkzeug Befehlszeilen, diff-pdf. Vergleicht 2 PDFs und gibt Exit-Code 0 zurück, wenn sie identisch sind, 1, wenn sie sich unterscheiden. Downloaden + extrahieren + fügen Sie es Ihrem PATH hinzu.

Nachteil - es muss beide PDFs rendern, um das diff durchzuführen. Wenn sie groß sind, schlagen sie perfekt.

Approver (basierend stark auf ApprovalTests.Approvers.FileApprover):

public class DiffPdfApprover : IApprovalApprover 
{ 
    public static void Verify(byte[] bytes) 
    { 
     var writer = new ApprovalTests.Writers.BinaryWriter(bytes, "pdf"); 
     var namer = ApprovalTests.Approvals.GetDefaultNamer(); 
     var reporter = ApprovalTests.Approvals.GetReporter(); 

     ApprovalTests.Core.Approvals.Verify(new DiffPdfApprover(writer, namer), reporter); 
    } 

    private DiffPdfApprover(IApprovalWriter writer, IApprovalNamer namer) 
    { 
     this.writer = writer; 
     this.namer = namer; 
    } 

    private readonly IApprovalNamer namer; 
    private readonly IApprovalWriter writer; 
    private string approved; 
    private ApprovalException failure; 
    private string received; 

    public virtual bool Approve() 
    { 
     string basename = string.Format(@"{0}\{1}", namer.SourcePath, namer.Name); 
     approved = Path.GetFullPath(writer.GetApprovalFilename(basename)); 
     received = Path.GetFullPath(writer.GetReceivedFilename(basename)); 
     received = writer.WriteReceivedFile(received); 

     failure = Approve(approved, received); 
     return failure == null; 
    } 

    public static ApprovalException Approve(string approved, string received) 
    { 
     if (!File.Exists(approved)) 
     { 
      return new ApprovalMissingException(received, approved); 
     } 

     var process = new Process(); 
     //settings up parameters for the install process 
     process.StartInfo.FileName = "diff-pdf"; 
     process.StartInfo.Arguments = String.Format("\"{0}\" \"{1}\"", received, approved); 

     process.Start(); 

     process.WaitForExit(); 

     if (process.ExitCode != 0) 
     { 
      return new ApprovalMismatchException(received, approved); 
     } 

     return null; 
    } 

    public void Fail() 
    { 
     throw failure; 
    } 

    public void ReportFailure(IApprovalFailureReporter reporter) 
    { 
     reporter.Report(approved, received); 
    } 

    public void CleanUpAfterSucess(IApprovalFailureReporter reporter) 
    { 
     File.Delete(received); 
     if (reporter is IApprovalReporterWithCleanUp) 
     { 
      ((IApprovalReporterWithCleanUp)reporter).CleanUp(approved, received); 
     } 
    } 
} 

zu überprüfen:

DiffPdfApprover.Verify(pdfBytes);

diff-pdf kann sowohl optisch als auch zeigen diffs. Ich habe einen Reporter dafür gerollt, aber benutze ihn nicht viel. Ich denke, es wird sich als nützlich erweisen, wenn es Regressionen nach der ersten Report-Entwicklung gibt (wo ich gerade bin).

public class DiffPdfReporter : GenericDiffReporter 
{ 
    private static readonly string Path = FindFullPath("diff-pdf.exe"); 
    public DiffPdfReporter() : base(Path, 
     GetArgs(), 
     "Please put diff-pdf.exe in your %PATH%. https://github.com/vslavik/diff-pdf. And restart whatever's running the tests. Everything seems to cache the %PATH%.") { } 

    private static string GetArgs() 
    { 
     return "--view \"{0}\" \"{1}\""; 
    } 

    private static string FindFullPath(string programInPath) 
    { 
     foreach (var path in from path in Environment.GetEnvironmentVariable("path").Split(';') 
          select path) 
     { 
      var fullPath = System.IO.Path.Combine(path, programInPath); 
      if (File.Exists(fullPath)) 
       return fullPath; 
     } 
     return null; 
    } 
} 
1

Sieht so aus, als ob dies jetzt in ApprovalTests eingebaut ist.

Nutzung:

Approvals.VerifyPdfFile(pdfFileLocation); 

Siehe the source:

public static void VerifyPdfFile(string pdfFilePath) 
{ 
    PdfScrubber.ScrubPdf(pdfFilePath); 
    Verify(new ExistingFileWriter(pdfFilePath)); 
} 
+0

Ich bin neu bei ApprovalTests und von dem, was ich gesehen habe, ist die Dokumentation ziemlich spärlich (besonders für PDFs). Können Sie erklären, wie Sie einen Komponententest schreiben, der eine PDF-Datei verifiziert? Das Beispiel auf github sieht aus wie ein Dateiname.reciew.pdf hätte erstellt werden sollen, aber ich kann keinen finden. – Ben

+1

@Ben sehen Sie sich das [Unit-Test-Beispiel] (https://github.com/approvals/ApprovalTests.Net/blob/master/ApprovalTests.Tests/Pdf/PdfTest.cs) im Projekt an. Aber Sie haben Recht, es scheint keine .Received-Datei für PDFs zu erstellen. Das erstelle ich selbst in meinen Tests. – Mathew

+0

danke @Mathew. Es führt jetzt zumindest den Vergleich durch, aber es schlägt immer noch fehl. Wenn ich die beiden Dokumente selbst vergleiche, ist das Erstellungsdatum anders (ich denke, dass das mit der PdfScrubber.ScrubPdf (...) Methode erledigt wird), und es gibt auch ein paar Guids am unteren Ende der Datei, die sich unterscheiden – Ben