Testing is Not for Beginners

joncalhoun

Jon Calhoun

Posted on March 13, 2019

Testing is Not for Beginners

I'm a big fan of testing. I write about it on my blog, I email my mailing list about it, I discuss it with other developers in my spare time, and I have even gone as far as creating a course that teaches testing with Go.

Despite having a fondness for testing, I don't recommend it for beginners.

Crazy, right? In this article I plan to explore why that is in a little more detail, but it basically boils down to two points:

  1. Beginners don't know enough to write anything but the most trivial tests. This inevitably leads to my second point...
  2. Trying to learn the skills required to actually write realistic tests while also trying to learn how to code and build things is overwhelming.

I guess it is kinda one point. Whatever. I'm breaking it up into two because I think it makes it a little easier to consume.

I know many of you may not agree with me at this point, but please give the article an honest read. If after reading it all you don't agree I'm happy to discuss it with you. After all, I'm here to learn as well 🙃

This article was original posted on calhoun.io, where I write about Go, web dev, testing, and more.

Beginners don't know enough to write anything but the most trivial of tests

Whenever a beginner writes code their primary goal isn't to separate concerns, avoid global variables, or to write testable code. Honestly, most beginners probably don't know what half of those things really mean. Instead, their primary goal is simple; it is to get the damn thing to work. That's it.

Confirming this hardly takes any effort. Take some time to review some code written by beginners.

Looking at a web app written in Go? Chances are they are writing SQL queries anywhere and everywhere in that code, and theres a pretty good chance that their DB connection is a global variable.

Looking at a Rails app? Chances are there is business logic in the views and the controllers have tons of logic jam packed into them.

Looking at a PHP web app? It wouldn't shock me if ALL of the logic is in a single php file - parsing a form, interacting with the DB, etc.

Even if we look at something simpler - say a calculator with limited functionality - we are still going to run into issues like this. It isn't that beginners don't care; they simply don't know any better.

Beginners don't know what dependency injection is. They don't understand how global variables make testing hard. They probably don't even know what mocking is, so expecting them to understand how to design code that is easily mocked is quite the stretch.

As a result, the only tests that really make sense to a beginner are the really simple ones like below.

func Add(a, b int) int {
  return a+b
}

// And a test...
func TestAdd(t *testing.T) {
  got := Add(2, 4)
  want := 6
  if got != want {
    t.Errorf("Add() = %d; want %d", got, want)
  }
}

While I don't have any problem with showing this to a beginner and giving them an idea of what testing is, I think it is pretty ridiculous to show them this code and pretend that it is anything like a real test.

So what ultimately ends up happening is we try to teach them more. We try to teach them what dependency injection is, why global variables make it hard to test, how time.Now() can make it hard to verify edge cases, and more. And this is where I start to get worried, because we are no longer teaching a beginner how to program. At this point, we are teaching them how to program, how to build things, AND HOW TO TEST all at the same time. And that brings me to my second point...

Trying to learn the skills required to actually write realistic tests while also trying to learn how to code and build things is overwhelming

Like before, I want you to think about code written by a beginner, but this time I want you to recall some of the first programs you wrote. Think about the first thing you made that was composed of more than one source file. Or maybe think about the first web page you made.

Now if you were anything like me, your first web app might have looked something like this:

<p>
  <?php
  // This may not work. I don't know PHP anymore.
  $name = $_GET['name'];
  echo "Hello, " . $name;
  ?>
</p>

A work of art, isn't it?

Now imagine if you just managed to write that code for the first time and someone told you that you should be testing your code. And you should be using React. And you should be using a framework. Oh and you will want to setup a database, and probably setup GraphQL to query it.

I'm not sure why, but as developers we have this habit of taking what we do now - after years of experience and practice - and expecting others, especially beginners, to be doing the same things right away. It is ridiculous. It is like expecting someone to be able to jump right into calculus just because we learned trig, algebra, and more which eventually lead to us learning and using calculus to solve a particular problem.

Just because something works well for you, doesn't mean it is a good idea for beginners. They might not have the context, the experience, or the practice required to really benefit from what you are using. Or maybe the problems they are tackling are just much simpler, and tossing in all that complexity is overkill.

It's like we all forgot that we gradually learned how HTTP request work. How headers work. How cookies work. How forms work. How POSTing to a web server works - or even that there ARE different HTTP methods. And through all of this we probably learned through some good old fashioned trial-and-error.

I don't actually think testing is at fault here, but the real problem is that we have this stigma that you should learn how to code, testing, web development, and a million other things all at the same time. I don't really know how this came to be, but I suspect part of the issue is that we never qualify things. A beginner asks, "what should I learn?" and we tell them, "learn testing, and react, and graphql, and go, but only use the standard library..."

No, no, no! Just stop.

I just want it to stop

This is ridiculous to me because of how obvious it is in any other scenario. If you were teaching someone how to play soccer you would start off with the basics like how to pass and how to dribble. You wouldn't start them off with videos of Ronaldo and say, "This is how the professionals do it." So why the hell are we doing this with programming beginners?

We try to make it better by saying, "well of course they should know not to try to learn that all at once", but they don't! And what makes this even worse is that when budding developers fall into this trap it leads to them feeling like shit the minute they get stuck. They feel like they just don't have what it takes to be a developer, and it is a shame because many of them would love programming if they didn't slam into this brick wall.

And that brings me to my real point - most of us learn better if we focus on learning a few things at a time. We want to be challenged, to try new things, but we don't want to be so overwhelmed that we are paralyzed. Trying to learn testing plus everything else - like how to build a web app, how http works, how cookies work, etc - is an easy way to get overwhelmed. As a result, I usually recommend learning other things first, then coming back and learning testing later. You can always revisit your old projects and see how you would redesign it to apply what you are learning about testing, but that is only possible if you don't get overwhelmed, get frustrated, and eventually quit.

But what if I want to learn testing?! (and the million other "what ifs")

Cool, go for it! You are more than welcome to learn testing first, and then learn about web dev or any other topic. I'm sure some people have done this, and you might enjoy it. When I say testing isn't for beginners, I'm not saying it is an awful topic to learn. What I'm saying is that trying to learn testing plus everything else is a mistake.

Most people want to learn how to build web apps or something visual first, but that doesn't mean you have to start there. You can probably learn testing first. Some of it might not make quite as much sense without first experiencing the pains, but by all means don't let me stop you from learning what you want to learn.

This also doesn't mean you can't learn while pair programming or anything like that. When in environments with a mentor you can often learn a lot despite being overwhelmed because you have someone there to guide you through it all. When you get lost you aren't just stuck, and you don't feel like a failure. Someone is around to tell you, "You are doing great, this is just a ton to take in. Try X and Y instead next time!" In short, getting overwhelmed, then stuck, and finally quitting isn't as much of a concern in these scenarios.

Pssstt...

Interested in learning or practicing Go? Check out my FREE course - Gophercises - Programming Exercises for Budding Gophers.

I also have some premium courses that cover Web Dev with Go and Testing with Go that you can check out as well.

💖 💪 🙅 🚩
joncalhoun
Jon Calhoun

Posted on March 13, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related