Ask HN: What's the best way to learn about testing/TDD?
Hi, I am learning web development for the last 5 months (mostly Javascript). I am fairly good (for a junior dev) at the language and the technologies I focused (React), so I started to look for a job as junior web developer.
But I noticed that lack of knowledge and practice in testing is hurting my chances. I was assuming that it would be something I would better learn in practice as part of an experienced team in a professional environment and that it was ok for a junior dev not knowing much about it. I changed my mind, so...
What online resources are great as an introduction to testing?
48 comments
[ 3.0 ms ] story [ 85.7 ms ] thread[0] https://github.com/substack/tape
[0]: https://github.com/airbnb/enzyme
[1]: https://github.com/facebook/jest
Find someone to pair with, particularly someone who's done a bit of TDD before. It'll be a lot quicker to work through.
At some point, as another poster suggested, read some of the debate on TDD. But learn it first, and from those who have succeeded with it in a professional capacity--so you can be better educated about where its value lies. It's a valuable tool, but no tool solves all problems. (While I currently teach/pair with devs on TDD, I spent at least 5 years doing TDD on professional, "real" systems.)
There are tons of really good books out there on the subject from Packt too. React using Jest isn't super widely filmed, but has good docs. If you do become a master, create a video series and help the next guy out. =) Happy coding!
I'd like to practice writing tests but would prefer if they didn't go to waste, or at least added value to something else.
https://searchcode.com can be useful in helping find repos based on code criteria.
Were it me, I'd build something small and interesting to me, write some unit tests against it after-the-fact. Then I'd do it again, using TDD the 2nd time to see how the approaches differed.
What automated tests do, though, is make it significantly easier to test. You will find bugs faster, and dramatically shorten the amount of manual testing that you need to do.
IMO, the best way to learn TDD is via experience. You need to work with a team that's willing to support a junior engineer. From a senior engineer's perspective, the amount of handholding that some junior developers need through writing decent unit tests is quite time consuming.
Thus, if I were you, I'd just be selective about who I work for. I'd look for a team that's willing to be patient while I learn, and that has enough senior developers that I can learn by following a good example. A team that wants a lot of experience in this or that is probably not able to allow you the time needed to learn.
A good approach to avoiding this situation is, what is that manual test you do to make sure stuff works? automated it.
Ask questions about their testing approach. Remember, no company is perfect. Often, small startups decide it's in their best interest to rely on manual testing and accept that their products are buggy. This can be an opportunity if you're able to clean things up, though.
If a company is honest, and takes the time to answer your questions, then it's probably a good sign. If the company thinks you should be grateful for a job and grovel for whatever crumbs they drop, RUN!
Remember, though, no company is perfect. It's better to work for a company that has an imperfect TDD then one that treats you like dirt.
Example. Last year I consulted at an IC company, building a huge "moon-shot" chip. You might expect TDD to be an absolute certainty in such an operation. Not so, individuals had all sorts of justifications for not doing TDD.
Here is one idea. In the technical interviews, when the inevitable "and do you have any questions for me?" moment comes up, ask them to talk about their best test.
If they have a good answer, it's likely you've found somewhere that genuinely values TDD.
I love it when people ask me about how we test. I can tell you the pains we've had with tying our tests too tightly with implementation. :D
Doesn't this show that either your test case is not product requirements based or the design is not aligned with the product requirements?
Trying to keep pace with most markets, it's hard for software developers to maintain detailed enough requirements to even hope to ever achieve exhaustive automated testing.
What is it that you're testing manually that you can't automate?
That said, bug-driven testing is a separate issue from TDD.
"What is it that you're testing manually that you can't automate?" I can't automate what I can't predict.
Simple example: Would you get in a robotic car that only had automated testing? What about a robotic flying car?
Real example: 20 years ago, I bought a modem that had an "obvious" problem when calling a dial-up BBS. It didn't flush the buffer appropriately, leaving me with an incomplete screen of text.
I'm sure the modem passed all of their automated tests! But, did whoever wrote the automated tests predict that the buffer should flush if no data came within a very small amount of time? Nope!
Another example: Have you recently used Netflix on Android with Chromecast? It breaks in a lot of corner cases when you put your phone in your pocket. Netflix proudly laid off their manual testers and only does automated testing. Can you really automate every aspect of the Chromecast in a test harness? I bet you can come close, but not achieve 100%.
They also are code and therefore may contain bugs, impose additional maintenance overhead, and have all the other pros and cons that code has.
Also, it's possible to over-test in the same way it's possible to overengineer.
The authors have recorded lectures too https://cs.gmu.edu/~offutt/softwaretest/videos/ plus open course slides and assignments http://cs.gmu.edu/~offutt/classes/737/schedule.html
I'm in the process of writing a course about JavaScript testing so it's good timing. I write a lot of unit and integration tests for our large codebase here at the BBC in the UK. We've got 3 Node + Express applications plus React for the UI for the 2 user facing applications. The other one is an API but it's got solid tests as it has does some complicated logic for redirecting users and updating sessions and tokens.
I'd love to get you on the mailing list for when I launch it and then you can fire me some questions via email. I'd love to help you get that job!
http://www.marclittlemore.com/courses/javascript-testing-mad...
Cheers, Marc
I worked in the videogames industry for nearly 20 years and they didn't do much unit/integration testing but I've immersed myself in learning about testing JS for the past 4 years since I switched industries. Hardest thing is knowing what to test I always found.
I'm happy to do some 1-on-1 with you to help.
https://medium.com/powtoon-engineering/a-complete-guide-to-t...
TDD is all the hype these days, but there are some who are very skeptical about it. For a good discussion, see this: https://www.infoq.com/interviews/coplien-martin-tdd
Since you are junior all this won't probably matter all that much to you - just wanted to make sure you don't put an = sign between these two terms accidentally.
That being said, I really like my automated tests.
Another thing I'll do a lot of times when I'm trying to figure out how to test a weird situation is try to think of another API that works similarly and look to see if it has any tests that are instructive. And I habitually go through OSS projects I use to look at their tests and see what techniques I might not know about. This is really useful when you're picking up a new language or paradigm (e.g. when I started using functional languages over the OO languages I was used to.)
The basic thing you need to remember about testing is the AAA approach[2]: Arrange (setup); Act(do the thing you're testing); Assert (measure the outcome to make sure it is what you were expecting). Just about everything you read on testing at a lower level is going to come down to that procedure. There's additional techniques like fuzz testing and property testing, but they're not common. At a junior level I'd just expect you to have a basic understanding of AAA and how to apply it to common situations with the toolkit of your choice (e.g. for a javascript dev, maybe jest).
When you think about it, you already test your software, as you write it—its just that instead of writing down the steps in a way that your test framework can use, you're doing it manually. So really you just need to learn how to write down what you're doing in the browser (or whatever your interface is). Further refinement of that process is to use break your software up into pieces that can be more easily tested on their own.
I really just meant to post the first link, but testing is one of those areas that's near and dear to my heart, so my apologies for the rambling :)
[1] https://www.amazon.com/Working-Effectively-Unit-Tests-Fields...
[2] http://wiki.c2.com/?ArrangeActAssert
Your comment was very useful in itself aside from the link. Thanks!
(I got to tell him this anecdote about a year ago. He was amused).
Much later I joined Pivotal Labs, hoping to see what the fuss was about, and got taught TDD by sitting next to people who are good at it. People who will go to enormous lengths to create automated testing from the outside in. It felt uncomfortable and unnatural at first. But now it seems obvious.
My advice is: seek out a mentor. Anyone who can sit with you for a few hours.
I love TDD because it makes me feel more comfortable as a programmer. The cycle of "write a test, test fails, write code, test passes, write another test" helps keep me centered. I know what I'm supposed to be doing at that moment, and don't get lost.
I don't think I write faster, and I may not write more bug-free. But I sure feel better with TDD.
False sense of achievement maybe ? You write more code, because you also simultaneously write tests. But, have you ever noticed that, while your tests are great, your design sucks ? To me TDD is more a distraction than a tool for helping me think first before coding. I see tests only as a mandatory bureaucratic paperwork that needs to be done at the end of design process. Don't get me wrong, I think tests are a must, but only for ONE reason, to prevent software regressions. TDD for me is very pointless if not a dangerous practice.
I actually find TDD helps me design components with fewer responsibilities, almost always as a result of realizing the complexity via writing permutations of test cases. It helps me think about 'what each thing should do' because I don't have that innate ability like some folks.
It is especially helpful in pointing out cases where adding a layer of abstraction or introducing subclass variants are beneficial.
Heck, even before coding, I like using Cucumber as a form to think about code behavior and responsibilities. I don't really enjoy fully automated Cucumber in practice, but the format is terrific.
If all you see tests for is "mandatory bureaucratic paperwork", maybe you should be concerned about overconfidence in your ability to do flawless design and implementation. Writing tests is one of the best tools I've found for making sure I actually understand what it is I'm trying to do (and if what I'm trying to do is actually wrong).
>> If all you see tests for is "mandatory bureaucratic paperwork", maybe you should be concerned about overconfidence in your ability to do flawless design and implementation.
I don't buy into the idea that TDD or any kind of testing methodollogy gives you confidence to do good design or in any way helps you make good design decisions.
>> When I do TDD, I have demonstrably working code. What doesn't give me a sense of achievement is writing a ton of code with no evidence that it works or is bug-free
False sense of program correctness right there ;) Are you telling me that by doing example based testing, you are 100% bug free ? Your tests must be humongous.
>> Writing tests is one of the best tools I've found for making sure I actually understand what it is I'm trying to do (and if what I'm trying to do is actually wrong).
Pen and paper for some and more code for others.
Then listen to them.