loading...

What made you interested in learning how to write tests or how to TDD?

jooforja profile image João Forja 💭 ・1 min read

I got interested in learning how to TDD and how to write tests because I wanted to improve my overall skills as a developer.

I had this idea that there are too many technologies, and they change so fast that I can't learn all of them in-depth, so my countermeasure was to improve my testing skills. Tests will tell me if what I'm building is working or not. They will also give me feedback on the design of what I'm building. And all of this independently of the frameworks/tools I'm using. So even when I have to dig in a codebase that uses technologies that I'm not so familiar with, I'm always reasonably confident that by writing tests and by reading the technologies' documentation, that I can get productive pretty quickly.

What about you? What made you interested in learning how to write or learning how to TDD?

Discussion

markdown guide
 

I've fixed so many bugs in one single app that I was wondering how to avoid them as much as I could. Talking about this to a QA engineer (who's also a friend) she told me everything about unit testing and let me know that most of the bugs I fixed were preventable with it (and probably integration testing but I haven't reached that point yet 🐌).

It took me a while (like, 2 years) to actually start including unit tests in our development flow... convincing is hard but, hey we're now doing it! \o/ I'm still super newbie with it, I'm terrible at inventing test scenarios, but I'll get there! There's always areas of improvement c:

 

Congrats on convincing people to start doing unit tests! That's probably the toughest part of making the team adopt unit testing.

Regarding coming up with test scenarios, I find out that it becomes easier if I build my modules as units that have simple inputs and outputs. If I have a good grasp of the inputs, I can fiddle around with the possible values and define what the output should be. Of course, this approach implies that you'll need to organize the code to make it easy to test, which is good because code that's easy to test is code that's easy to understand. Hope this helps :)

 

aah thanks for the advice! much appreciated 💖 I'm also facing the problem that I don't really know exactly what to expect as an output because there aren't any requirements (sad I know), but maybe making the code much smaller than what we currently have might help. Thankies!! 😄

Unfortunately, that's common, and it tends to be one of the core issues behind not knowing what to test.

Making the code the code base as small as it can be without compromising readability is an excellent approach to keep code maintainable. I'd say that it's one of those practices that we should follow almost always :) But this approach won't fix the situation :/

Usually, when we don't know what to implement, we should ask management or someone who should know that. The real problem comes when management doesn't know what needs to be implemented because the client also doesn't know what needs to be implemented! It might seem that the client is at fault here, but actually, it's just the way these things work, and the sooner we accept that, the faster we can start working on a solution.

Most often, the client has a general idea of what the app needs to do for it to benefit the business, and it seems quite well thought out when he talks about it. But as we start to develop three issues become apparent:

  1. The client kind of knows what needs to happen, but he doesn't know HOW the app should make it happen.
  2. We find out that we didn't entirely understand what the client meant.
  3. The idea that the client had of what the app needs to do keeps changing. The longer it gets to release something that real users can use, the worse the three issues above will get, and ironically, the harder it will be to release something that real users can use. And this is because we lack feedback/guidance from the real world, so everyone involved in making the app (from clients to devs) will get stuck in their heads trying to guess what the app needs to do to be a success. But we are awful at guessing, and it's easy for this process to keep going on indefinitely and burn through all the project's budget.

One solution to this problem is to simplify an application to the point where we can sit down with the client and easily map what's on his mind into inputs and outputs. Or in other words, we can write acceptance tests for the app. So if a client wants an app with 50 features, we might start with a single feature, or with degenerates of 5 the 50 features that we can figure out with the client how they'll work. Which approach to take will depend on which one leads to the shortest route to deploy something for real users because the goal is to get stuff out there as soon as possible. The faster we deploy, the sooner the client gets money, the quicker we get out of our heads and get guidance from the real world, and the more likely the project is to succeed. Also, there isn't a better way that I know of, to make sure that we're on the same page as the client than to show him/her a working application. After we have something working, it doesn't matter how minimal it is, the conversations start to become a lot more specific and a lot more productive.

Well, I ended up writing a bit more than I was expecting. The essence of what I wanted to say is that not knowing what to expect as an output of a test, can be a sign that there's a problem with how the project is being managed and that it is urgent to reduce the scope of the next release to the point that we can clearly define the requirements. Otherwise, the project will likely fail.

I hope that my mumbling is useful in one way or another xD

aaah thankies!! I can't go into much details regarding the project but I'll definitely try to use your suggestions in order to help ease the unit testing process. I appreciate your input a lot \o/ (though I guess you could use this reply as a blog post wink wink)

haha thanks a lot for the suggestion. I think I'll follow it :D

 

Save time in debugging as I had to search for the problem one by one in my source code. Showing to people that what you wrote meets the quality of being fit to be in production. Without pulling your hairs out when it fails in production with a higher stake if it fails.

 

In my case, as I am new to programming, I started to contribute to an existing project and I realized that some of the changes I made were causing side effects and they had no tests to show that my contributions were working as expected and that the existing features continued to function properly. So, I realized that I needed to implement tests to be more confident, reduce the amount of bugs and at the same time have clear documentation of what the existing code should be doing.

 

It's awesome that you've reached that conclusion. Many people don't have those concerns and just go on and break things thinking that it's part of the job. I also believe that we can do better than that :)

Since you said that you're new to programming, I don't know if you're aware of the term legacy code or not, but what you're describing is part of the problems that we face when we work with legacy code. And in my opinion, working with legacy code is one of the hardest challenges of software development because we need to reverse engineer code into a design that allows us to test it. It's an entirely more complex scenario than writing tests from the get-go. So don't feel frustrated if you get to the point where you can consistently write tests for an app that's not yet written, but still find it hard to introduce tests to already existing projects :)

 

Yes, from what I have seen so far (which is not much), working with legacy code is more challenging but it is also much more likely than writing something from scratch or that already has well-established tests. But it’s good to know that even more experienced programmers also find this difficult, I’ll keep that in mind.

 

I started with TDD by the usual reasons: improve code quality, expand my horizons, try out new methodologies etc. But a huge thing for me that I had just realized is that TDD takes a lot of time to implement. And those minutes that I'm using writing tests are minutes I probably would've used to procrastinate if I'm not doing TDD.

TDD keeps me in check. It gives me structure and flow, which is invaluable for my productivity.

 

In a complex enough library, testing with edge cases is just inevitable, and has to be done every time you change the library code. Sometimes there are collaborators, and sometimes you just forgot how it works. This is just needed if you maintain the code long enough.

As you might forgot to test before publish or commit, automated testing, as well as Git hooks and CI are needed.

As UI / JavaScript is getting more complex. This is inevitable for the frontend too.

Pure functions (purely functional programming) and dependency inversions are also moving in this direction, testing for cases you cannot guess they will occur, in production; where you have to be responsible for everything, even wild cases.

I might not go as far as religiously test from day one with null hypothesis; but I don't really think it is that bad either.

 

My memory of this is very clear although it is now very much a distant memory:

I'd just joined a company that was "extremely" immersed in Extreme Programming. I needed to write my first every xUnit automated tests for my code submission and wrote my first test-driven tests on Day 1 of the job. I can still remember how I used to name my tests; "test1", "test2", etc. Thankfully, my testing skills have improved a little since then.

p.s I love your rationale of investing in testing skills to offset the risk of technology creep

 

I was interesting in TDD as it was becoming as buzzword. After learning how it worked, I lost interest as it really wasn't the magic solution some people claimed it was. I barely use it now.