Skip to main content

Capturing Test Results

In the previous tutorial, we reviewed the main Touca functions for describing the behavior and performance of our code under test, by capturing values of important variables and runtime of interesting functions. In this section, we dive a little deeper to explain how Touca tracks values of variables and performance benchmarks.

Preserving Data Types

Touca data capturing functions such as check, preserve the types of all captured data so that the Touca server can compare them in their original type.

touca.check("username", student.username)
touca.check("fullname", student.fullname)
touca.check("birth_date", student.dob)
touca.check("gpa", student.gpa)

In the example above, touca.check stores value of properties username and fullname as string while properties dob and gpa are stored as datetime.date and float respectively. The server visualizes possible differences in these values based on their types.

The SDK is designed to handle iterables and custom objects by serializing their elements and properties. This makes it possible for us to add object student as a single entity, if we so choose.

Customizing Data Serialization

While Touca data capturing functions automatically support objects and custom types, it is possible to override the serialization logic for any given non-primitive data type.

Consider the following definition for a custom class Course.

@dataclass
class Course:
name: str
grade: float

By default, the SDK serializes objects of this class using by serializing all of its public properties. This behavior results in object Course("math", 3.9) to be serialized as {name: "math", grade: 3.9}. We can use touca.add_serializer to override this default behavior. The following code results in the same object to be serialized as ["math", 3.9]:

touca.add_serializer(Course, lambda x: [x.name, x.grade])
for course in student.courses:
touca.add_array_element("courses", course)
touca.add_hit_count("number of courses")

While our serializer changed the way Course data is serialized and visualized, it still preserved both properties of this object. If we like to exclude the property name during serialization and limit the comparison to grade, we could use (x: Course) => x.grade instead

It is sufficient to register each serializer once per lifetime of the test application.