Live data from Hacker News

Sensible Software Engineering

scriptcrafty.com

61–70 of 77 posts

Re: Sensible Software Engineering

#61

> Bugs are correlated with lines of code and TDD forces writing more code so how can it reduce bug counts? If the test code has no bugs then just write the rest of the code in the same style Nobody has pointed out the fault in this reasoning yet, so I will. The linear relationship lines-of-code vs. total-bug-count is based on independence of bug introduction in different parts of the code. That is, introducing a bug…

Bugs in tests exist (and are just as prevalent as bugs in production code in my experience). However, writing production code introduces a kind of constraint on the system. If you run a function with certain program state, then it returns a certain result. No matter what you do, this will happen because that's how you wrote the code.

A test introduces the same constraint. Instead of implementing the function, it runs the function. No matter what you do, the test will run certain code and get a certain result. Tests pass when the constraints introduced by the production code match the constraints introduced by the tests.

Because of this, if there is a software error in the production code, usually you need to have a corresponding error in the tests in order for the test to pass. This definitely happens from time to time, but the odds of it happening are much lower. Similarly, if you have a software error in the tests, you need to have a corresponding software error in the production code in order for the test to pass -- assuming that the test is actually exercising the code (something you can't always assume, unfortunately).

Re: Sensible Software Engineering

#62

> Bugs are correlated with lines of code and TDD forces writing more code so how can it reduce bug counts? If the test code has no bugs then just write the rest of the code in the same style Nobody has pointed out the fault in this reasoning yet, so I will. The linear relationship lines-of-code vs. total-bug-count is based on independence of bug introduction in different parts of the code. That is, introducing a bug…

Agree. Consider the situation of data entry professionals, those people who transcribe audio recordings or enter data into databases.

If you have one person entering data into a computer, then the odds of them introducing an error and failing to spot it are fairly high.

If you have twice as many people entering twice as much data data, then the odds of an error getting introduced are roughly doubled.

However, if you have those two people entering the same data, then their mistakes cancel each other out. If person A and person B both entered the same thing, it's extremely unlikely that it's incorrect. If they differ though, the a problem has been identified, and can now be fixed.

The odds of both of those people entering the same piece of data incorrectly is tiny. Likewise, accidentally introducing a bug into both the production code and the test is pretty unlikely.

That said though, if those two theoretical data entry people above are given the wrong data to enter, then they the system cannot protect them. They will both correctly enter incorrect data. "Garbage in, garbage out".

Likewise, if the requirements of a piece of software are poorly understood, then it is quite likely that both the test and the production code will implement the same "bug". Writing tests won't fix a failure to understand the problem you're trying to solve. And they're not supposed to.

Re: Sensible Software Engineering

#63
post #38

Earlier quoted context omitted.

Tests don't exist for solving bugs as much as they exist to prevent regression. Writing exhaustive tests is not sufficient to bring c' to zero, because some of those bugs exist because of the developer's own presumptions about how code should behave.

But testing exhaustively means the full range of inputs are used, and therefore, if a bug arises as inputs not considered by the dev initially, it would show up as a failure. What you're actually saying is that reaching full exhaustive testing is near impossible.

Testing for regressions is a a valuable thing to do, but your point is also valid. We can prove that it is impossible to test every scenario in general (for example, does this program end ;-) ). In my mind, unit tests exist for documenting what the code is doing now -- not to determine if it is correct (acceptance tests are different). Your goal for a unit test is to have it fail when the behaviour of the production code fails. This way you can verify that the changes you are making are having the effect you expected. Similarly, you can be warned when changes you make affect part of the code you didn't expect to be affected.

Of course, you will never get full coverage, but tests are a programmer's tool. It allows you to reduce the amount of time you spend inspecting parts of the code you aren't working on. For example, when I'm writing code with good test coverage, I can find out what happens if I change an attribute in a structure simply by doing it and watching the tests fail. Each failure tells me where in the code I'm likely to have to make a change.

If you make a small viewpoint change that tests are not to find bugs, but rather are a tool to help you understand the code base, they make a lot more sense. (IMHO)

Re: Sensible Software Engineering

#64
"Whenever I’ve approached a new system the bottleneck has never been writing more code. The bottleneck has always been in understanding all the implicit assumptions baked into the system that for one reason or another are essential to its correctness". Well.... I know the feels... Assumptions without "understanding" is like the sword of damocles. As you sway into the program itself, there's always this notion that "something" is not right. Or maybe our assumption is not good enough. Most of the time, unplanned assumptions make it harder to integrate "more" code in the long run.

Re: Sensible Software Engineering

#65
post #9

Earlier quoted context omitted.

