text: Using Approval Testing for ELMAH.MVC Project
  Using Approval Testing for ELMAH.MVC Project
  Join the DZone community and get the full member experience.Join For Free
  In case you are following my blog, you probably read about Approval.Test framework, which I personally like and recommend to my fellow developers. I did some posts, there I tried to show some Approvals benefits. Today, I'll show some real-life use case.
  Installing by NuGet
  Last time I played with Approvals, the binaries were only available at SourseForge project page. It is not convenient at all. I was happy to see the tweet from Llewellyn Falco, he mentioned that ApprovalTests are now available on NuGet. So, installation now as easy as:
  PM> Install-Package ApprovalTests
  Thinking of test
  I had to have some kind of assurance, that I will not break existing ELMAH pages after I switch to new ELMAH controller. Basically, I need to have some 'Master Database' that would contain all logged errors and I need to grab all possible output that is being generated by ELMAH error log page handler.
  This is what perfectly match the 'Locking Down' testing strategy. In locking down testing, you try to get all possible system output, and approve it. In my case, I wanted to approve that all HTTP calls to ELMAH pages, like '/elmah', '/elmah/stylesheet', '/elmah/rss' and so on, still work as they worked before, meaning producing the same output as they produced before.
  Test implementation
  For my 'do' step of the the test, I need to collect all possible applications output. I already know all URL's, so I just fired up the site with ELMAH.MVC 1.3.2 version installed. I configured the site to use XML files for storing the tests, so I can easily copy them before each test run. That made a kind of 'Master Database' for me.
  For the verification, all I need to have is ApprovalTests.Approvals.Verify().
  [UseReporter(typeof(DiffReporter))] public class ElmahMvcTests { private const string ElmahMvcAppUrl = ""; [Test] public void lock_elmah_mvc_pages() { // do var content = new StringBuilder(); var pages = new[] { ElmahMvcAppUrl, ElmahMvcAppUrl + "/", ElmahMvcAppUrl + "/stylesheet", ElmahMvcAppUrl + "/rss", ElmahMvcAppUrl + "/digestrss", ElmahMvcAppUrl + "/detail?id=5dd2a560-c6fd-4847-a6cc-e3e253db5764", ElmahMvcAppUrl + "/json?id=5dd2a560-c6fd-4847-a6cc-e3e253db5764", ElmahMvcAppUrl + "/xml?id=5dd2a560-c6fd-4847-a6cc-e3e253db5764" }; foreach (var page in pages) { content.Append(GetContent(page)); } // verify ApprovalTests.Approvals.Verify(content.ToString()); }
  The GetContent() is responsible for getting page content. It could be as simple as ApprovalTests.Asp.AspApprovals.GetUrlContents(url), but you might get in the trap, as I did so.
  Dealing dynamic data
  The trap is called 'Dynamic Data'. Dynamic data is every dynamic part of you output. In my case, the dynamic part was a server time generated by ELMAH and putting into page footer. Of cause, even if I run the test and approve the results, on a next test run I still have red test, since I have differences in a seconds of timestamps in footer. It's annoying, but nothing you can do about it.
  My solution was simple. Since I actually don't care about those timestamps at all, I can simple cut it away from output. The rest of the document, including structure and content would remain the same, so testing quality will not be lower.
  So, the GetContent() method will look as follows,
  private string GetContent(string url) { return RemoveFooter(ApprovalTests.Asp.AspApprovals.GetUrlContents(url)); } private string RemoveFooter(string content) { var(.*)</p>"; return new Regex(pattern).Replace(content, string.Empty); }
  Approving the results
  After I had stable test output, I safely approved that test. Approving in terms of ApprovalTest framework, is simple copy of Accepted file into Approved file.
  Now the system got into 'Locked' state and I'm safe to do the changes. This is something as Llewellyn mentioned 100% test coverage with one test. Indeed, having only one test and spent 10 minutes to create it I covered huge piece of functionality.
  Keep that safe
  After I applied all my changes, I re-run approval test to see how it works. I was happy to see, that I'm still generating the same output as it was before. It means, the system still functions as it's expected. All routes works, generated content does not have differences inside. Cool!
  As I said earlier, you don't need to keep the test for all time. In my case, as I completed my refactoring and saw that code still works (and of cause, manually tested the application), it's OK just to delete approval test. No longer needed.
  Approval.Tests are really shines for a scenarios like that.
  Opinions expressed by DZone contributors are their own.
  {{ parent.title || parent.header.title}}
  {{ parent.tldr }}
  {{ parent.linkDescription }}{{ parent.urlSource.name }}