CS Blog

CS-443 Quater 1 | Reaction to Golden Rule of Assertions

What the title says. Go read it here it's pretty nice.

After reading Artem Zakharchenko's article on assertions, two things became clear. First, it's more important to assert the intent of the code than the implementation. Second, it helped me understand why some developers write tests before writing any code.

Let’s break this down. Zakharchenko emphasizes that tests should focus on verifying the right output; how we reach that point is a different concern. This is especially important as projects grow and the implementation changes over time. I've gone through a lot of restructuring across many points of most of my projects but the output of each part generally stayed the same so I can vouch for this lest the output changes too then you're gonna need to rewrite the tests too.

For example, consider a calculator:

const result = evaluateExpression('3 + 5*2');
assert(result === 13); 

The test only concerns itself with the result. It doesn’t matter how the expression is parsed or evaluated. It could be something implemented yourself or some library; the unit test has no prejudice, it will pass either way. As the article says:

“The implementation may change but the intention stays the same.”

Why Write Tests First?

So, why do some developers prefer writing tests before the actual code? The main idea here is that if you already know what you want your program to do, writing tests first can provide a clear direction. You’re essentially defining the expected behavior upfront, and then you write the code to make those tests pass. It's like translating a plan on Figma to a checklist that manages itself as you grow out your program.

Let’s say you’re working on a checkout system, and you want to ensure the total price, including tax and discounts, is calculated correctly. You could write a test for this behavior before even starting to implement the Cart class:

test('correctly calculates total with tax and discount', () => {
  const cart = new Cart();
  cart.addItem('item1', 20);
  cart.addItem('item2', 30);
  cart.applyDiscount(0.1);
  const total = cart.calculateTotal();
  assert(total === 54); // Total = (20 + 30) * 0.9 * 1.05 = 54
});

It defines a Cart object that can take in items, apply a discount, and calculate a total. It would roughly translate to the following implementation:

class Cart {
  list[Item] items;
  double discount
  double taxRate

  void addItem(name, price) { ... }

  void applyDiscount(discount) { ... }

  double calculateTotal() { ... }
}

It may not seem like much but imagine a lot more tests being made to assert different parts of that the system should have. Like customer discounts, removal, coupons, etc. A lot of the structural aspects of building that out would've been ironed out already if ample tests like this one were cranked out beforehand.