An Ode to Testability, Part 7

We made it! The final post in the testability series. Here we bring the Benchmarker application to a reasonable close. Then we’ll take a bit of time to briefly cover the journey we’ve taken together here.

Our design pressure has led us to this point: delivering the value that we started off articulating in the first post. Specifically, organizations funding an archaeological dig site want to know if the team associated with the dig is going to finish it on schedule or not.

Through these posts we put a lot of tests and code in place. Here we’re going to finish up our dig_site_spec.rb by adding a few more tests to the the “pace” block.

Evolving the Code: Schedule

So what do we need to do here? Well, we only really have two options: the dig is either on schedule or it’s not. Keep in mind the context we have for our “pace” block and the tests within it. This is what we ended up with:

In the previous post we calculated how many days remaining there were (75.6, as it turns out) given the data here, which is indicating the rate of activities being finished. So let’s add a test to check if we’re on schedule. As in the previous posts, I’ll show the test first and then we’ll look at the full spec file:

Make sure it’s clear why this test is structured as it is. Clearly two weeks from now is well under 75.6 days from now, which was the projected time. So this dig is definitely not on time in terms of schedule.

To get this test to pass, the DigSite (dig_site.rb) needs to be modified a bit:

Let’s put in place the other test that we know we need:

And that passes. And that’s to be expected: our dig is projected to take 75.6 days, which is about 2.3 months. So if the ideal finish date is 3 months from now, then the dig is on time.

So here’s what the full test spec looks like now:

And that’s it for the code! Note that the final version of the project is available at the Benchmarker repo.

I think that brings us to the end of our code and immediate project, folks! Clearly there is some refactoring that could be done with the production code. And as we’ve gone through these posts, I’ve pointed out areas where our test code may not be ideal. I’ll leave those as thoughts and exercises for you to contemplate on your own.

So let’s close out this series by doing a bit of a summary of all this.

Was This Series Even Relevant to Testers?

I can see someone asking that, feeling that perhaps with so much code in the posts, perhaps this was more of a developer exercise.

I would suggest that testers do need to practice their skills at building solutions, even if only simple ones. By building solutions you start to understand the challenges of design. And then how to put pressure on design, which is what testing does. And you also start to learn how mistakes happen, when they are likely to happen, how they magnify as your code base grows, and so forth.

That’s what I hope this series did.

By going through this process, you also start to learn the sensitivities of various technologies, particularly when various technologies are layered on top of each other. That’s not something I covered here but in the context of Benchmarker, you can imagine this scenario by thinking about adding an API to it, and then a web front-end using perhaps Angular or React. And then having a database to store everything.

Working through actual implementations like we did here — and building your own, even if only as practice — encourages testers to think about how testability should be a primary quality attribute when building complex things. But to see that, and to truly understand it, you have to be able to build something on your own so that you can feel it.

Shifting the Vocabulary of Testing

What we looked at in this series of posts is essentially a very simplified, but accurate, view of “how the product is designed and works.” Along the way, we were able to think about external qualities and internal qualities. Testers need to be concerned with both, just as do developers. This is vocabulary that we need to get more testers speaking about.

Another vocabulary shift is that testers need to keep emphasizing something good developers already know: testing puts pressure on design. It does so at numerous abstraction levels, from the human on down to the deepest levels of the tech stack. It is critical to have a facility to move between those abstraction layers. This series of posts were able to actualize the philosophical point I was making in the shifting polarities of testing.

Another vocabulary shift that I believe needs to be emphasized more is that all of this means testing has to be framed (at minimum) as two types of activity: as a design activity and an execution activity. And those two activities can and should be interleaved.

The Value of Testers

So what we end up with is test design and test execution going on at multiple levels of abstraction, investigating external and internal qualities.

Speaking to my tester readers, you being aware of all that can be eye-opening to many decision-makers. This gets into another part of what testing is: it’s a framing activity. It helps frames discussions and thus helps enable rational decision-making under uncertainty.

Ultimately that’s what testing (as a discipline) and specialist testers (as domain experts in that discipline) are focusing on: how we help people make better decisions sooner. Doing so requires that we are reasoning about a manageable amount of scope. “Manageable,” in part, being defined by how hard it is to have a shared understanding of what quality means (how the product adds value) in the limits of that scope.

Finally, what we end up with here is a focus on a delivery team where — ideally — everyone is considered a type of developer. What matters is that all members of the team work to understand what users need to be successful. Focusing on finding the simplest solutions that provide the right amount of value, consistent with our knowledge of what that value actually is. Everyone on the team is responsible for turning the functionality needed by the users into software that provides value.

You Made It!

I hope this series was informative for you. This was, in many ways, really hard to put together. I’m thankful for the “Gatherer” project from the book Rails 5 Test Prescriptions which helped me consider a contrived example as well as well the book Developer Testing for providing the impetus to show how “developer testing” is extremely relevant to testers, not just (programmatic) developers.

I tried to show a lot in as little space as possible, consistent with recognizing that people’s time is valuable and you have a lot of choices of what to read out there. My hope is that this series is able to appeal to developers and testers — keeping in mind I believe testers should be a type of developer — and that you can use some of the ideas here for discussion on your own teams, either to agree with what I said, disagree with what I said, or find yourself somewhere in the middle and then, hopefully, carrying forward the discussion.

We need more of this in our industry. I want to encourage those who are better than me at presenting all this to do so. Only by doing this, by putting ourselves out there, will we reclaim our discipline from the professional consultants (who turn testing into a semantic problem), the technocrats (who turn testing into a programming problem), and various so-called “QA Managers” (who turn testing into nothing more than a clerical problem).

I hope you enjoyed this series and I appreciate you coming along for the ride.

Share

About Jeff Nyman

Anything I put here is an approximation of the truth. You're getting a particular view of myself ... and it's the view I'm choosing to present to you. If you've never met me before in person, please realize I'm not the same in person as I am in writing. That's because I can only put part of myself down into words. If you have met me before in person then I'd ask you to consider that the view you've formed that way and the view you come to by reading what I say here may, in fact, both be true. I'd advise that you not automatically discard either viewpoint when they conflict or accept either as truth when they agree.
This entry was posted in Testability. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.