Pages

Thursday, February 15, 2024

Don't know where to start on TDD?


This post got me thinking about how difficult it can be for people new to Test Driven Development to know where to start. I started writing this post as a reply to the post, but I ended up 29 characters beyond the limit, so here it is:


You might start by coming up with an example of what you want your code to do, what its behavior should be. Here's an example:

"When I give [specific complex input] I will get [specific output]"

Then imagine this example sequence of test-writing:

1. a test that asserts that I can call newCode
2. a test that asserts that calling newCode returns nothing
3. a test that asserts that calling newCode with any argument returns nothing
4. a test that asserts that calling newCode with any argument returns six (or some other dummy result)
5. a test that asserts that calling newCode with simplest argument returns the correct result
6. a test that asserts that calling newCode with more complex argument returns correct result

Each test should fail when you first write it. Then you add implementation to newCode to make only that test pass. Don't add code to make future tests pass - remember, small steps. As you write implementations for subsequent tests, 1-4 will fail (maybe even to the point of not compiling). That's expected. Delete any test that is superseded by one that moves you closer to your goal.

You might not get to 6 with the same steps as me, or you might gain enough TDD experience to start at 2 or 3 or 4 instead of 1. But hopefully this example shows a means of tests "driving" behavior.


Friday, September 1, 2023

"Don't Make Me Think" about your code.

Sometime after 2008 or so, I started telling software crafters that I was coaching that I have a guideline for code quality: “Don’t make me think.” Often I used the phrase to reference one of the many well-known code smells. Recently, I wondered where I first learned that expression. Unfortunately, online searches are dominated by Steve Krug's 2000 UI/UX book (with editions in 2005 and 2013) by the same name.The earliest use that I could find of “Don’t make me think” as applied to code quality is a blog post from 2011, If you know of an earlier use, please get in touch.

As I thought more about "Don't make me think", I've come up with many examples. Here's my list so far. What's your favorite?

  1. Have a readme that tells me how to run tests and install and run your application
  2. Use a test naming convention that gives the action, initial state, and expected state.
  3. Name things well
  4. When possible, use the names that are the same as in the business domain
  5. No commented-out code
  6. No comments, except to explain something that you have to do in an unexpected way (Debunk “good” comments)
  7. Unless you squash, have meaningful commit messages. If you squash, have meaningful merge messages.
  8. Write short methods
  9. Write with idiomatic use of your language
  10. Don’t write “clever” code
  11. Don’t over architect or over generalize
  12. Have sufficient types and amounts of automated tests
  13. Maintain your tests as you maintain the rest of your code
  14. Methods should have few arguments, and probably no boolean arguments.
  15. The interface of a class should “hang together” without methods that “don’t belong”
  16. Avoid “primitive obsession”
  17. Find solutions besides switch statements
  18. Don’t go crazy with inheritance. Prefer composition.
  19. Use a rich domain model, not an anemic one.
  20. Avoid conditional nesting
  21. Avoid subclassing unless you need all (or most) of the parent class (avoid Refused Bequest)
  22. Declare things where they are used.
  23. Arrange Act Assert
  24. One assert/concept per test
  25. Avoid double negation
  26. Use a Formatting Convention
  27. Short feedback cycles
  28. Don’t mix levels of abstraction