Click here to Skip to main content
15,885,546 members
Articles / DevOps / Testing

Scribe4net - The test oriented serializer

Rate me:
Please Sign up or sign in to vote.
4.67/5 (5 votes)
3 Apr 2013CPOL4 min read 15.8K   9   3
How to assert an object state using only 2 code lines

 Scribe4net is also on codeplex feel free to suggest changes and open defects...  

 Introduction 

Scrive4net is a simple serializer for test scenarios, in contrast to traditional serializers which are used for object persistance to HDD or over network connections, no thought was given to deseirialization back to the original object (as this was not the intention), the main concern here was human readability and full control over serialization.  

The need it fills is getting an object into text form so it can be compared to the standard / preapproved object, or to approve it as the standard object.  

  • The output string is as human readable as can be, and comes with built in formatting.
  • Output is deterministic = the same object will produce the same output string every time. (for string diffing) 
  • Produces a simple ToString value for primitive types (including string and date)
  • Produces a xml / json representation of an object including all properties
  • Opt in & opt out support
  • Depth limitation support
  • Handles List / Array & Dictionary properties (IEnumerable & IDictionary)
  • Complience with standard xml & json formats is provided so deserialization into a wroking object model is easy.
  • Supports serializing properties and fields of any object
  • Full control over which types of members to serialize (public / nonPublic / static / instance)  

 Background  

As software project have grown in size and complexity, many of them began to rely on multi tiered automatic testing for early dicovery of bugs and regressions, unit tests and integration tests are a big part of that, but they are time consuming and writing them is definitely not of the best loved things to code...

I have been looking for ways to shorten the time it takes to write tests, and came across the concept of comparing the object recieved to a standard object, preapproved as the correct answer (both in string form), this way can be used instead of checking the object's properties and verifying it's content by code, it is easy to understand and compare, there are many nice diff tools for the job, and you don't need to code the assertions by hand. 

This approach can already make use of a nice framework called Approval Tests which speeds up comparing and approving the string representations of the situations, but i still thought there is still something missing: Getting the object into string form is still done manually, picking the right set of fields, and creating getString and ToString functions. What about complex objects like trees? getting those into string form takes a bit of work, and you have to do it all over again for each class.  

So i started writing this little project, its a simple serializer written in c# with the json concept in mind: everything can be expressed using only dictionaries and lists, and an object is just a dictionary... 

The main point is that you get full control over the output serialization, and that the output is readable, so that changes will really pop up when diffed. 

Using the code  

I kept the usage of this class as simple as can be, just a simple static call to the function: 

C#
string result = TestObjectSerializer.SerializeToString(yourObject, SerializationType.Xml); 

When more control is needed you can pass an aditional settings object:

C#
SerializationSettings settings = new SerializationSettings() 
{  
 MaxDept = -1,
 IncludeFields = true,
 FieldInclusion = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic 
};
 
string result = TestObjectSerializer.SerializeToString(yourObject, SerializationType.Xml, settings); 

The SerializationSettings object contains the following properties:  

  • MaxDept lets you control the depth which the serializer will reach in the object graph before stopping.
  • Include fields allows you to include fields (in addition to properties)
  • FieldInclusion is a BindingFlags enum, which allows full control over which types of fields to include 
  • PropertyInclusion is a BindingFlags enum, which allows full control over which types of properties to serialize. 
  • OptIn is a boolean which switches between opt in and out modes (default is OptOut, where all properties are included, unless an attribute is set to exclude them). 

 To Exclude properties you can use the  [TestSerializerOptOut] attribute: 

[TestSerializerOptOut]  
string YourProperty {get;set;}

To inlude only explicitly included properties you can use the  [TestSerializerOptIn]  attribute while passing the OptIn=true setting in the settings object (this is false by default): 

[TestSerializerOptIn] 
string YourProperty {get;set;}    

Serialization Depth can be controlled by changing the MaxDept setting (-1 is unlimited, and is the default) 

SerializationSettings settings = new SerializationSettings() 
{  
 MaxDept = 3,
};   

So now objects can be compared as simply and easily as comparing integers and strings, asserting the correctness of a complex situation now takes two lines of code:  

string result = TestObjectSerializer.SerializeToString(primitive1, SerializationType.Xml);
Approvals.Verify(result); 

The second line uses Approval tests, but it can just as easily be Assert.Equals(strExpected,strReceived).   

 Conclusions   

I hope this will cut some test writing time for everyone...  tell me what you think !  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Hp Software
Israel Israel
I've been all over the coding world since earning my degrees
have worked in c++ and java, finally setteling into c# about 6 years ago, where i spent a good amount of my time in Performance tweaking & memory debugging, as well as designing new solutions and hacking at old ones to stay in line.

Computers never cease to amaze me, and i'm glad to have found a field where i get paid to do what i enjoy.

I have been toying around with the idea of publishing stuff online for years, never actually getting around to it, so i still have a lot of stuff to write up, aside from all the other new stuff i'll get excited about, hope you'll like enjoy reading it as much as i enjoy writing.

linkedin
google plus

Comments and Discussions

 
QuestionThis looks rather awesome! Pin
John Torjo28-Oct-15 23:36
professionalJohn Torjo28-Oct-15 23:36 
GeneralMy vote of 5 Pin
Abinash Bishoyi4-Apr-13 7:45
Abinash Bishoyi4-Apr-13 7:45 
Nice
GeneralMy vote of 4 Pin
_Vitor Garcia_4-Apr-13 4:06
_Vitor Garcia_4-Apr-13 4:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.