TDD action list and gaps in knowledge
12 Nov 2019
I have been changing my approach to reading technical books lately, with a focus on addressing gaps in knowledge, and it has been helping massively. Will share a bit of the process here.
I have been reading Kent Beck's Test Driven Development for some time now, playing with the ideas and generally doing my best to grasp and apply the concepts.
This time, I read one of the chapters and took some notes as I usually do. This time paying attention to ideas and concepts that I could turn into an action plan.
Once I had the notes, I wrote them up as an actual step-by-step action list which covers the process mentioned in the book. It took a lot of mental energy to do this. I had to really think about what counted as a step, and also found myself trying to skip over parts that I wasn't fully familiar or comfortable with yet.
Whilst creating this action list, I also created a list of questions I had and gaps in knowledge (things that I kept trying to skip over and ignore).
After creating this list, I focused on the gaps in knowledge. First, I rated them in terms of how difficult I think it will be for me to fill in those gaps in knowledge. I can consider whether that estimate was accurate afterwards.
Then I ordered the gaps in knowledge into what I consider to be the most important ones to focus on first.
Finally, I brainstormed ideas for things I can do to start filling in those gaps in knowledge. Whilst learning the things I need to to fill in those gaps, then I'll likely end up repeating this entire process for each of the sub-steps.
TDD Action List
- What are the stories you want to be able to tell about your system?
- What functionality do you want to test? (Assertions come next).
- Write a list of tests you know you will have to write.
- Put on the list examples of every operation you know you will need to implement.
- For the operations that don't already exist, put the null version of that operation on the list.
- List all of the refactorings that you think you will have to do in order to have clean code at the end of this session.
- Have a test list which expresses the things you intend to accomplish over the next couple of hours.
- Have a similar list pinned to you wall with a weekly or montly scope.
- Write your tests before writing any code.
- Write your asserts first before writing the rest of your test.
- Where does the functionality belong? Same class, somewhere else?
- What should the names be called?
- Expected input and output.
- Will we be testing multiple inputs in our real system? Do our tests need to reflect that?
- What other tests does this test suggest?
- As you make the tests run, new tests will be implied, write the new tests down, do the same for any new refactorings.
- Items left on the list when the session is done need to be taken care of. Do they stay on the current list or do they need to go on a later list?
- If I ignore all tests and run a couple of random tests at a time, will they still pass? (Not dependent on other tests).
Questions/gaps in knowledge
- Gap: Stories you want to be able to tell about the system.
- Gap: Identifying functionality (behaviour)
- Question: How do other people approach writing their test lists?
- Gap: Listing all the refactorings you think you'll have to do in order to have clean code.
- Question: How to break your problems into little orthogonal dimensions for isolated tests.
- Question: How to compose solutions out of highly cohesive, loosely coupled objects.
Plan for addressing gaps in knowledge
Now that we have the gaps in knowledge that we want to address, it's important to do two things. First, brainstorm some ideas for how you might go about addressing those gaps in knowledge. Then create a set of macro and micro goals for yourself. The micro goals are more important. They should be things that you can mark as done within just a couple of hours.
Now that we have the gaps in knowledge that we want to address, it's time to create a realistic and manageble action plan. This is a three step process. Brainstorming, goals, assimilation.
Brainstorm solutions for addressing gaps in knowledge
The first thing we do is brainstorm our ideas for how we might go about filling in our gaps in knowledge.
We also need to go one step further in this step, and make any resources that we list easy to access. Our aim is to make our future lives easier, by reducing cognitive load wherever possible. That way if you want to dive into one of these resources, you won't be put off by having to make the effort of finding them. I'd wait until ordering books and courses until you have completed the goals step, so that you know whether you really need them or not.
It took a surprising amount of energy to do this, and it would have made it a lot harder to get started if I had to do the research at the same time that I wanted to spend learning and doing.
- User Stories - Mike Cohn article.
- User Stories - Mike Cohn video.
- User Stories - Mike Cohn - 200 user story examples.
- User Stories Applied: For Agile Software Development - Book by Mike Cohn
- Whole Stories for Whole Teams - Article by Industrial logic.
- UserStory - Article by Martin Fowler
- The card is not the User Story - Article by Andy Palmer and Antony Marcano
- It starts with a story - Article by Antony Marcano
- Apples, oranges and user stories - Article by Antony Marcano
I struggled to find resources that could help me with the process of breaking down user stories into functionality that we can then start test-driving. So I decided to tweet out my question, tagging Kent Beck (The author of TDD). The question is as follows:
Reading @KentBeck 's TDD book and would really appreciate help. In the book, it mentions starting with stories,then the functionality you want to test. My question: How can you work with users to identify functionality from user stories (if they are conversation placeholders)?
I don't know if that was a clear enough question, but will see if there are any responses and if it needs any further clarification.
Oh woww, got some AMAZING responses to that question that really helped. Here is a link to the original question and thread. I'll include the replies anonymously below though.
The stories are about describing the problem (from a standpoint of having solved it), the functionality is a way to get to that outcome. E.g. Remember when we had trouble with that dragon terrorising the village. It's so nice and peaceful now (problem/outcome)
"Yes, and all it required was our finest warrior and our finest blacksmith to create a sharp, pointy thing" (functionality/solution 1) "Yes, and who'd have thought he was just acting out because he needed a chat" (functionality/solution 2)
Remember when we had to log all the temperatures with pen and paper? It took hours and was so boring Yes, and all it took was reading the regulations to realise that that wasn't even necessary Yes, and now we have a shiny device that logs it all for us automatically
Not sure I understand your question exactly. Are you asking something like, "How do I learn about the story interspersed with building it using TDD?" Or am I way off?
For your test list gap one thing I find helpful for a lot of people is this article, TDD guided by Zombies. In a way the test list is just a checklist of things to accomplish expressed as testable conditions.
Thank you for elaborating. The classic XP way to do this is to ask the user to elaborate a bit on the story until you can create something small and ask the question, "Is this what you had in mind? Is it moving towards telling the story?". 1/3
The thing you create could be a sketch or it could be code but it should be fairly quick. Then if the answer is No, you ask why and then repeat. If it is yes then either the next step is fairly obvious or you ask what is missing. Then you do that over and over. 2/3
I tend to think of TDD as something you do with in the context of each of these small iterations. I will think some more about it and see if I have better answers tomorrow. Hopefully some of this is helpful. I will take another look at your list of gaps tomorrow if you want. 3/3
Writing Test Lists
- In the beginning, there was no code - Article by James Grenning.
- TDD ignores the design, yes it does, no it doesn't - Article by James Grenning.
- Legacy Code Changes, a boy scout adds tests - Article by James Grenning.
- Refactoring, Book by Martin Fowler
Loosely Coupled, highly cohesive
- I could try and build out a couple of Mike Cohn's user stories using the TDD style approach.
- I could reach out to Mike Cohn and ask for feedback about my own user stories.
Macro and Micro goals
I was thinking the other day about goals I have in mind when it comes to programming. My goals have been along the lines of "Learn Test-Driven Development", or "Learn Object-oriented programming". The problem with these goals is they are not specific enough to be useful. How exactly will I know that I have 'acheived' them, especially as these are lifelong skills that are going to grow and adapt along with my knowledge and experience.
So, I needed to find a way to turn my fuzzy goals into measurable, acheivable outcomes. There are a few ways you can do this. You can set SMART goals. You could focus on process-based goals, which are essentially habitual practices you consistently do, which should allow you to hit goals by default, instead of actively working towards them. Both are great choices, but in this case I'll show you the goal setting approach I'm using right now (it could change next week).
First thing to note. When I set a macro or micro goal, I don't follow through until that goal is met. They are not resolutions or targets that must be met. Instead, they are compasses.
A compass usually contains a small magnetic pin, which is suspended so that it can spin freely inside of its casing and respond to the planets magetism. Its purpose is to provide explorers a constant sense of direction.
I wrote a fictiony story to explain the compass part just for fun. The key point here is that the compass helps you know which direction to start walking, but the exact path you take to get there will vary.
It was more beautiful than I could have imagined.
In our village we have a tradition.
On the 16th day of summer during our 17th year, we are each given a tiny package wrapped in a single, shining sycamore leaf - mottled green and yellow.
The leaves had slowly unfurled themselves in my cupped hands, revealing what appeared to be a tiny copper compass. I noticed that its edges were worn smooth as if handled by a thousand people, even though I knew it had never before been handled.
As you would expect, the compass contained a small magnetic pin which span freely inside of its casing. In non-magical compasses, this pin would respond to the planet's magnetic fields, providing explorers with a constant sense of direction.
This compass was a little different. Without being told, I knew exactly what to do. Carefully, and admittedly a little shakily, I opened the glass casing. Curiously, my fingers left no prints. I watched as the small pin rose gently until it hovered above it's casing. Spinning gently in no particular direction.
After a little while, the pin dipped twice as if it was prompting me to look down. My breath caught as I saw what looked to be trapped sunlight shining from a shallow pocket right where the pin was resting. There were dust motes dancing in the light, except that the dust motes were actually particles of unformed promises.
So I told it my biggest dream, and watched as the particles formed into a question mark. It took me weeks to realise that the question mark was a simple question. Why?
In this time, I was alone with my thoughts, observing the currents of my emotions, cautiously following their threads until a definitive point where all of the currents became one. The force of it so powerful that my ability to speak was gone. I had found my why, and the compass responded.
The questionmark grew brighter until the light was blinding. There were flashes of purple and black and gold and silver, for this why was woven in threads of pain and joy. Then suddenly the light collapsed in on itself until a tiny sparkling gem remained.
Slowly, the gem lowered itself through the dappled summer air until it very gently touched the surface of the magnetic pin and clicked in place. This process repeated itself until the pin clicked into the compass and the glass resealed itself. The pin stationary, pointing forwards.
I knew that I would now return to the village, the same but qualitatively different. I knew that the younger ones would wonder what happened to me, why my footsteps were slightly firmer, why my gaze seemed older yet more free than it was in just a few short weeks.
Never noticing the tiny, circular shape pressing against the inner lining of my breast pocket, home to my True North.