# Invariants: A Better Debugger?

DevFeed: [Invariants: A Better Debugger?](<https://devfeed.tech/articles/invariants-a-better-debugger-12542.md>)

Original publisher: [Read original article](<http://brooker.co.za/blog/2023/07/28/ds-testing.html>)

Author: Marc Brooker

Published: 2023-07-28T00:00:00Z

Content type: article

Language: en

Sources: [Marc Brooker's Blog](<https://devfeed.tech/sources/marc-brooker-s-blog.md>), [Marc Brooker's Blog](<https://devfeed.tech/sources/marc-brooker-s-blog-2.md>)

Topics: [debugging](<https://devfeed.tech/topics/debugging.md>), [Algorithms](<https://devfeed.tech/topics/algorithms.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [distributed-systems](<https://devfeed.tech/topics/distributed-systems.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [blog](<https://devfeed.tech/tags/blog.md>), [bugs](<https://devfeed.tech/tags/bugs.md>), [code](<https://devfeed.tech/tags/code.md>), [debugger](<https://devfeed.tech/tags/debugger.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [distributed-systems](<https://devfeed.tech/tags/distributed-systems.md>)

## AI overview

The article argues that testing invariants can be a more effective debugging approach than relying on debuggers or printf output. It recommends unit tests that check properties after each step of a system or algorithm, including data, data structures, business logic, and distributed systems. A personal example involving a Delaunay triangulation algorithm illustrates how step-by-step and global invariants exposed a bug quickly. The article also connects this approach to TLA+ and global invariants, though the supplied text ends during a Paxos example.

## Source excerpt

Invariants: A Better Debugger? 🎵Some things never change🎵 Like many of my blog posts, this started out as a long email to a colleague. I expanded it here because I thought folks might find it interesting. I don't tend to use debuggers. I'm not against them. I've seen folks do amazing things with gdb, and envy their skills. I just don't tend to reach for a debugger very often. I'm also not a huge fan of printf debugging. It can be useful, it's easy to implement, and works well in both one-box and distributed systems. But very quickly the reams of output become overwhelming, and slow me down rather than helping me reason about things. My go-to approach when faced with bugs is testing. More specifically, testing invariants. Most specifically, writing unit tests that assert those invariants after a system or algorithm takes each step. Invariants, like assertions, are things that must be true during or after the execution of a piece of code. "This array is sorted", "the first item is the smallest", "items in the deleted state must have a deleted time", that kind of thing. Invariants are broader than assertions: they can assert properties of a piece of data, properties of an entire data structure, or even properties of collections of data structures spread across multiple machines. Some History Way back in undergrad at UCT, I was trying to implement Guibas and Stolfi's algorithm for Delaunay triangulation for a class project1. My implementation very nearly worked, but there was one example where it just gave the wrong answer. I spent days banging my head on the problem with printfs and debuggers and just wasn't making progress. The TA was no help. I asked a CS graduate student I knew that lived nearby, and his approach just blew my mind. He sat me down with a piece of paper, and went through the algorithm step-by-step, asking what is true about the data structure at this step? after each one. Together, we came up with a set of step-by-step invariants, and some global inva