Slashdot Mirror


Alan Cox on Writing Better Software

Andy Gimblett writes "Alan Cox recently gave a talk in which he discussed some current and emerging techniques for producing higher quality software. Some of these will be familiar to Slashdot readers, such as validation tools, type checking, etc, but others seem heavily influenced by his recent MBA. In particular, he has a lot to say about Quality Assurance in the software world, and the kinds of things we should be doing (and some people are doing) to make better software. Story and lots of quotes at Ping Wales, and video at IT Wales."

50 of 391 comments (clear)

  1. 2 words by otisg · · Score: 2, Insightful

    unit tests

    not a panacea, but it does go far.

    --
    Simpy
    1. Re:2 words by ceeam · · Score: 2, Insightful
      That's nice thing when you do your project bottom-to-top, i.e. when you have some engine tossing around your data and stuff, and then write UI on top of it. (UI is not very unit-testing-friendly, is it?)

      Unfortunately, IMHO, most of software is done as this - let's put pretty gadgets around, cool nice icons, and then we'll do the job in event handlers somehow. Here it all breaks loose.

      Why it is done that way is easy to see - managers/supervisors are not interested in you doing smth behind-the-scenes for weeks/months without showing "cool stuff" to them.

    2. Re:2 words by Anonymous Coward · · Score: 1, Insightful
      UI can be unit tested -- start at the display component level, write a bot to simulate input through your OS (windows messages, X events) and run simulated back-end data outputs and front-end screen scrapes and data inputs. Catch exceptions and weed them out (or document work-arounds). Web apps are particularly easy to do, just build HTML get/post tests.


      The UI unit test should focus on 2 things: does it crash, and does it transform the I/O it's supposed to handle in an unexpected way. Either one is an error that automated tools can find and fix, and they're both show-stoppers for end user testing. Usability testing is the proper domain of the end-user test cycle, but you can check to make sure the display is as-designed with a tool.


      There's commercial stuff available if you want to test the UI attached to the application, but you really can roll your own component-level tests if you're so inclined. At some scale it will become infeasible to keep building one-off UI test programs (because yes, they are harder than most library testing) but by then you'll either be making enough money or out of business :).

  2. "free" ? by mirko · · Score: 2, Insightful

    I see that the word "Free" doesn't appear in this story's synopsys.
    How would Alan apply his quality methods to projects which member might never meet due to geographical contingencies ?

    --
    Trolling using another account since 2005.
  3. Good code... by TrollBridge · · Score: 5, Insightful

    ...isn't just for end-users! If you anticipate that others will be working on future versions/releases of your software, good commenting can make the job SOOOOO much easier for the next codemonkey.

    I'd say commenting is doubly important in OSS projects, as it involves many sets of eyes trying to comprehend what you coded.

    --
    There's a Mercedes gap too. I want one and can't afford one, but it's not government's job to do anything about it.
    1. Re:Good code... by Dr.+Evil · · Score: 4, Insightful

      Commenting must be 100% accurate else it is detrimental to understanding the code.

      Sometimes code changes don't result in updated comments...

      Once I find an inaccurate comment in somebody's code, I have to start rewriting or deleting all the comments because I can't trust them anymore.

    2. Re:Good code... by Anonymous Coward · · Score: 1, Insightful

      Agreed.

      I myself was a big commenter until I realized that when I read others' code I never read the comments. Comments tend to state the obvious and not tell you what you really want to know. I think it is more important to write the code itself in the most transparent way --- meaning not using obscure language features, not being afraid to break slick but unreadable code lines into multiple, stupid-looking-but-obvious lines, etc.

    3. Re:Good code... by johannesg · · Score: 4, Insightful
      That, and good naming of variables / functions / classes. To clear up any possible confusion: that means that the name has some bearing on what the thing in question is doing for you...

      Recently I had the misfortune to wade through a few hundred kilobytes of Java that was written by someone who thought he should 'abstract' everything as much as was humanly possible. Sounds good, right? Well... It turns you can do a lot of harm that way, too. I don't think he had a single function in there that _wasn't_ called something like SetProperty(), GetValue(), DoFunction(), etc. There was absolutely no way to guess what it was doing based on the name of the functions. Naming of classes and variables wasn't much better. After looking at it for a couple of hours I don't think I could have guessed what it was trying to do if I hadn't already known that beforehand.

      So, next time you are writing software, feel free to get in touch with reality and name stuff after what it is supposed to be doing. Nice long names please, no abbreviations unless you go over 30 or 40 characters. Down with CmtPmt2Db(), down with SCUPD(), and down with GetPropertyValueInterfaceCaller()!

      Because, be honest: those mean nothing, while CommitPaymentToDatabase(), ScreenUpdate(), and GetXLocation(), have intuitive meanings we all understand...

    4. Re:Good code... by gidds · · Score: 4, Insightful
      Comments tend to state the obvious and not tell you what you really want to know.

      This is a reason to write better comments, not to avoid them completely!

      Of course comments that are flippin' obvious, or wrong, do no good to anyone. But some sorts of comments can be incredibly helpful:

      • Big-picture comments. Explaining what this function, method, class, file, or interface is doing; how it fits into the app or system; important design decisions. Also authorship and date information, if that's important.
      • API comments. Describing the implicit (or explicit!) contract that a function, method, class or whatever has with its caller. When you should be calling this code, what the caller needs to have set up beforehand, what the code guarantees to do in return, any gotchas.
      • Section comments. Within long functions, just a few words every 10-30 lines, breaking it up into logical sections, can make it much easier to understand the flow, or find the particular section you're looking for.
      • Here-be-dragons comments. Describing tricks, shortcuts and other hacks. Better to make the code clear and obvious, of course, but there are times when a clever technique or bit of magic is needed, and for those rare occasions, a few words of explanation can make things so much clearer -- and prevent someone ignorantly 'fixing' it later!
      Of course, there's some overlap. But these are the sorts of things that can make code so much easier to read, and don't take much effort to maintain. The big-picture and API comments tend to be common practice in literate languages like Java (JavaDoc) and Perl (POD), but too many people don't follow it -- and even where those comments aren't extracted automatically, they can still be incredibly useful.

      My rule of thumb is: Try to make the code itself obvious. And comment everything else!

      --

      Ceterum censeo subscriptionem esse delendam.

    5. Re:Good code... by ajs318 · · Score: 2, Insightful

      You see, that's the point. There's no point being too clever -- you can use the programming language itself as a sort of "generality-of-purpose abstraction layer". After all, if a language is computationally complete then as a matter of definition, any task you might want to perform can be implemented using that language. There is no shame in writing a program to do just the thing it has to do. It's far better to be able to play one song all the way through from start to finish with no mistakes, than any number of fancy riffs and bits of verses.

      Code that you've written once for one specific purpose can be picked apart and made to do something different later if you ever need to -- and you might not. Just keep the thought at the back of your mind that you may need to make something a little more general-purpose, so as to make sure you will be able to do it when the time comes. That will mean intelligent use of comments and choice of variable names. If you're following KISS principles anyway, it should be almost obvious what something is doing.

      I once wrote a function to send a MIME-formatted e-mail with exactly two attachments, and did not feel even slightly guilty about it; because that was what it had to do. Sure, later I did need to be able to send three attachments, or just one; but it was much easier to extend something that had already proved itself sending two attachments, than to write something from the outset that could handle an arbitrary number of attachments. The bits that needed to be altered to use loops and arrays stood out much more clearly once I was seeing them hard-coded with separate statements and separate variables.

      Extraneous generality of purpose is really just a form of cruft. It just makes your code harder to write {because you have to consider other things beyond the problem you were originally considering} and harder to test {because you have inevitably introduced more ways to break it}.

      --
      Je fume. Tu fumes. Nous fûmes!
  4. Re:Unit testing? by Anonymous Coward · · Score: 1, Insightful

    here here. as a coder i tend to get things working as they should be, but the user comes along and does something completely different. i've found that the key lies in trying to break the code, and when you get it so that it doesn't break, you're halfway there. i try to code for at least a 'mars rover' level of reliability.

  5. Re:Unit testing? by bloggins02 · · Score: 5, Insightful

    Unit testing is essential, but it's not a panacea. In particular, beware of two pitfalls:

    1) "The unit tests passed, so it works." This assumption is flawed on several levels. First, and most fundamentally, even if all unit tests pass, there is still the issue of whether your software works as a whole. Software often has "emergent logic" and UI scenarios that are difficult or impossible to test (after all, that's not what unit testing is for, but some people seem to think it is).

    Second, just because a test passes, doesn't always mean the API works. This is especially important if you didn't write the tests yourself. Just because a unit test CLAIMS it tests X, doesn't mean it does. Is the test complete? Any false positives? Is the test just a skeleton that was intended to be implemented later but never was? I've had all these bite me in the past.

    2) "That particular test has NEVER passed, so there's something wrong with the test. We just ignore it now." Bzzzt! Wrong! There's a REASON it never passed. It's either not implemented properly, just a stub that fails waiting for someone to write an implementation, or maybe you just think the feature it tests actually works. Look closer. The test might be trying to tell you something.

    If you are careful with unit tests, they can be very rewarding and useful (especially for regression testing, where they are invaluable), but put too much confidence in them or depend on them to do the kind of overall testing they were never designed to do, and you will fail long before your first test does.

  6. Re:Unit testing? by cerberusss · · Score: 3, Insightful

    What people should realize, is that it can cost quite a bit of effort to build a unittest. I.e. if you write some code that reads several rows from a database and as a result writes a bunch of rows in another table, you need to run scripts before and after your unittest. It's of course all doable, it's just that it's sometimes more work than writing the method itself.

    --
    8 of 13 people found this answer helpful. Did you?
  7. Testing is good by TreadOnUS · · Score: 4, Insightful

    But the real key is reducing the number of defects introduced into software. Testing only finds existing errors. If the number of errors are low from using good requirements, design and development practices then testing becomes less expensive and time consuming.

    1. Re:Testing is good by djmurdoch · · Score: 3, Insightful

      Testing only finds existing errors.

      No, testing finds new errors. That's what test suites are for: to let you know when your change to X caused Y to break.

  8. Re:Quality by mfh · · Score: 4, Insightful

    And what then when the customer wants some hard evidence about what has been done? What then? What will you provide to them? How does your irrational hatred of managers actually assure quality in concrete steps?

    A good manager does all the detail work and keeps track of everything. My post was about what they haven't been doing much of lately.

    I don't hate managers, and to suspect that I might by reading my previous post means you failed to understand it.

    Quality in business comes from many different people in any given project. Software quality can be adversely affected by morale, and you guessed it -- programmers have some of the lowest morales in the business world today; they are often not respected by management, they have the highest workloads, and they have no time for social lives.

    If managers listened, and remained silent or inquisitive instead of arbitrary or antagonistic, software quality would be up.

    --
    The dangers of knowledge trigger emotional distress in human beings.
  9. Paths to quality by Anonymous Coward · · Score: 3, Insightful

    The links seem dead so I will add my .02. The programmer's view of the software should not be confined to the source code control system. Programmers should know how to install and implement the software they design and code. Programmers should have some personal experience supporting the software they code. NOTHING highlights the weaknesses of your software faster than being forced to work a support line/forum, etc. Establish personal relationships with employees in the sales force and management. You will be able to be more influential in the company if you do this. Establish personal relationships with your customers. You can use them to push your agendas. Paying customers have some of the most pull with your company. Use this to your advantage.

  10. Re:Unit testing? by Unkle · · Score: 5, Insightful
    But that's really the reason it's not done all that often. Developers think that the unit test will be a waste of time. The problem is, nobody codes perfectly. Finding a bug during unit testing is much better than finding it in design validation testing. Indeed, on many projects I have worked on, issues that could have been found with adequate unit testing were not found until after release.

    Unfortunately, when schedules get tight, it's things like unit testing (and testing in general) that get cut. The more emphasis we get on the importance of QA the better our industry will be.

    --
    Against stupidity, the gods themselves contend in vain.
  11. Re:Unit testing? by Anonymous Coward · · Score: 3, Insightful

    Study Mock objects

  12. Keeping prototypes just that by mark1348 · · Score: 4, Insightful

    You can't help but be frustrated when dealing with projects that were obviously "proof of concept" which then evolved directly into the actual "product". Hard to resist but just plain stupid. I wish more open source projects had strict standards.

  13. There are different types of code reviews... by Richard+Steiner · · Score: 4, Insightful

    We used to implement code reviews at my former workplace, but they were more "sanity checking" peer reviews than anything else. They didn't take very long, and it gave one or two other people a chance to see how understandable or generally logical the changes were.

    That type of thing doesn't work as well for large changes, but we found that for small ones it sometimes can be a useful thing.

    --
    Mainframe/UNIX Bit Twiddler and long time Windows/Linux Hobbyist.
    The Theorem Theorem: If If, Then Then.
  14. Write the tests *first* by wowbagger · · Score: 5, Insightful
    More importantly, write the tests FIRST. Then write the code, updating the tests for anything that is identified during the coding.

    This has several important benefits:
    1. You have to DEFINE what the module is to do so that you can write the tests. Granted, the first pass for the "tests" may simply return "failed" until something is written for the module, but at least you will have a chance to think about what you should be testing.
    2. You actually DO write the tests, rather than blowing them off. If your manager says "Why aren't you working on $blarg?" you can say "I *am* working on $blarg" since the first step is writing the tests.
    3. As you get funtionality working (as demonstrated by the tests passing) you can quickly determine if a later addition to the code breaks the working feature - and fix it while the change is still fresh in your mind (and hopefully BEFORE you commit your changes to the mainline code path (you ARE using a source code control system, aren't you?))
    4. You can automate the testing of the system.

    1. Re:Write the tests *first* by iabervon · · Score: 2, Insightful

      You don't catch SQL injection issues with unit testing; you catch them with type checking. A SQL injection occurs when someone uses a string plus quotes as a partial SQL statement. There should be a different type for partial SQL statements, and the operation to make one for a string constant out of a string should escape the string appropriately. Alternatively, you could just use prepared statements exclusively and make your database happy as well as making SQL injections totally impossible (as the database will be done parsing the SQL when it looks at the user-supplied data).

      The best reason to write the tests first, in my opinion, is that this will give you a good idea of whether the API is any good. Many of the APIs I've wanted to be different obviously couldn't have been tested in advance, because writing the test would have made it clear that the API was just too much of a pain to use. If writing 10 example uses for your API is enough work to worry about, your design is bad, and people are probably going to not like how it works. Change it before either finishing the tests or writing the code (or, ideally, telling anyone else about it).

    2. Re:Write the tests *first* by Surt · · Score: 2, Insightful

      Peronsally, I don't like anything from XP except the testing ideas, and those don't originate with XP.

      The process I like best for 'test-first' is actually 'almost-test-first'. Instead of just sitting down and writing tests, the process is:

      1) Design a system that solves the problem.
      2) Figure out what entry points are to the system.
      3) Implement the interfaces for the entry points so that the public contract is defined.
      4) Now you start writing tests that verify the fulfillment of the public contract.
      5) Implement the interfaces in a way that satisfies the tests.

      Our current project has about 7500 tests. The system is what I would rate as middleing complex. I average about 3 sideffects caught by tests per major checkin. That's a lot of subtle stuff no qa person had to chase down, and a lot of developers who aren't irritated that someone else broke their stuff.

      --
      "Who is the Journal of Quantum Physics going to believe?" --Stephen Hawking
  15. Re:software dev by 110010001000 · · Score: 2, Insightful

    Viewing your code in assembler? Comment every 3 lines? You must be kidding, or trolling.

    The top 5 things are:
    1) Meeting the requirements
    2) Stability
    3) Maintainability
    4) Expandibility
    5) Efficiency

  16. Re:software dev by Anonymous Coward · · Score: 1, Insightful

    You said "speed" at number 2. 4 and 5 just reiterate that. Are you a speed freak? Games coder, perhaps? :-)

    Robustness is WAY more important than speed. Forget speed. Really. Forget it. Then forget it some more. I'm an assembler coder and I could do without the competition :D

  17. Good practices by vinukr · · Score: 5, Insightful

    These are some things i guess is necessary for good software
    1) Reviews at all stages.(Reqs/design/dev)
    2) While at development, u sure must know whats the most efficient way to code a design (which libraries are more suitable etc)
    3) Unit testing and Integration testing (when the project is huge)

    Some practices that managers can really use to take the pressure off the team
    1) Try giving buffers to the team (seriously, it works)
    2) Proper Code management (Lotsa rework and pressure come due to lack of this)
    3) Proper tracking and status updates to the customers

  18. Re:Unit testing? by OP_Boot · · Score: 3, Insightful

    the engineers who wrote the code actually write tests

    Do NOT get the engineer who wrote the code to also write the test.

    It's fairly fundamental - the engineer who wrote it will have a prejudiced view of what should/will work.

    Get someone else to do it and get a valuable fresh insight.

  19. error-free software by frankvl · · Score: 1, Insightful

    The only way to create error-free software is using a guaranteed error-free interface (I'm not talking Java, we should go much further), which has to be the base of the operating system to be actually error-free.
    As a nice by-product, developing applications will be much easier.

  20. Re:Unit testing? by Anonymous Coward · · Score: 1, Insightful

    It's quite surprising to me that there's no mention here of unit testing, or any sort of automated testing where the engineers who wrote the code actually write tests.

    It's better if you get different people to write the tests. Otherwise the engineers might subconsciously make assumptions in their unit tests that real-world use might not.

  21. Re:Quality by Anonymous Coward · · Score: 0, Insightful

    Managing people to be happy and productive is not the only quality assurance activity you can do.

    I ask you again, how does your four-part list concretely assure software quality? The human issue is just a really small part of the software quality. You have tight schedules, inane processes, nonexistent budgets, requirements from some other galaxy, need I go on?

    How does for example listening to people automagically track the number of defects? Or make sure there's a responsible person for certain code modules? Or make sure the test cases are written, run and kept up-to-date?

    The problem is not so simple as you put it. Yes, listening to people will help but it's not the whole solution nor the end-all to this dilemma.

    If someone is arbitrary or antagonistic, speak up and give constructive feedback, tell them to stop being such. If you are reprimanded for that, why work in such a place?

    It's fashionable to bash managers, but how many of you will not speak out about things which are wrong when you have the chance, then complain about it being so? If your managers don't listen when you do that, find another job with better managers.

  22. Re:Interfaces and contracting... by LeonardShelby · · Score: 2, Insightful

    I'm not claiming silver bullet status. Far from it. I'm simply stating that software engineering requires contracting and better interface design techniques as part of its standard repetoire. Add these to the hard work and discipline you mention.

    (Also note these are not tools, but techniques.)

    --
    remember Sammy Jankis
  23. Re:Unit testing? by mark_lybarger · · Score: 2, Insightful

    you only need to validate the functionality in the method itself is working. from your sig it seems you're using java. junit with an embedded axion database allows for extremely easy testing of a method that uses a database connection for its work. of course, you have to setup your test by creating a table, and inserting any base data. getting that basic framework is as simple as writing the method itself. you'll probably double your time in writing the actual method. i'd think the return on that investment is "priceless".

  24. Re:software dev by Timesprout · · Score: 2, Insightful

    Surprising you dont seem to think good software should meet the users/customers requirements. That would be first on the list for me. Software must do what the user wants or it is a total failure as far as I am concerned. In general I would agree with your points. Code should be robust, testable, maintainable and reasonably performant. I prefer the source code to be documented well and autogenerate documenation from it rather than maintain duplicate documentation.

    I am also a big fan of profiling code, and for server apps, proper load testing is and absolute must. It often only finds the low hanging fruit as performance bottle necks tend to be resource based eg the database is usually the 'culprit'. Profiling and code coverage/ code analysis are valuable tools though to identify critical paths and likely sources of problems and help developers gain a clearer picture of how the application actually works.

    --
    Do not try to read the dupe, thats impossible. Instead, only try to realize the truth
    What truth?
    There is no dupe
  25. Re:Code review and pair programming by Alan+Cox · · Score: 3, Insightful

    If you are bug hunting then the code review needs to be an explanation of what the code does. "We get a foo, we have to decide if its in US or UK format so we compute both checksums and .. oh umm.. I'll come back later'

    It's very different to things like design reviews. They have their place too. A lot of things Linus rejects are really design review things. Its not uncommon to get a "Yes this needs fixing but do it this way instead". It works well providing the person saying that has good judgement.

    Bad code review, bad tools, bad compilers and bad managers are _all_ useless

  26. Re:Code review and pair programming by someme2 · · Score: 3, Insightful
    [... Examples of how code reviews slowed down this guy's work without doing any good ...]

    If this happens to you on a regular basis then you are probably a better-than-average developer. Which is just fine as long as we find a way to make your work more average. And code reviews seem to do the job.

    Seriously, the productivity spread between developers (20 times as effective... adding more people... Thank you Mr. DeMarco) is what a lot of very strict process models and practices (such as code reviews) really attack - and it is a good thing, too. Because otherwise developer workforce does not scale well.

    The productivity spread is the enemy of plans, predictions, estimations and bureaucracy. Bureaucracy is the most successful human scaling mechanism.

    In other news: Big cooperations have difficulty exploiting the individual genius of low-level members of their workforce.
    --
    You can attach boosters to anything. It just costs more. -
    Anonymous Coward on Sunday November 07, @12:26PM
  27. Re:Unit testing? by deranged+unix+nut · · Score: 1, Insightful

    Unit testing doesn't find bugs, it just ensures that you didn't regress the obvious or break something that your previously fixed.

    With end user applications, on average, a couple hours of active ad-hoc testing and test case development per week finds 95% more bugs than hundreds to thousands of automated unit tests will.

    For an API, unit testing might be more effective, but APIs are much simpler to test than full end user applications.

  28. Re:Quality by angel'o'sphere · · Score: 2, Insightful

    The human issue is just a really small part of the software quality.
    Trust me. All problems in software engineering are human issues.
    It helps nothing if a guy in the team is a hero or super hero or the brightest expert if the human factros are a mess.
    All problems in software projects are simple:
    1) lack of understanding -- people do not understand the problem domain
    2) lack of insight -- people do not realize they suffer from (1)
    3) lack of problem aware ness -- people do not realize that there ARE problems and that they have to SOLVE them
    4) blaming other people -- as soon as it gets obvious that (1) to (3) is happening, a solution is not searched but a guy to shift the blame on

    This are the core problems. All so called Software Process or Software Engineering tools and habits only soften those problems. A issue tracking tool, e.g. makes it harder to shift blame. As the author of the issue, the assigner and the asignee are known. Same for version control.

    As soon as the simplest tools and the simplest habbits get established, people start working together. Working together or not working together. Thats the big point.

    How good a certain guy at certain technology is, thats less important. That guy can learn or can be placed at a different work area. If you have such a guy you made your first mistake anyway allready. That again was a human issue (he tricked you in believing he is good, or you misjudged). So cope with it buy educating him or fix it by replacing him.

    It's fashionable to bash managers And rightfull so!
    For a software project you need no managers! At least not a manager in the traditional sense. A managers job is to get the staffing and the budget done right. Furher he has to be able to understand the development speed/quality of the team and communicate the teams results to the budget owners or customers. Most managers don't do that but make technical descissions about stuff they have no clue about! E.G. my latest project we used a JDO engine (of a so called market leader lol, well the simple piece of software costed Euro 500). We had hughe problems in certain areas of the software and spend about Euro 50.000 in internal development costs in working around those problems.
    The team wanted to switch to Hibernate. The manager descided: NO! This is in spite the fact that we made a thouroughfull investigation about costs and benefits and showed we start saving money after 3 weeks and would have speeded up the development process by spending less time in DB mapping etc.
    Thats just a simple example. So, we had a human issue again! The coders failed to communicate! The manager failed to understand!
    The project was close to run overtime, because of that issue. It was over budget because of that issue.

    Nevertheless Alan Cox is right in his analysis. Better coding habits and better strategies and better tools and better languages of course have an impact. The limit however are allways the humans.

    angel'o'sphere

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  29. Re:Unit testing? by rumblin'rabbit · · Score: 2, Insightful
    I disagree.

    First, it is not necessary for unit tests to be absolutely complete to be useful. Anything that finds a hitherto-undiscovered flaw is valuable - extremely valuable.

    Second, that there are bugs in a unit test is not, in practise, that big of a deal. At worst it means is you haven't tested a unit as thoroughly as you think you have. Unfortunate, but not a disaster. Perhaps two people should write their own units tests for a single module, and then compare the bugs they found in the module. An interesting experiment I think.

    My experience with unit testing is that it greatly speeds up the development process. Trying to get a half dozen classes all up and working simultaneously is an arduous task that can take god-knows-how-long. Trying to get one class up and working through unit tests is generally straightforward and predictable.

    And the quality of the component goes up. Waaaaaay up. It is rare when I write a unit test and don't catch at least one bug, thus easily paying for itself.

    It is not a case of unit testing versus reviewing. It should be a case of unit testing and reviewing.

  30. Re:Unit testing first by johannesg · · Score: 2, Insightful
    Hye, cal lyour pear pro gramign budy! You rtypign skils a ren t up to scrtach wehny our alon e!

    Man, if only there were unit tests for slashdot postings... Ah, wait, we have those (lameness filter!) and they don't help at all!

  31. Re:Unit testing? by richieb · · Score: 3, Insightful
    A solid requirements based development process and requirements based testing/verification process is the key to large high quality software.

    You tacitly assume that it is possible to get solid requirements. When writing avionics software, I'm sure you can, because the problem is well understood and we have good science/math to back it up (eg. GPS nav system).

    But in most sofware projects it is impossible to create requirement ahead of time, mostly because the problem you are trying to solve is new and we don't understand it well enough yet.

    Are there requirements for the web browser? Were they created before the code was written? WHat about requirements for MS Word?

    --
    ...richie - It is a good day to code.
  32. INTERFACES INTERFACES INTERFACES! by argent · · Score: 2, Insightful
    Good interfaces is why UNIX originally took off. Back in the '70s when you had to actually call the OS rather than just doing (say) Fortran formatted I/O, you had to do stuff like:

    Allocate a file control block. In assembly, this was usually done statically at compile time. In Fortran it was usually a global common.

    Call something like SYS$INIT%FCB

    Fill in half a dozen random fields in the FCB with magic numbers. Like, file mode, file type, access mode, device type, file name, file extension, file owner, file password, read key, write key, tape policy, ...

    Call something like SYS$OPEN%FILE, which may involve two or more calls. If It was a device, you might need to call SYS$ATTACH%DEVICE, for example, or SYS$LOCK%FILE...

    Repeat the above for an I/O control block. If the I/O control block doesn't contain a buffer, repeat the same for the buffer. You may need to allocate an event flag, or just pick one and hope that the same one wasn't used by another library. You may need to allocate a "mailbox" or other asynchronous I/O endpoint.

    Call the variant of SYS$READ%BLOCK for the file type or device type you're using. You could be calling SYS$READ%BUFFERED or SYS$QUEUE%IO followed by SYS$WAIT%IO.

    Do something with the buffer.

    Manually increment the block offset in the I/O control block.

    Repeat the reads until done.

    Release the I/O control block, and any event flags or mailboxes.

    Call SYS$CLOSE%FILE or SYS$RELEASE%DEVICE or whatever.

    On UNIX you did this instead:
    int fd;
    char buffer[BUFSIZ];

    fd = open("file name",mode);
    if(fd != -1) {
    while(nr = read(fd, buffer, BUFSIZ) > 0) {
    do_something_with(buffer, nr);
    }
    close(fd);
    }
    This was revolutionary. Really. It's not perfect, but it's so much better than what we were using at the time that it's no wonder people couldn't wait for AT&T and re-implemented UNIX from scratch several times.

    This is the same kind of improvement we need in our interfaces for GUIs, databases, network services, and so on. Even the Berkeley socket interface is too complex... all those details of address formats and address structures? Those shouldn't be there... you should be able to do this:
    fd = open("/tcp/host.domain/http/options",mode);
    // or at least fd = tcpopen("host.domain","HTTP",sockopts);
    if (fd != -1) {
    ...
    close(fd);
    }
    Yes, there's libraries that do this, but they all have the same socket()...gethostbyname()...connect() stuff under the hood. This should be handled at the system call level.

    As for GUIs... Plan 9 is about the only one I've seen that looks like it's even trying to reach the level of clarity, safety, and consistency we need.
  33. Re:Quality by penglust · · Score: 2, Insightful

    What you say is mostly true. Managers often get on my nerves too. Especially at crunch time. I also know a few developers that actually expect the code they write will never fail.

    What ever the case, good management will know when to get involved and when not to. There are always signs of problems. As an example: Many years ago I worked at a company that was second marketing several different Unix machines under their own name. We did a lot of work to make them as compatable as possible to give customers a real choise. A whole group of tests were thrown together to try and test this. At any time over 80 percent produced some kind of failure messages on all or some of the different platforms. This was in the late 80's and 2 consultants were brought in to look at the test and failures. They were supposed to fix the tests where needed and report on real problems. 3 or 4 months later, on a saturday, I was trying to use the tests to validate some compatability changes I had made. They all passed. A couple of months before nothing had passed. I expected some success but not complete by a long shot. Every test I needed had simply been commented out in the latest snapshot of the tests. They had done nothing at all. When confronted they had no excuse but "we are still identifing tests that fail". They were gone about 2 hours later.

    Point being, I think most quality failures are from both managment and development being secretive, self serving and practicing a lot of CYA. I guess these are the reasons why I like OSS. Secretive and CYA has a very hard time occuring and self serving comes about because the programmer gets reconized for both managing and developing on a project far above industry standard quality levels.

    If you want an example of managment gone bad take a look at ISO 9000 time sinks.

  34. Re:Type Checking = false promises by dvdeug · · Score: 2, Insightful

    Heavy type-checking relies on the same theory that more buerocracy is the solution to quality.

    The earlier you catch a bug, the easier it is to fix. That's been proven. Heavy type-checking catches bugs at compile time. Dynamic type-checking may leave bugs until the user runs over them.

    Is the array row-first or column-first? If rows and columns are different types, then the compiler will tell me when I got it wrong. I don't find that chasing that bug later, when it could be anywhere in a thousand lines of code, is a more efficent way to quality. Sure, it means a few more casts when I want to add rows and columns, but I've never found that a problem.

    Type-checking doesn't always make the code harder to read. In a type-checking language, "if (a==0)" lets me know that a is a number. In several non-type-checking languages, a could be just about anything. It's possible that you can't figure out what a is, even after looking around the code; it's possible that the else part of that statement may have to deal with a being a list, or a record, or a string. There is no local checks you can make to discover that; you may have to read every line of code to discover what type a is.

  35. Re:Unit testing? by Anonymous Coward · · Score: 1, Insightful

    you (and many others) are confusing software requirements with design and implementation. if you can conceive it to write the code you *can* write some level of requirements. requirements are not the design of the system. a simple requirement can spawn many many many design decisions. however, in the end you want the software to meet the requirements, usually irrespective of the implementation that gets you there. what you find is that some design decisions are routinely made to meet a requirement, this does not make them the same.

  36. Quality is not profit by Anonymous Coward · · Score: 2, Insightful

    Stunned by the horrible quality of the software in the megacorp I work for, I was complaining to a dot-com millionaire friend of mine who got rich on a different company. It was enlightening.

    He related the experience of meeting one of their VPs. Turns out the VP was famous for having realized that every customer service call was an opportunity to SELL MORE PRODUCT. Their profits went up. Wooo-hooo! Writing SHIT CODE actually made them MORE MONEY.

    I realized it was the same with my company. On all the on-line forums I hear "I'd never buy any other brand. I once had this horrible problem, and their customer service was so responsive! They fixed the problem!" It never seems to occur to customers that if the product actually WORKED they wouldn't have needed to call support in the first place. Shit code boosts our profits, too. People get a warm fuzzy talking to good customer support, no matter how bad the technology is.

    There are other ways to benefit from bad code, especially if you dominate the market. Releasing a new version? If you botch the backward compatibility it forces everyone to upgrade! Profit!

    So, what's all this nonsense about better code?

  37. Re:Quality by penglust · · Score: 5, Insightful

    Been there, done that. I could not agree more. But I have had a number of good managers in the past. Did a stint as manager myself at one time. I backed off because, like you, I just plain like to be productive and I think like an engineer. This may it difficult to deal with those above me.

    My direct manager right now is acutally one of the best I have seen. The other 3 or 4 layers above are lost and clueless most of the time. Their buzz word at the moment is ISO 9000.

    I think your comments bring up another issue. F**k up move up is often not just a saying. I have made friends and lost friends in the past for my opinions but if one of my fellow programmers is just plain incompetent, lazy, or an ass hole then they need to go. I don;t encorage moving them to get them out of my hair. I have done this before and somehow I always ended up having to deal with them again.

    There is also the type that are just biding their engineering time till they can become a manager. I have generally found these guys to be less than worthless. They are usually garanteed to make the worst managers.

    These are the criteria I usually find good in a manager and tried to use as one:

    1. Have a good broad software background. If working at the kernel level (including driver) have a basic understanding of hardware

    2. Understand how software impacts the potential customers and their needs. Books have been written on this, most of them wrong.

    3. Know your employees and their stengths and weaknesses. Use this to build a team that can and will perform.

    4. Trust the team but keep track of everything anyways.

    5. Process is a must but it should be pretty lightweight. Make it enforcable and do not waiver in ensuring the necessary pieces occur.

    6. Insulate your engineers from most of the stuff above. Not all, just most of it. Usually controlling the flow will suffice (often this involves rumor squashing).

    OK enough for now.

  38. Alan Cox doesn't get it... by renehollan · · Score: 2, Insightful
    ... which surprises me because he is one smart dude.

    All his points are valid, but (a) dangerous when taken as gospel, and (b) miss the forest for the trees.

    What kills software is complexity. I've been writing code professionally (i.e. getting paid for it) since I was 15. It's been 28 years. Starting with Dijkstra's "GOTOs Considered Harmful", I've seen fads to improve software reliability come and go: structured programming, object-oriented programming, garbage collection to handle memory leaks, etc; as well as programming languages prividing the syntactic and semantic sugar to support the fad du jure. Hasn't helped, has it?

    The general problem is one of managing complexity: if you can "come from" anywhere to a snippet of code, how can you ensure that all your assumptions about the context you're in are valid? Similarly, if you can access a global variable, well, globally, how can you be sure it contains what you expect? How do you know all the ways your data can be accessed? How do you control when and where an object is destructed, or that all resources (memory being just one) are freed?

    Either restrict who can do what, or restrict the assumptions you make about the things you are operating on.

    Using a garbage collector restricts who can allocate and deallocate memory. Object oriented programming restricts who can muck with private members. Structured programming restricts how you can get somewhere. O.K. wise guy, how are you going to write a garbage collector without dealing with raw memory? Gee, you have to get your hands dirty. How are you going to deal with private members inside private member functions? Gee, looks a lot like functional programming with globals, doesn't it?. How, the heck are you going to compile that loop without a jump at the end? Gee, what was that about GOTOs?

    The trend appears to be to try to find the "next great technique" which will provide the best bang for the buck when improving quality. All of them help. None of them enough. Frankly, this incremental approach is not going to solve the problem of defects that are a result of the product of human error and code complexity. We need to learn how to manage complexity on its own.

    Are there any examples of success in managing complexity, and can we learn from them?

    I think so.

    The best example I can think of is a compiler. Look at how many different inputs it can handle and still produce correct machine code with a fairly low defect rate. I attribute this to the fact that its input is highly structured: it has to follow strict syntactic rulers. Thus, when compiling something, one has a great deal of knowledge about the context in which this occuring. Yes, you have to deal with semantic issues (types, declarations, etc.), but an unambiguous language should make this clear.

    One can point out that programming languages are well-specified, so implementing a compiler is relatively easy. If only all requirements were so detailed. I don't think that's it, however: one can come up with very detailed specifications for a complicated system that's difficult to implement. A programming language, by contrast, can be syntactically expressed in a few pages of BNF.

    Contrast this with a user interface, where various elements need to be enabled or disabled depending on what other elements have been previously activated, or used to gather data. How easy or difficult is it to "forget" to enable or disable a control? If you see a parallel with this problem and excessive use of GOTOs in a program, you're starting to get a feel for what I'm talking about.

    What has happened in the past 25 years or so of programming language evolution is that the complexities of the past have been pushed and morphed into the complexities of the present. And tackling one in isolation (memory management) does nothing for a transformation of the same problem (resource management in general -- memory isn't the only thing that leaks), though it may provide the best bang defect-rate-reduction-wise

    --
    You could've hired me.
  39. Re:Unit testing? by dubl-u · · Score: 2, Insightful

    But I've come to realize, it [unit testing] just doesn't help to reduce big errors in system level design.

    That's like saying that street maps don't tell you what the continent looks like. It's technically true, but it seems to miss the point.

    Unit tests are for testing relatively small chunks of work. If you want to be sure the pieces work together, you do testing at higher levels. I think both are necessary for a solid system.

    Personally, I think of my high-level tests as executable requirements. Every time I check in code, a server makes sure that all our tests, both unit and end-to-end, run happily. That's a big step up from the traditional requirements phone book that most people don't use except as an aid to yelling at someone.

  40. Re:Quality assurance is dead. by dubl-u · · Score: 2, Insightful

    In particular, programming methodologies such as Extreme Programming that require greater management involvement in the coding process will be treated with scorn; management wants less involvement, not more. As to whether or not the code actually works - once it's out the door and bonuses are in hand, who cares?

    Well, for one, companies that want to make money. A company may be able to get away with shipping crap for a little while, but it's rare that somebody can do it for long. Why? It's not just that customers notice. A cruddy code base is hard to build on, so low initial quality means slow development for the life of the code base.

    Once a manager has experienced doing a project right, it's pretty rare they want to go back to the old, painful, unproductive way of doing things.