Version 0.1

All you need to know about:

Data formats for network transfer

In any type of test automation, you will need to work with structured test data. This section is a walkthrough of common test data formats, and how to use them and what to look out for. It's intended for technical testers and is meant for aspiring technical testers to gain enough knowledge to keep learning from Google or training.

It's worth noting that testers tend to think about data formatted with JSON or XML as text while programmers view them as objects that are being transferred in a serialized format. Both views are true, while it's beneficial to understand each others perspectives.

Happy learning, or happy confirmation that you are already skilled.


Table of contents


General concerns

Non-text-based system integrations

Many systems transfer data between systems. There are a lot of mechanisms for this. Sometimes it includes persisting (=storing) data to a database in between different components of the systems use them. Sometimes organizations use integration platforms to transform a deliver information between systems. Certain technologies include their own mechanisms to use functionality and pass data between system components:

This session will not go through these types of technologies. Partly because they are being transition to REST services, and partly because they need a white-box testing approach to be useful.

When the IT landscape became more complex, and the network capacity developed a magnitude faster than the rest of IT (where the rest of IT kept following Moore's law), client/server systems were abandoned in favour of centralized architecture, enabling a diverse IT landscape. In the process of unifying these systems and making them communicate mechanisms like SOAP and REST were developed, and structured program language and operating environment independent data transfer formats. This section aims at delivering enough comprised information about these formats to enable further learning.


Character encoding

As soon as text-based data is mention it is worth mentioning character encoding. It's a common source of problems, and any tester should know the basics of character encoding.

In the inner workings of any computer it only works with bits, zeros and ones. Binary format. Eight bits become a Byte (note the difference between kb - kilo bit, and kB - kilo Byte).
Depending on the computer architecture bytes are combined to words of different lengths. These are not words in the common sense. In computerology a word is a number of Bytes that are addressed in the memory space.

There are a lot of different character encodings to tell the computer what combination of zeroes and ones that should be what text character. Most operating systems come with a default character encoding, but programs easily override this. There are a lot of reasons why this is beneficial. Examples:

Using the wrong character encoding makes some characters appear strange.

Popular character encodings are:


CSV - Character Separated Values

One basic form of structured data is the CSV format. Sometimes the CSV is interpreted as Comma Separated Values, but it actually works with different types of separators and the original meaning of CSV is Character Separated Values.

Like the flat file format this format mimics the way data is stored in a database. This makes it easy to send a result set from an old fashion database to a client.

Maybe the easiest form of structured data is the CSV formatted data. It's a simple table with data that has its rows separated by line break character(s) (=variants of /n/r depending on OS/character set), and its cell per row separated by a specified character. Generally ; (semi-colon), {TAB}, or , (comma) is used to divide cell data from each other.

Sometimes the headings row is included, sometimes it is omitted.


                Name;OrgNr;amount
                Karl Bengtsson;101010-1010;45
                Emily Wattson;202020-2020;1034
            

There are several things that can go wrong interpreting a CSV formatted data.


Regular expressions

One very powerful, standardized, and widely used mechanism for finding information in text-based content is called Regular Expression.

Regular Expressions is a syntax for pattern matching in text content. Regular expressions are implemented in most programming languages, and is extremely googleable. If you for example need a pattern for validating email addresses, numbers, texts, or social security numbers, or company id's, or IP-addresses, they are readily available. With just a little bit of practice you'll be proficient enough with them too.

Regular expressions rely on a content string to find something in (could be multiple instances), and a pattern matching string. A few examples are given below:


            //Data:
            var contentString = "My name is Oscar, or Bengt, or Carlos.";

            //Regular expression boolean match:
            if(RegEx.Match(contentString, ".*sca.*")){
                Console.WriteLine("Yes"); //Output Yes since the character combination 'sca' can be found in the contentString
            }
        

Cheat sheet

Regular expression basics are easy, but it can quickly become very complex. A few of the basic reserved characters are:

Character Explanation
. Any character
* Any amount
.* Any amount of any character - essentially: Ignore this part of the string
[] Brackets for range of characters
() Prioritized part of pattern, for execution preference
/ Escape character to enable use of reserved characters

Regular Expressions may be used with any of these serialized object types. It's very diverse and powerful. Any technical tester should know the basic of these.


Structured data

Sending data over a network could be easy, if it's already in binary format and need no context. For simple services it's ok to send simple text encoding, but most often this is not enough. Say you want to transfer information about an employee from a server to a client.


                public class Employee{
                    public string Name;
                    public int EmployeeNumber;
                    public Date EmploymentDate;
                    public Salary CurrentSalary;
                    public List<Salary> HistoricSalaries;
                }
            

Looking at this employee we can deduct that the Salary part probably is another class with its own complexity in start dates, decision dates, end dates and amount per timespan. Trying to send an employee as CSV formatted data would be problematic.

The process of transforming an object in a program to something that could be expressed in a text format for storage or transfer is called serialization.
The reverse process of having an object expressed in for example XML data or JSON data is called deserialization.


XML

The XML (eXtensive Mark-up Language) is probably the most powerful text-based data format. It doesn't only include the data, but can also include attributes, tag names, be validated towards a schema and described in service descriptions.

An XML representation of an Employee derived from the class above would look like:


                <Employee>
                    <Name>
                        Anders Engelberg
                    </Name>
                    <EmployeeNumber>
                        1232
                    </EmployeeNumber>
                    <EmploymentDate>
                    </EmploymentDate>
                    <CurrentSalary>
                        <MontlySalaryInDollars>
                            3000
                        </MontlySalaryInDollars>
                        <StartDate>
                            Saturday 30-December, 2017
                        </StartDate>
                        <StopDate />
                        <AgreedNextNegotiationDate />
                    </CurrentSalary>
                    <HistoricSalaries />
                </Employee>
            

As can be seen above the empty data fields may be short capped with the / sign rather than with its closing tag.

One of the benefits of XML is that you may include extra information with the data. For example, the same data could be spiced up with attributes:


                <Employee company='Gr8test Inc.' class='currentlyemployed'>
                    <Name encoding='utf8'>
                        Anders Engelberg
                    </Name>
                    <EmployeeNumber>
                        1232
                    </EmployeeNumber>
                    <EmploymentDate>
                    </EmploymentDate>
                    <CurrentSalary currency='USD' timespan='perMonth'>
                        <Salary>
                            3000
                        </Salary>
                        <StartDate format='unix' timezone='GMT+1' summertimecorrelated=false>
                            Saturday 30-December, 2017
                        </StartDate>
                        <StopDate />
                        <AgreedNextNegotiationDate hasHadYearlyDevelopmentTalk=false />
                    </CurrentSalary>
                    <HistoricSalaries />
                </Employee>
            

XML has been widely used for a long time and is very googleable. To enable easier googling the following terms should be known.


                <Employee company='Gr8test Inc.'>
                    <Name encoding='utf8'>
                        Anders Engelberg
                    </Name>
                    <HistoricSalaries />
                </Employee>
            

There are several pitfalls with XML, and it's a source of headache at times. Common errors include:

XPath

XPath is a mechanism for identifying nodes, and interacting with them, in XML data. XML consist of a hierarchy of elements with different values, names and attributes. XPath generally returns a set of XML nodes.

To identify nodes in the XML tree a specific notation called XPath has been developed. In the GUI testing of web, we'll go much further into this. This section is but a brief introduction.

Any XML has at least one root node. Sometimes there are several root nodes, thus starting with an array of elements.

XPaths are made up of a combination of specific expressions and strings. They are interpreted from left to right.

XPaths are dynamic in the programmatic sense that they return an array of elements if multiple are found, or the first element if only one is found - or null if no element is found.
This means you don't have to do unnecessary null checks or check for results length, or have to use results[0] to get the first element.

Cheat sheet

Basic XPath notation:

Expression Description
// Any element below this point in the node tree (among the descendants)
/ Child node of this element
* Any node type
[] Condition for node identification, either by boolean match or item count in array
() Prioritized expression that is calculated before anything else
and Logic operator when used in a condition []
or Logic operator when used in a condition []
text() Method to get the value of a node
contains(longString, partToFind) Method to identify attribute values, or node values, containing a specific text string
@ Marker to get the value of an attribute by its name (e.g. @id='myId')
.. One level up in the tree, to current node's parent
. Current node

To use these, they are combined into strings, for example would //Name in the XML above return the whole element <Name encoding='utf8'>Anders Engelberg</Name>.

However, this would not be terribly useful. It might be better to retrieve the current salary from Anders by //Name[text()='Anders Engelberg']/../CurrentSalary/Salary.
To break down this expression; by // it searches the whole tree, not only the top node. Name is the node name, but not any Name element since it's being followed by a specific condition that it should be matching [text()='Anders Engelberg']. When that node is identified, the XPath states we should go back to the parent node of this. That is the /.. part stating this. From the parent node of the Name node with the text 'Anders Engelberg' a child / with the node name CurrentSalary is selected, and from this the child node / with the name Salary is selected.

XPath examples

Given a HTML page like this:


            <!doctype html>
            <html>
                <head>
                    <title>THIS IS THE TITLE</title>
                </head>
                <body>
                    <h1>Document title</h1>
                    <p class=/"ingress/">
                        Lorem ipsum...
                    </p>
                </body>
            </html>
        

The following XPaths return the following nodes:


            /html/head/title 
            Returns: The <title>THIS IS THE TITLE</title> element.

            //title
            Returns: The <title>THIS IS THE TITLE</title> element.
        

XSLT

One of the benefits of XML is that you may validate data towards a description of valid data. This could include what fields are mandatory, how many of each element could be included where, max or minimum field lengths or number ranges, and so forth.


JSON

JSON formatted data contains less information than XML based data. JSON support is native to JavaScript, but since the format is very popular, most programming languages integrates libraries for easy JSON management.

The same Employee object as was expressed with XML above would be expressed with JSON like this:



                { 'employee': 
                    'name': 'Anders Engelberg',
                    'employeenumber': '1232',
                    'employmentdate': '',
                    'currentsalary': 
                        'montlysalaryindollars': 3000,
                        'startdate': 2017-09-30,
                        'stopdate': ''
                    'historicsalaries': []
            }
            

There are several versions of JSON. Sometimes the names don't have quotes. Sometimes it uses double quotation marks, sometimes single quotation marks. The different JSON frameworks out there cope with this.

Cheat sheet

Reserved characters in JSON

Character Description
{} Object start and stop character.
[] Group of objects of the same type (array/list)
' String enclosing character. In REST either ' or " could be used as long as it's consistent
" String enclosing character. In REST either ' or " could be used as long as it's consistent
: Separation between object name and value
, Field separator between different properties/fields of an object expressed with JSON

JsonPath

Just like XML has XPath, JSON has JsonPath to find node values. Just like XPath the JsonPath is implemented in libraries for most programming languages. However, the syntax of the two are very different.

Notation

JsonPath uses special notation to represent nodes and their connections to adjacent nodes in a JsonPath path. There are two styles of notation, namely dot and bracket.

Both of the following paths refer to the same node from the above JSON document, which is the third element within the location field of creator node, that is a child of the jsonpath object belonging to tool under the root node.

With dot notation:

            $.tool.testautomation.vendor[2]
        

With bracket notation:

            $['tool']['testautomation']['vendor'][2]
        

The dollar sign ($) represents root member object.

Operators

JsonPath also has a number of helpful operators:

Root node ($): This symbol denotes the root member of a JSON structure no matter it is an object or array. Its usage examples were included in the previous sub-section.

Current node (@): Represents the node that is being processed, mostly used as part of input expressions for predicates. Suppose we are dealing with book array in the above JSON document, the expression book[?(@.price == 49.99)] refers to the first book in that array.

Wildcard (*): Expresses all elements within the specified scope. For instance, book[*] indicates all nodes inside a book array.

Functions used as filters

JsonPath also has functions that can be used to the end of a path to synthesize that path's output expressions: min(), max(), avg(), stddev(), length().

Filters are used as booleans to restrict result sets.

A few examples are equality (==), regular expression matching (=~), inclusion (in), check for emptiness (empty). Filters are mainly used for predicates.

Cheat sheet

Part of expression Description
. One step down in the hierarchy
[ ] Specific descendant node name
$ Root node
* Any node
@ Current node

YAML

YAML is an attempt to make structural data more human readable.

It's structured data built from indentation and colons, much like a human would structure data in Notepad.

The usage of YAML is spreading, but at the time of producing this material it's not widespread enough to render a chapter of its own, but the reader should know the YAML structures exist.


Rarely needed extra information for the really curious

Binary data

Binary data, like for example images, compressed data, or programs, may be transferred as a byte stream, or you play the trick of tricking the client to interpret the bytes of zeroes and ones as the corresponding character according to a specific character encoding. For example, this makes it suitable for SOAP/REST based transfer. To decode it again it needs to use the same interpretation backwards. The most common mechanism for this is called BASE64 encoding (works in any programming language and is very googleable).

Even if the BASE64 encoding/decoding is the most common one - especially for web (since it is HTML character safe), several others exist.


Flat files

Flat files are a bit like CSV formatted data, but instead of using a separating character, each data field is divided by being a specific number of characters in length. This makes the files very large, since for example a name field will need to be long enough for the longest name - and all other name fields need to be at least this long and set in advance.

To cope with complex data in a hierarchy many times one of the fields of a data row is a schema identifier to interpret what data schema the row should be interpreted by.

Flat file formatted data quickly can become very cumbersome to use.


Exercises

Link to exercises.

Index of keywords