7 ms·
This may sound weird, but I've written code professionally for 25+ years and I have never written a unit test, I'm not even sure what a "unit test" is or would
by noduerme 4y ago
This may sound weird, but I've written code professionally for 25+ years and I have never written a unit test, I'm not even sure what a "unit test" is or would look like in the context of what I write.
My job is to first consider a dozen ways a new feature might be used; then consider how it could be misused; then write a backend portion and UI for it, testing it for usability and potential for error along the way, using everything I've already thought could go wrong; then monitor it once it's deployed to see if anything actually does go wrong. After actually testing it through everything I can think of by hand, function by function, line by line as I write it, it seems totally stupid to write code to test my own code.
Not to sound like a shit, but that's what end users are for ;)
- spoils19 4y agoThat's awesome to hear! I myself do something similar with my own code, but then again, I also trust myself more than any computer ;) About how long would you say that process takes you? Do you repeat it every time a minor change needs to happen to your code? If not, how do you verify the impact of your changes?
- noduerme 4y agoRough answer, I spend about 50% of my time just thinking about pitfalls before I actually write the code, 10% of the time writing it, and the other 40% testing it to my satisfaction (doing every stupid thing I can think of someone doing to break it) before I deploy. Usually though, in practice, this looks like tracing/logging several times in the middle of each function to make sure I'm getting it right. Where unit tests are supposedly most handy is when unexpected types are passed to functions, leading to unexpected errors. The majority of proofing against that can be done by strict typing and good code documentation. Ultimately the best test is when you ask yourself "wait, what if someone sent this" and you try it to see if you can break your own code. That's just a spidey sense in the back of your head. If you didn't have the specific doubt to begin with, I don't know how you could write a unit test to disprove it anyway. [edit] just a note to any new coders reading this: Spend the time to always read, read, read everything about how to harden the code you write for security purposes. Unit testing will not save you from SQL injection or XSS attacks, so study those and bulletproof your work against them first before you worry about mathematical proof that your database call never results in an error under some odd condition.
- t43562 4y agoi.e. you're the only one who can update your code because only you know what it's precisely supposed to be doing. Also if you come back in a year you'd better be able to remember everything. I am sorry if I am being a bit mean - I just have had to take over maintenance of things like this and have found it a nightmare from hell so far.
- noduerme 4y agoI think code comments and breaking everything into well-named functions, along with ample side documentation, make it fairly clear to follow. The business logic gets confusing - but anyone who had to work on the code would need to understand that first anyway. I don't think the code itself is difficult. It's all in the docs. Frankly, I don't always remember how something should work and I need to spend a few hours to re-understand some tricky piece of 10 year old code again before I change it. That's the job. My main concern, of course, is not leaving a mess for myself. That should be every coder's priority. Then taking over someone else's projects wouldn't be so hard.
- t43562 4y agoThe problem with anything you've been doing for 25 years is there's not that much chance that I, or anyone else, will convince you to do it differently. That is true of me too of course. Nevertheless, I highly recommend having automated tests and running them in the presence of memory profilers etc like valgrind if you're using a compiled memory unsafe language like C or C++. I would look for another job if I had to work with someone that refused to write them to be honest. It's not that I love tests, but I have had to fix other people's bugs.
- asalahli 4y ago> Ultimately the best test is when you ask yourself "wait, what if someone sent this" and you try it to see if you can break your own code. That's just a spidey sense in the back of your head. If you didn't have the specific doubt to begin with, I don't know how you could write a unit test to disprove it anyway. I can't speak for others but that's precisely how and why I write tests. It goes like "Wait, what if someone sent this" -> check what happens -> write a test to automate that check -> optionally, fix the code to handle this specific case. Then, over time you accumulate tests that check all these weird edge cases for you and it doesn't take much to run them over and over again every time you change the code.
- jawr 4y agoThat’s great if you’re the only person working on the code. Not everyone is as diligent and not everyone will have thought through/remembered all those edge cases when they happen to end up maintaining/adding to your code. Personally I find that tests are a great way to ensure all that hard work you did thinking about those edge cases isn’t wasted. That and manually testing stuff is annoying after the first time.
- noduerme 4y agoThings that either work or don't, don't really need tests. Things that have a ton of edge cases... you might spend ten times as long writing tests as writing the code. In a few cases it might be worth it. Like, I have a piece of hotel software that lets rates be set by the night plus peak extra rates over overlapping time periods, and has to delineate the nightly totals for a customer stay that crosses over lots of those. Lots of edge cases. I had that in production for 5 years before someone noticed that although the totals were right, if the very last night was at the default rate after coming off a peak rate, the line item wasn't printed on the bill. It was a simple case of greedily including one more segment in what was printed. Now... would a unit test have found that? You have to know exactly what you'd be looking for first. The test would have to be smarter than the person writing the code.
- dandy23 4y agoNo, the test would not help to find it, but now you can write a test for that bug. Later, when you change something, related to this code or something unrelated, you can be sure it did not affect this part. Tests are useful when you change code that is unrelated, but still somehow connected. You would never notice the issue as you don't manually try the unrelated code, but the test would catch it. If you had unit/integration tests for all potential edgecases you came up with, you don't have to manually test that over and over.
- noduerme 4y agoyeah but because the code is segmented into very discrete functions... and it's quite easy to see their call chains... Well, I get it. You're right in principle. The truth is, though, I have had to rewrite software from scratch in new languages every 10 years, and these sorts of bugs only appear a few times per decade. Once a piece of central business logic works, it usually works forever; a change to that central logic will of course require changes and tests across the whole system, from user inputs to annual reports, but that can't be helped. I suspect you'd then have to rewrite the unit tests, too. It's probably true that when I die, most of my software will slowly wind down and eventually be abandoned. But also that's probably true even if I were to write a lot of tests.
- ImPleadThe5th 4y agoI think if you're working alone or on a small team on a small project it's use is negligible. The added tidium may not be worth it, and many major issues can be shaken out with integration tests, QA and users. I think a lot of people miss the (in my opinion) best use case for UnitTests. It's in-code self-documentation. Leaving a little nugget of your understanding of the functionality behind for other developers in the future. Even if a method is horribly named or the business logic is so complex it takes an hour to understand exactly what is happening, a simple group of (input -> method -> expected output) unit test can get you working with the method fairly fast. Actually, if I am extending a giant god function that is un-tested. I find it exceedingly helpful to add some tests for the specific use cases I am adding, just to be sure I have understood the code path relevant to my change correctly.
- yunwal 4y agoYeah I feel like the best reason for unit tests is to have a beginner run them with a debugger and take a tour through the code.
- Lewton 4y ago> This may sound weird The weird part is not that you don't write unit tests, plenty of developers don't. It's that in 25+ years, you never even had the stray thought "hm, maybe all this manual work that I keep repeating might be worth automating?" and then tested it out to see whether it was worth doing or not
- noduerme 4y agoThe manual testing really isn't very hard... where it relies on the same logic I use existing logic. Where it's new logic, particularly new UI, testing really can't be automated. Where it's not UI but server logic or DB queries, it's pretty explicit and tested six ways to Sunday before committing. I think the only true unit tests I ever wrote, if you can call them that, were to test pseudorandom behavior across distributions of things like character spawning in games, where player testing wouldn't be sufficient to spot anomalies. For something like that where you're going to have a billion variants, it makes sense to test for oddities on some subset of a million or two. In other words, tests to make sure that output fit a certain curve. Not that logic itself worked or didn't work, because if I can think of a test to write where it might fail, I'd already have fixed it not to fail under that test.
- blowski 4y agoThere is a difference between these three statements: 1. It can't be tested. 2. I don't know how to test it. 3. The tests don't give enough value given the effort required to write them. The less experience you have with tests, the worse the cost-benefit analysis comes out. This is why people disagree over unit tests. Good tests give a huge productivity gain, but the opposite is true of bad tests. Unfortunately, there's a vicious cycle: You write bad tests -> You don't value tests -> You don't spend time learning to improve tests -> You continue to write bad tests
- hbrn 4y agoThe problem is that writing good tests is harder than writing original code. And what happens in most companies? We hired a junior engineer and don't have work for them... let them write tests!
- LandR 4y agoSay you have to test 15 things to know it works. Then you make a change, that change impacts 10 of those. You now need to go back and re-test, manually, those 10 thing and check they haven't broke. That's mainly why I use unit tests, as regression testing. Also as documentation, if I'm unsure around what a piece of code is actually doing, it's helpful to see tests that hit and find something like. When_FooIsInThisState_ThenIExpectThisThingToHappen() Then see the setup and expected output. It's also good for incrementally building stuff. e.g. I have 3 scenarios I want to get working, I write a test for the first and get it passing. Then I move onto scenario 2, this requires changing the code slightly for scenario 1, but I don't have to re-test scenario 1 as I've got a unit test that is running each time I change the code that tells me it still passes, and so scenario 1 is still working. Then when I do scenario 3, I know 1 and 2 are still working without manually going back and testing them... They can really save a lot of manual effort.
- hbrn 4y ago> Then you make a change, that change impacts 10 of those. You now need to go back and re-test, manually, those 10 thing and check they haven't broke. Unit tests provide no guarantee that those 10 things haven't broke. They can break in a way that's not under test. Or they can be working individually, but breaking as a whole. You still have to test those 10 things manually before merging. Sure, sometimes unit tests will show you regression early on. Early feedback can be useful. But it will never give you confidence, it doesn't eliminate manual testing. The important part is that you're making a change and you don't have confidence that it is safe. This is a signal of bad design. In most cases the right solution is to fix the design, not throw tests at the problem. There are exceptions of course, but even in those cases tests are not something to celebrate or be proud of. It's like getting obese and then celebrating statin therapy. I mean it's great, but not as great as not being obese in the first place.
- deleted 4y ago[deleted]
- spoils19 4y agoAgreed. That lack of guarantee generally means that it's a waste of time to even try unit testing in the first place.
- vladsanchez 4y agoPor eso "noduermes" LOL
- flippinburgers 4y agoIf this is actually the case you are not writing complex systems.
- hbrn 4y agoNot writing complex systems is a skill (that most engineers lack).
- Supermancho 4y agoIf you have written a debug println you have written a unit test.