3 ms·
I would add two things to this: 1. Automated tests are not the only way to write code with less bugs. The other two, currently less in fashion but IMHO very im
by js8 10y ago
I would add two things to this:
1. Automated tests are not the only way to write code with less bugs. The other two, currently less in fashion but IMHO very important, techniques are abstraction and assertion.
2. In my view, there are two kinds of automation - bad and good. Bad automation checks if humans did some process correctly. Good automation implements some process without human intervention. It's very easy to start working on bad automation rather than the good.
- dfischer 10y agoHave any examples to clarify point two?
- js8 10y agoWell, an example I have from work, where we have a certain very old and obscure process to build fixes for our application. It's somewhat a manual process. Somebody wrote a program to check if this manual process was done correctly. It prevents problems, but better would be to replace this manual process with an automated one, however that would mean to change the process somewhat to accommodate the automation (this is sometimes necessary since humans can deal with weird exceptions much better than machines). Another example could be used linter or valgrind to prevent C-style bugs with pointers and allocation, instead of using a high-level enough language, such as Java, to avoid those in the first place.
- dfischer 10y agoYeah it's an interesting perspective. Thanks. I'm looking at it from a product UX perspective. It's a good challenge. Thanks for the insight.
- crdoconnor 10y ago>Automated tests are not the only way to write code with less bugs. It's absolutely a prerequisite. Humans can model the behavior of small parts of a code base without the aid of automation, but once a code base grows beyond a certain size, you either need to have automation to have a handle on the code or let it congeal (which ends up accelerating the creation of technical debt). There are bad tests just like there is bad code. All of the rules for good code apply to tests too.
- Kiro 10y ago> assertion What does it mean in this context?
- js8 10y agoAssertion is check for a certain condition. It can be static (type checking is the simplest example), or dynamic, to be executed at runtime (the simplest version is a null pointer check). Assertions are more general than tests, they test an expected state of application, not if specific case of input gives specific output. On the other hand, you can probably test more things that you can assert. So both have their place.
- therealjumbo 10y agoI'm not disagreeing with you; I really like both of your points however, I have two problems with assertions. Let's say the assertion is inside a function e.g.: void function adjust_fan_control(uint8_t fan_speed) { assert(0 != fan_speed); ... // some complicated code here } What if the adjust_fan_control function isn't necessarily called for a given run of the program? Then you don't know if you actually tested that assertion, that is for all callers of function X, you don't know if all those callers are calling X correctly if you only rely on the above. Of course I'm not trying to suggest that you're arguing for assertions to the exclusion of tests, just pointing this out. The second problem I have with them is in embedded systems. I'm heavily in favor of putting assertions (which are then omitted in prod builds, or instead of looping the LED blink routine they map to a soft reset if fail) inside functions in embedded systems. However, if I have very limited I/O, specifically, I don't have the ability to log when/where an assert was hit, all I know is that an assert was hit because the LED pattern goes to 'blink really fast like this indefinitely which means an assert failed'. If I have a lot of asserts, that doesn't really tell me anything. On the other hand, if I have unit tests, and my mocks assert, and I can run the unit tests on a simulator or heavily instrumented system, then I know which assert failed in what function and who called that function. The point is I can't do that (or I don't know how) without the tests. Edit: formatting.
- quanticle 10y agoAutomated tests aren't the only way to write code with fewer bugs, but they are the easiest way to write such code. Automated tests are also the easiest to have running constantly, giving you instant feedback when you've broken something. The only downside is that there are some tests (like testing with particular datasets or high-load performance testing) that can be onerous to automate. My personal rule of thumb is that checks for program correctness should all be automatic. Non-automated tests ought to be reserved for testing non-functional requirements (e.g. making sure the service is performant under load, reliability measures like failovers, etc.).
- dozzie 10y ago> Automated tests [...] are the easiest way to write [code with fewer bugs]. Actually, automated tests are best at ensuring the code doesn't have regressions. But writing bug-free code takes much more than just that; it needs thought-out architecture and interfaces, and with those you often can get decent code without automated tests, so no, it's not "the easiest way".
- crdoconnor 10y agoThey also serve as a form of code documentation (defining expected behavior). When doing TDD, often speed up development owing to the ability to get much quicker feedback on the code you just wrote. Code without tests has a tendency to congeal owing to the massive uncertainty surrounding changing any particular part.
- dozzie 10y ago> They also serve as a form of code documentation (defining expected behavior). Oh, far from it. Tests are not documentation, documentation is documentation. Tests can be treated as a set of examples at best.
- crdoconnor 10y agoGood well explained tests serve well as documentation. I've used them before in lieu of specifications. Bad tests not so much.
- rhinoceraptor 10y agoIf your code fails an assertion and dies, isn't that still a bug to the end user?