I am a big fan of Nomad's scheduler and the code is easy to pull in to an existing Go project. It doesn't have everything Kubernetes has but I don't think it needs it, either. Kubernetes has for sure won the popularity contest but the overhead involved in running it The Right Way™ on your own is a lot. Given what I've seen I would advocate for OpenShift if you like RedHat products / projects or sticking with Kubernet…

I have a sneaking suspicion that Kubernetes is another Ruby on Rails waiting to happen: https://trends.google.com/trends/explore?date=all&geo=US&q=r...

The geographical map of Rails vs Kubernetes is quite interesting:

https://trends.google.com/trends/explore?date=all&geo=US&q=r...

Re: Sensible Software Engineering

#66

Earlier quoted context omitted.

Out of curiosity, which more modern stacks were those?

Most NodeJS with ReactJS frontends. Some of them had already started doing React for frontend and just need the backend work.

React for a js front end makes a lot of sense. But, for the back end, what advantages did they expect by moving to node - besides having the same language in the back end?

Re: Sensible Software Engineering

#67
post #2

>Bugs are correlated with lines of code and TDD forces writing more code so how can it reduce bug counts? If the test code has no bugs then just write the rest of the code in the same style I'm not advocating for TDD (the programmer methodology in the IDE) but the author's explanation about "test code" isn't correct. Code written for explicit purposes of a test to exercise other code has been shown to increase correc…

The question that always comes to mind whenever testing is discussed is "how do you know the test code is itself free of bugs?" I distinctively remember once posing that question in a meeting about testing, and a manager replying --- seriously --- with "then perhaps the test code should itself have tests." Someone else must've come up with that before too, because (at a different job) I've also worked on a codebase w…

Add to this countless hours going into engineering tests that have to bent over backwards and mock the universe itself to test a tiny bit of logic that doesn't make sense to test in the first place. Then multiply with the hours getting lost trying to debug frail tests that break time-expensive continuous integration pipelines.

Good unit and integration tests are a rarity. Instead tests like the above ones which actually are being developed like a side-project to the real project are the norm and they are bogging down the whole project. But you cannot deliver any code that is not "covered" because that would be against the current 100%-TDD bible/best practice/call it however you want.

So the next dev/maintainer has to work out a badly written test (probably bearing untrue assumptions about the programs intended business logic) and after some fun hair pulling he does the reasonable thing which is working around the test or pampering the test to get it to pass. And that is how you end up with test code that is actually buggy and problematic in itself and does not really test much but it is increasing the test-coverage holly counter.

Re: Sensible Software Engineering

#68
post #34

Earlier quoted context omitted.

I see 5 cases: Code | Test | Result -------------------------------------------------- fine | fine | a) We have a regression test, yay! fine | buggy | b) Someone breaks the code to make the test work. Oops. c) Someone fixes the test, we have a regression test, yay! buggy | fine | d) We'll fix the code, and we have a regression test, yay! buggy | buggy | e) Bug remains in code. Oops. If the probability of introducing…

Top notch explanation here. P = 0.01 is 1 in 100 though right?

Oops, yes.

Re: Sensible Software Engineering

#69
Basically, the author suggested a “back to basic” approach, which is of course not totally wrong. But ignore the very real challenge of the software industry is not going to help either. We can not sit down to plan and wait for the so-called “global optimal” design and then and only then proceed to implement. Because to achieve a “global optimal” design one has to consider each and every details and aspects of the problem, which is simply impossible in the software industry because so many are unknown. The Waterfall model is long dead. History has proven it does more harm than good. Don’t dig it up.

PS: I don’t disagree that in some cases, academics can use the formal methods to find a (near) global optimal solution. But I don’t think it’s practical in a daily context, nor necessary. Our evolution is the best proof that local optima can lead over time to fantastic solutions.

Re: Sensible Software Engineering

#70

> Bugs are correlated with lines of code and TDD forces writing more code so how can it reduce bug counts? If the test code has no bugs then just write the rest of the code in the same style Nobody has pointed out the fault in this reasoning yet, so I will. The linear relationship lines-of-code vs. total-bug-count is based on independence of bug introduction in different parts of the code. That is, introducing a bug…

Agree. Consider the situation of data entry professionals, those people who transcribe audio recordings or enter data into databases. If you have one person entering data into a computer, then the odds of them introducing an error and failing to spot it are fairly high. If you have twice as many people entering twice as much data data, then the odds of an error getting introduced are roughly doubled. However, if you…

> The odds of both of those people entering the same piece of data incorrectly is tiny.

This is just not correct. There may be a systematic reason why they are making a mistake (e.g. a miss-pronounced word) in which case increasing the confidence intervals does not increase the accuracy. Check out the concepts of accuracy, precision etc from physical sciences.

Post reply on HN