Skip to content

Commit

Permalink
BAU: Test-driven development
Browse files Browse the repository at this point in the history
  • Loading branch information
mrwilson committed Nov 1, 2024
1 parent f53354b commit e32e1fe
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions source/partials/_svg-tdd-red-green-refactor.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<svg version="1.1" viewBox="0.0 0.0 518.488188976378 375.79527559055117" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="500px" style="display: block; margin: 0 auto"><clipPath id="p.0"><path d="m0 0l518.48816 0l0 375.7953l-518.48816 0l0 -375.7953z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l518.48816 0l0 375.7953l-518.48816 0z" fill-rule="evenodd"/><path fill="#ff0000" d="m5.7244096 82.03018l0 0c0 -38.381615 31.114447 -69.49606 69.49606 -69.49606l0 0c18.431503 0 36.108093 7.321886 49.141136 20.354925c13.033043 13.033039 20.354927 30.709637 20.354927 49.141136l0 0c0 38.381615 -31.114449 69.49606 -69.49606 69.49606l0 0c-38.38162 0 -69.49606 -31.114449 -69.49606 -69.49606z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m5.7244096 82.03018l0 0c0 -38.381615 31.114447 -69.49606 69.49606 -69.49606l0 0c18.431503 0 36.108093 7.321886 49.141136 20.354925c13.033043 13.033039 20.354927 30.709637 20.354927 49.141136l0 0c0 38.381615 -31.114449 69.49606 -69.49606 69.49606l0 0c-38.38162 0 -69.49606 -31.114449 -69.49606 -69.49606z" fill-rule="evenodd"/><path fill="#ff0000" d="m58.10828 71.03018l34.224384 0l0 22.400002l-34.224384 0l0 -22.400002z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m58.10828 72.06117l34.224384 0l0 21.452866l-34.224384 0l0 -21.452866z" fill-rule="nonzero"/><path fill="#000000" d="m59.57703 88.95018l0 -13.359375l5.921879 0q1.78125 0 2.703125 0.359375q0.9375 0.359375 1.484375 1.28125q0.5625 0.90625 0.5625 2.015625q0 1.40625 -0.921875 2.390625q-0.921875 0.96875 -2.84375 1.234375q0.703125 0.34375 1.078125 0.671875q0.765625 0.703125 1.453125 1.765625l2.328125 3.640625l-2.21875 0l-1.765625 -2.78125q-0.78125 -1.203125 -1.28125 -1.828125q-0.5 -0.640625 -0.90625 -0.890625q-0.390625 -0.265625 -0.796875 -0.359375q-0.296875 -0.078125 -0.9843788 -0.078125l-2.046875 0l0 5.9375l-1.765625 0zm1.765625 -7.453125l3.7968788 0q1.21875 0 1.890625 -0.25q0.6875 -0.265625 1.046875 -0.8125q0.359375 -0.546875 0.359375 -1.1875q0 -0.953125 -0.6875 -1.5625q-0.6875 -0.609375 -2.1875 -0.609375l-4.218754 0l0 4.421875zm18.09795 4.34375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm15.406967 5.765625l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125z" fill-rule="nonzero"/><path fill="#010000" fill-opacity="0.0" d="m92.332664 72.06117l0 0l0 21.452866l0 0l0 -21.452866z" fill-rule="nonzero"/><path fill="#00ff00" d="m373.77292 82.03018l0 0c0 -38.381615 31.11444 -69.49606 69.49606 -69.49606l0 0c18.431488 0 36.108093 7.321886 49.141144 20.354925c13.03302 13.033039 20.354889 30.709637 20.354889 49.141136l0 0c0 38.381615 -31.11441 69.49606 -69.49603 69.49606l0 0c-38.381622 0 -69.49606 -31.114449 -69.49606 -69.49606z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m373.77292 82.03018l0 0c0 -38.381615 31.11444 -69.49606 69.49606 -69.49606l0 0c18.431488 0 36.108093 7.321886 49.141144 20.354925c13.03302 13.033039 20.354889 30.709637 20.354889 49.141136l0 0c0 38.381615 -31.11441 69.49606 -69.49603 69.49606l0 0c-38.381622 0 -69.49606 -31.114449 -69.49606 -69.49606z" fill-rule="evenodd"/><path fill="#000000" d="m425.03085 83.715805l0 -1.578125l5.65625 0l0 4.953125q-1.296875 1.046875 -2.6875 1.578125q-1.375 0.515625 -2.84375 0.515625q-1.96875 0 -3.578125 -0.84375q-1.609375 -0.84375 -2.421875 -2.4375q-0.8125 -1.59375 -0.8125 -3.5625q0 -1.953125 0.8125 -3.640625q0.8125 -1.6875 2.34375 -2.5q1.53125 -0.828125 3.515625 -0.828125q1.453125 0 2.625 0.46875q1.171875 0.46875 1.828125 1.3125q0.671875 0.828125 1.015625 2.171875l-1.59375 0.4375q-0.296875 -1.015625 -0.75 -1.59375q-0.4375 -0.59375 -1.265625 -0.9375q-0.828125 -0.34375 -1.84375 -0.34375q-1.203125 0 -2.09375 0.375q-0.890625 0.359375 -1.4375 0.96875q-0.53125 0.59375 -0.828125 1.3125q-0.515625 1.234375 -0.515625 2.6875q0 1.78125 0.609375 2.984375q0.625 1.203125 1.796875 1.796875q1.171875 0.578125 2.5 0.578125q1.140625 0 2.234375 -0.4375q1.09375 -0.453125 1.65625 -0.953125l0 -2.484375l-3.921875 0zm8.042664 5.234375l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm12.853302 -3.109375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm15.766357 2.65625l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm9.141327 5.765625l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0z" fill-rule="nonzero"/><path fill="#4a86e8" d="m189.74866 293.76605l0 0c0 -38.381607 31.114456 -69.49606 69.49606 -69.49606l0 0c18.431519 0 36.108093 7.321884 49.141144 20.354935c13.033051 13.033035 20.35492 30.70964 20.35492 49.14113l0 0c0 38.381622 -31.11444 69.49606 -69.49606 69.49606l0 0c-38.381607 0 -69.49606 -31.11444 -69.49606 -69.49606z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m189.74866 293.76605l0 0c0 -38.381607 31.114456 -69.49606 69.49606 -69.49606l0 0c18.431519 0 36.108093 7.321884 49.141144 20.354935c13.033051 13.033035 20.35492 30.70964 20.35492 49.14113l0 0c0 38.381622 -31.11444 69.49606 -69.49606 69.49606l0 0c-38.381607 0 -69.49606 -31.11444 -69.49606 -69.49606z" fill-rule="evenodd"/><path fill="#000000" d="m225.45972 300.68607l0 -13.359375l5.921875 0q1.78125 0 2.703125 0.359375q0.9375 0.359375 1.484375 1.28125q0.5625 0.90625 0.5625 2.015625q0 1.40625 -0.921875 2.390625q-0.921875 0.96875 -2.84375 1.234375q0.703125 0.34375 1.078125 0.671875q0.765625 0.703125 1.453125 1.765625l2.328125 3.640625l-2.21875 0l-1.765625 -2.78125q-0.78125 -1.203125 -1.28125 -1.828125q-0.5 -0.640625 -0.90625 -0.890625q-0.390625 -0.265625 -0.796875 -0.359375q-0.296875 -0.078125 -0.984375 -0.078125l-2.046875 0l0 5.9375l-1.765625 0zm1.765625 -7.453125l3.796875 0q1.21875 0 1.890625 -0.25q0.6875 -0.265625 1.046875 -0.8125q0.359375 -0.546875 0.359375 -1.1875q0 -0.953125 -0.6875 -1.5625q-0.6875 -0.609375 -2.1875 -0.609375l-4.21875 0l0 4.421875zm18.097946 4.34375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm9.531967 5.765625l0 -8.40625l-1.453125 0l0 -1.265625l1.453125 0l0 -1.03125q0 -0.96875 0.171875 -1.453125q0.234375 -0.640625 0.828125 -1.03125q0.59375 -0.390625 1.671875 -0.390625q0.6875 0 1.53125 0.15625l-0.25 1.4375q-0.5 -0.09375 -0.953125 -0.09375q-0.75 0 -1.0625 0.328125q-0.3125 0.3125 -0.3125 1.1875l0 0.890625l1.890625 0l0 1.265625l-1.890625 0l0 8.40625l-1.625 0zm11.105194 -1.1875q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.5937653 0 -2.4531403 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875153 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.54689026 0.40625 -0.81251526 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.4531403 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.42189026 0.1875 -0.65626526 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.50001526 0.4375 1.4531403 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm10.516327 1.3125l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm6.59375 2.078125l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.9958191 -3.375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.281952 4.84375l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m144.71654 82.03018l229.07088 0" fill-rule="evenodd"/><path stroke="#000000" stroke-width="4.0" stroke-linejoin="round" stroke-linecap="butt" d="m144.71654 82.03018l205.07088 0" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="4.0" stroke-linecap="butt" d="m349.7874 88.637115l18.152374 -6.6069336l-18.152374 -6.606926z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m308.38586 244.62492l85.73227 -113.44882" fill-rule="evenodd"/><path stroke="#000000" stroke-width="4.0" stroke-linejoin="round" stroke-linecap="butt" d="m322.85553 225.47736l56.79297 -75.15369" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="4.0" stroke-linecap="butt" d="m317.5844 221.49402l-5.673004 18.465591l16.21521 -10.498932z" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="4.0" stroke-linecap="butt" d="m384.91962 154.30699l5.673004 -18.465576l-16.21524 10.498917z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m210.10359 244.62492l-85.73229 -113.44882" fill-rule="evenodd"/><path stroke="#000000" stroke-width="4.0" stroke-linejoin="round" stroke-linecap="butt" d="m210.10359 244.62492l-71.262634 -94.301254" fill-rule="evenodd"/><path fill="#000000" stroke="#000000" stroke-width="4.0" stroke-linecap="butt" d="m144.11206 146.34033l-16.215225 -10.498917l5.673004 18.465576z" fill-rule="evenodd"/></g></svg>
49 changes: 49 additions & 0 deletions source/standards/test-driven-development.html.md.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Test-driven development (TDD)
last_reviewed_on: 2024-10-21
review_in: 6 months
---
# <%= current_page.data.title %>

