2.1. Tests Define Your Contract
When you write tests first, then write code to make them pass, it forces you to focus on the contract that your code is making with the rest of the system. Every piece of code has a contract, whether implicit or explicit. Every piece of code does something (or at least it should), and what the code does and how it is called by other code constitutes its contract. We'll talk more about contracts in Chapter 8, "Contract, Contract, Contract!," but for now we'll look at how writing tests helps define your contracts and why that's important.
As an example, imagine a simple calculator interface that adds, subtracts, multiplies, and divides integers. It's easy to imagine how such an interface would be implemented, but there are several ways it could be used. Thirty years ago, most serious calculators used Reverse Polish Notation (RPN). RPN is convenient from the implementer's perspective, because it uses a stack to store operands and operators, and it's very useful for implementing complex calculations. It would be easy to write an RPN-style calculator interface, such as the following:
public interface IRPNCalculator { int Op1 { get;set;} int Op2 { get;set;} int Add(); int Subtract(); int Multiply(); int Divide(); }
If you were to write the tests for this interface before implementing it, you might end up with a test like this:
[Test] public void Add() { IRPNCalculator calc = new Calculator(); calc.Op1 = 2; //set the first operand calc.Op2 = 2; //set the ...
Get Code Leader: Using People, Tools, and Processes to Build Successful Software now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.