GDS advocates for agile software development practices because we believe that flexibility and responsiveness-to-change are key to building software that meets the needs of our users.

Test-driven development (TDD) is a core agile software development practice which aims to build flexibility and correctness into production software.

The process starts with a set of desired behaviours for a piece of code. This list could include happy-path behaviours, error cases, and interaction points with other components.

The inner-loop of TDD is also commonly referred to as "Red-Green-Refactor"; red to represent a failing test, green to represent all passing tests, and refactoring only when all tests are passing.

<%= partial 'partials/svg-tdd-red-green-refactor' %>

### Red (a failing test)
Turn exactly one item on the list into an actual, concrete, runnable test. This test should fail when you run it.

### Green (all tests passing)
Change the code to make all tests, including the new test, pass. If you discover that you are missing a behaviour or test, add them to the list


### Refactor (iterative and incremental design)

Improve the design and implementation of the code by removing duplication, utilising well known patterns and structures.

These steps are repeated until your set of behaviours is exhausted.

## Why we recommend it

The advantage of writing the tests before the implementation is that the behaviour of the code you will write is defined first, rather than implementing the change and retroactively applying tests.

A test-first approach gives you quick feedback on the design of your code - if you code is becoming difficult to test or has many dependencies, these are signals that you likely need to refactor.

> For each desired change, make the change easy (warning: this may be hard), then make the easy change - Kent Beck

Test-driven development naturally lends itself to our recommended approach to [breaking down work](/standards/breaking-down-work.html). If you are careful about introducing feature toggles so that code can be "dark launched" into production environments, test-driven development can give you a robust and reliable iterative workflow.

For example, if you are defining a new component, you could first define the interface, integrate a "do nothing" or noop version of that component into the live codebase, and then iterate on that implementation or another implementation safely.

## What if we can't do TDD?

The most valuable output of the TDD process is not the code itself but the tight feedback loops that allow you to reflect and the iterative design decisions that you make along the way.

If doing what Kent Beck calls [canon TDD][canon-tdd] is not possible, for whatever reason, that's okay as long as you have another mechanism for realising the fast feedback and incremental delivery advantages that TDD does provide.

[canon-tdd]: https://tidyfirst.substack.com/p/canon-tdd

0 comments on commit e32e1fe

Please sign in to comment.