• AGray (unregistered) in reply to G

    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...

  • Jim boi (unregistered) in reply to Dave
    Dave:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.

    I tend to agree, but that's a very different case to that mentioned in the article:

    The Article:
    solely to duplicate the behavior
    Ya but that be çause the poster didn't know why it was like that. When testing, the class is substituted for one that returns predictables results. Often easier to substitute one of your own classes than one you might rely on (possibly for someit else) elsewhere
  • Manic (unregistered) in reply to Not sure if Fry or just Philip
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar) public final static or whatever length = 205;

    Even better, use javadoc.

    I would comment as you did, but then still do = 199 + 6. In this example it's trivial, but you don't want to make a calculation mistake (one that would be more noticeable if the code is not consistent with the comment).

    TBH (as many others have sadi before me), I think I'd generally split it into several constants: [code] /* Message = Header (sender, msg ID 10 char) + 100 for body (although most messages will be 50, we support sending 2 Customers in one message) + Footer (for whatever reason the protocol requires two byte tail) */ public final static int MSG_HEADER_LEN = 10; public final static int MAX_MSG_BODY_LEN = 100; public final static int MSG_FOOTER_LEN = 2; public final static int MAX_MESSAGE_LEN = MSG_HEADER_LEN + MAX_MSG_BODY_LEN + MSG_FOOTER_LEN; [code] It costs little or nothing, and is clear why we set message length to a particular value (without the developer having to think about what the specific value is).

  • aeryh (unregistered) in reply to Not sure if Fry or just Philip
    Not sure if Fry or just Philip:
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar) public final static or whatever length = 205;

    Even better, use javadoc.

    Oh, now that makes perfect sense, thanks!

    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const. On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.
    Wha? So the compiler is more likely to make a mistake than the dev?
    Why wouldn't you rely on the compiler to do the math - you are, after all, (likely) relying on the compiler to correctly create instructions to do other more complicated math.

    Sure your name didn't used to be geoffery?

  • Dongle (unregistered) in reply to Matt Westwood
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?

    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=46060". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.

    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS

  • JJ (unregistered) in reply to Flink
    Flink:
    It's a code obfuscation technique....makes it more difficult for someone who is specifically searching for 205 in a binary...not much more difficult, perhaps, but more difficult all the same.
    ...

    If you're a troll, You're Doin' It Right(TM). If you're serious, step away from the computer and never program again.

  • Dongle (unregistered) in reply to Dongle
    Dongle:
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?

    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=46060". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.

    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS
    With a comment above explaining it is currently set to 4 hrs...eg: [code] // Timeout = 4hrs #define CACHE_TIMEOUT_SECS 46060

  • (cs) in reply to Dongle
    Dongle:
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?

    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=46060". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.

    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS
    (snigger) he said SECS

  • (cs) in reply to Dongle
    Dongle:
    Dongle:
    Matt Westwood:
    Jay:
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?

    No, so that it is clear where the constant came from.

    As others have said on here a bazillion times, a constant like TWO_MINUTE_CONSTANT is a bad name, only slightly better than "const int TEN = 10". A more likely name would be, say, "CACHE_TIMEOUT". So suppose I see "CACHE_TIMEOUT=46060". That clearly tells me that we're counting 4 of something that normally comes in packets of 60 which in turn come in packets of 60. I can quickly guess that this likely means 4 hours. But what if I see "CACHE_TIMEOUT=14400"? Where did that number come from? Is it second, milliseconds, hours? Or is it not a time at all, maybe it's the maximum number of entries to leave in the cache when the timeout expires. Etc etc. It's little pieces of self-documentation like that that make the difference between easy-to-read code and hard-to-read code.

    Almost there - CACHE_TIMEOUT_SECONDS would be better. Then the obviousness is even more blinding.

    CACHE_TIMEOUT_SECS
    With a comment above explaining it is currently set to 4 hrs...eg:

    // Timeout = 4hrs
    #define CACHE_TIMEOUT_SECS 4*60*60
    Actually what you might want to do to be *really* bleedin' obvious is: [code] #define CACHE_TIMEOUT_HRS 4 #define HRS_TO_SECS 60 * 60 #define CACHE_TIMEOUT_SECS (CACHE_TIMEOUT_HRS * HRS_TO_SECS)

    ... or some such buggery. It's neater in some other languages.

  • Fer (unregistered) in reply to Mike

    I don't know, but the random generator that will random generate it, good random generator will be!

  • picka (unregistered) in reply to wbrianwhite
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.

    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time. Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?

    Reading comprehension not your forte'?

    What Ol' Frank is saying is that you FIRST test that the specific issue reported is fixed (this might be checking that the issue with 12321232 is fixed). THEN you test to make sure everything else still appears to work - this would include the normal testing of edge cases (0, Max valid value, max valid value+1, etc) as well as (probably seeing as we use Random Numbers) some testing to satisfy yourselves that with Random Numbers things still work (and although I agree with some people who say it's not the Random Number Generation that we're testing, I think at least some testing with the real random Number generation is worthwhile if nothing else to maximise the chance of catching a hitherto unthought of error)

  • Cynic (unregistered) in reply to KattMan
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?

    Because they are developers not testers - and let's face it, even many testers are crap

  • Oh dear (unregistered) in reply to Dave
    Dave:
    enim is Latin for "truly"
    I thought it was short for enema
  • Ryan (Original Poster) (unregistered) in reply to AGray

    The constant in question is actually defined at method level, which to me was a WTF for sure, especially when you sprinkle in the magic number.

    Further, the 199 + 6 magic number was not commented to explain anything about it.

    Captcha: erat - e-rat?

  • Oh dear (unregistered) in reply to Jack
    Jack:
    Lurch:
    wbrianwhite:
    KattMan:
    Why does it not surprise me thagt so many here have no idea how to really unit test?

    A random number generator should be replaced with a repeatable series generator when testing the code that uses it's results, but then you do still need to test the randomness of the generator in a separaate test.

    Now randomness is usually not needed in business applications, but maybe there are a few cases that need it. In those cases I'm sure it is not a case of "What happens when this particular number is generated?" but rather "What happens when the same number is generated back to back?" You can't test this using the generater directly, remember you aren't testing the generator here, but rather the code that uses the results.

    In other apps, let's say game simulators, you may do something specific with the random number generated, but then you are usually using a small generation range, like 1-6 or maybe 1-52 for card sets. In this you want a test that passes each value into the test for the code that uses the result.

    In neither case are you testing the randomness of the generator, you are testing the code that uses the results. The random number generator for production should be tested sepratly to make sure it reaches a good level of randomness for your usage.

    Why can't people understand this?

    So if you're testing an online poker bot, the best way to test it is with a series of games where the other players always have the exact same hands? Seems like an excellent way to introduce algorithm errors where the algorithm works well in those specific cases but would fail elsewhere. If you want to say that is integration testing's job that is fine, but not many shops have a formal integration testing suite that is actually separate from unit tests. I could write unit tests for my code where my code would work on 4, 9, and 67 and put those in as the test values, but my could could just blow up on 5, 10, and 68 and that test suite would detect no problem.

    Also, please define "tested to be sure it generates a good level of randomness". How would you measure this? What is 80% random versus 85% random? If this was actually a quantifiable event, computers wouldn't be stuck with pseudo-random number generators. Generally all you can do is use a PRNG from a crypto library in preference to the universally flawed RAND built in language functions.

    Firstly, there are ways of testing random numbers. Second, you have a very poor understanding of regression testing. Third, I don't think you understand the concept of "universal". And, how would you know the quality of the "PRNG for a crypto library" anyway? (given you don't know how to test random number sequences). Indeed, (and this IS meant to be insulting), your comment is the real WTF here.

    And the reason computers are "stuck with pseudo-random number generators" is because computers are, by design, deterministic, and not random.

    But that only means you're stuck with psuedo-RNGs as long as you're using a purely software solution. There are devices that can generate true random numbers.

    http://www.idquantique.com/true-random-number-generator/products-overview.html

    Maybe there's no such thing as a truly random number.

    Weather phenomena and the like may be unpredictable because we don't fully understand all the factors that go into causing a particular event, not because there's some higher being rolling 14 sided dice...

    Perhaps a clearer example is traffic. Traffic is caused by coincidence, not randomness. A number of people make decisions that result in them being on the same transport infrastructure at the same time. Meanwhile, decisions dictating traffic light sequences (and other factors come into play).

    So what if "Random" is just our way of saying "inexplicable with our knowledge"? What if there is no random? What if Chaos Theory is the only truth? Sierpinski's Sieve is certainly an example of how even random events can be used to create predictable patterns. Even lotteries are not random (in fact I think they rarely even have "Random Distributions"), although I guess that movie's already been made....

    Short: Pillosophical - What is Random? If Random is simply "unpredictable" then perhaps there comes a time when more is understood and random ceases to exist.

  • Luiz Felipe (unregistered) in reply to Other Nagesh
    Other Nagesh:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.

    Or you could use multiple random number generators and randomly select the one to use for enhanced super-randomness.

    Dont do that, this will skew the statistics, and will not produce an perfect s-curve.

  • Luiz Felipe (unregistered) in reply to Karl
    Karl:
    C'mon guys it is staring you right in the face! How come nobody got it yet?

    // Sanity check

    If you are a sane person, when you look at the next line of code you will immediately delete it. Nobody has yet, therefore you and all your peers are insane.

    No programmer is a sane people

  • Jim (unregistered) in reply to AGray
    AGray:
    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...

    admittedly I'm mainly fmiliar with C so this new-fnagled exception type stuff might be a bit beyond me, however....

    One of the probelms (as I see it) with Exceptions is that some programmers decide (rather than shutting cleanly, and perhaps displaying a quasi-useful explanation for Tech Staff) they think they should try to recover the irrecoverable.

    We recently had an incident where a (fairly critical) database error occured (corrupt data file, I think). Whoever had written our code (thankfully about 12 years before me, so it wasn't I) had a check in place to break out of a loop on a Database (or any) error. Unfortunately, this meant that we exited the loop and assumed life was normal (ie DB transactions had successfully) and a whole lot of mess ensued.

    Granted, an Exception in the Java/C# sense might have meant that this was caught rather than ignored, however one way or another the behaviour has to be to do no more processing - even if that means the system doesn't work for the user!! If something is broke, then make it break for the user, don't try to pretend the world is happy...

    That said, not all errors/exceptions are (or should be) fatal, but I think there are times when you want them to be.

  • blowhole (unregistered) in reply to AGray
    AGray:
    Constants in a class may or may not be a WTF - I'd honestly rather deal with a constant defined at the class level (preferably, in a Constants region) where I can easily find, identify, and maintain it, than have to sift through a bunch of code to find a method-level constant.

    The value of that constant though...I think that's TRWTF.

    Captcha: enim - must be Eminem's little brother.

    A constant in a class is standard procedure. In a non-static context though, well that would be silly.

  • blowhole (unregistered) in reply to Jim
    Jim:
    AGray:
    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...

    admittedly I'm mainly fmiliar with C so this new-fnagled exception type stuff might be a bit beyond me, however....

    One of the probelms (as I see it) with Exceptions is that some programmers decide (rather than shutting cleanly, and perhaps displaying a quasi-useful explanation for Tech Staff) they think they should try to recover the irrecoverable.

    We recently had an incident where a (fairly critical) database error occured (corrupt data file, I think). Whoever had written our code (thankfully about 12 years before me, so it wasn't I) had a check in place to break out of a loop on a Database (or any) error. Unfortunately, this meant that we exited the loop and assumed life was normal (ie DB transactions had successfully) and a whole lot of mess ensued.

    Granted, an Exception in the Java/C# sense might have meant that this was caught rather than ignored, however one way or another the behaviour has to be to do no more processing - even if that means the system doesn't work for the user!! If something is broke, then make it break for the user, don't try to pretend the world is happy...

    That said, not all errors/exceptions are (or should be) fatal, but I think there are times when you want them to be.

    I like exceptions and find them useful. As a programming feature, they do make sense. Primarily because it deals with the problem that based on what you're returning, it might be hard to have a consistent way of reporting errors (no error channel). In a strongly typed traditional language it makes the most sense. In a weakly typed language you could return an error object instead of the normal return type ultimately to the same effect.

    If you think that it means no more processing can be done or that the program should just crash I have to disagree with that. Some things can be recovered, or more likely ignored. Especially in the context of where you are doing things in parallel and a failure somewhere shouldn't bring down the entire program (as it wouldn't affect anything else). When it comes to programming people are more often at fault than their tools. Don't make the mistake of blaming tools because they can't fight back.

    There's really nothing wrong with handling errors, no matter the criticality, as long as you are actually handling them. However it is something that can be horribly abused.

    Probably the most common abuse:

    try do_everything_under_sun();
    catch(Exception) do_one_thing_irrespective_of_error_details();
    

    An ambiguous abuse:

    try do_something();
    catch(Exception) do_nothing();
    

    This isn't always an abuse, remember that throw is like an extra return channel and sometimes you just aren't always interested everything that gets returned. However, sometimes people ignore what is being returned hen you really shouldn't. A more common mistake is being too unspecific about the type of Exception that you want to ignore. To give an example of where you may want to reasonably ignore a throw, when closing a socket.

    The most fubar thing I ever saw was where someone had apparently used every error handling system under the sun.

    method x() {
        try {
            y = ob.do_something();
    
            if(y == -1) throw new Exception();
    
            z = ob.do_some_more();
    
            if(z.isError) throw new Exception();
        }
        catch(Exception ex) {
            this.isError = true;
            this.errorMsg = "Blah blah.";
            return -1;
        }
    }
    

    It's been a while now since I was working with that but it was something like the above but probably worse. You could never be too sure in any instant what you had to do to detect an error. Some things would let it be throw up the stack, some not. Being in a high level language made things even worse. I'm sure someone once thought this was a clever pattern but the net result was having to implement error checking at every level from the callee up through every caller when not having to do that is one of the key benefits of throwing exceptions.

    I have since decided that I would rather spend the rest of my life on the dole and only program for personal enjoyment.

  • blowhole (unregistered) in reply to G
    G:
    like the System.Environment.Exit calls peppered throughout library code that causes the app to inexplicably exit.

    I'm no .NET expert, but it seems to me exits caused by a function called "Exit" seem perfectly explicable to me...

    I think he means without any explanation. A very common malpractice. Something went wrong? Go with the bare minimum exit strategy.

    Considerate programmers have the common decency to in the very least have a print() before exit() or use a procedure to the effect of printThenExit(message).

  • Major DoucheBag (unregistered) in reply to KattMan
    KattMan:
    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random.

    It's good to know that you have no concept of what random is.

  • fs (unregistered) in reply to Major DoucheBag
    Major DoucheBag:
    KattMan:
    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random.

    It's good to know that you have no concept of what random is.

    I agree - to a point.

    All of those results could be randomd (unlikely, perhaps, but possible). If you always got those result I'd start to worry, but still could be random....

    I don't knwo whether you're (@kattman not MDB) aware of this, but people do actually win the lottery occasionally. Some people win it multiple times. It would be possible to win it with the integers from 1 to n (where n= the number of numbers required to win).

  • (cs) in reply to picka
    picka:
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.

    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time. Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?

    Reading comprehension not your forte'?

    What Ol' Frank is saying is that you FIRST test that the specific issue reported is fixed (this might be checking that the issue with 12321232 is fixed). THEN you test to make sure everything else still appears to work - this would include the normal testing of edge cases (0, Max valid value, max valid value+1, etc) as well as (probably seeing as we use Random Numbers) some testing to satisfy yourselves that with Random Numbers things still work (and although I agree with some people who say it's not the Random Number Generation that we're testing, I think at least some testing with the real random Number generation is worthwhile if nothing else to maximise the chance of catching a hitherto unthought of error)

    The part I was objecting to was:

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.

    Which seemed to forbid testing with random numbers and insist on using a fixed set of predetermined numbers

    Addendum (2012-05-18 00:50):

    picka:
    wbrianwhite:
    Frank:
    snoofle:
    Severity One:
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.
    Would you mind giving an example where a non-random random number makes sense?
    If you want to write a test where you need predictable results, then you'll need to know the "random" inputs in advance.
    Almost got there snoofle.

    Everyone should know the answer to this question. If you don't, you're Doing It Wrong. (Or never worked with random numbers.)

    Think about your workflow. You write software. You test it. It goes live. Someone finds a bug. You fix it. You test it again.

    What is the goal of that last test?

    Hmmm?

    Are you sure?

    If you answered "to confirm the bug is fixed" you lose. Well you get half points, which is 50%, which is an F in most classes.

    The answer is "to confirm the bug is fixed and to ensure no new bug is introduced, or other old bug came back".

    How do you do that? You save the results of the "before fix" test and compare them with the "after fix" test. Only one thing should have changed. The badness should now be goodness. No other new badness.

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.

    So 12321232 causes a problem, add a unit test that generates 12321232 every time.
    Next month, 098098908 causes a problem, add a unit test that generates 098098908 every time. Repeat ad infinitum. Never have a test suite that runs N times generating actual random numbers every time, because that will only find actual bugs, rather than being repeatable. That doesn't seem right.

    You know, every time your browser opens an HTTPS connection you send a random number to the browser to be used in establishing the connection. If you were unit testing the TLS protocol, would you generate the same number every time? It would miss the thrust of what you were trying to test wouldn't it?

    Reading comprehension not your forte'?

    What Ol' Frank is saying is that you FIRST test that the specific issue reported is fixed (this might be checking that the issue with 12321232 is fixed). THEN you test to make sure everything else still appears to work - this would include the normal testing of edge cases (0, Max valid value, max valid value+1, etc) as well as (probably seeing as we use Random Numbers) some testing to satisfy yourselves that with Random Numbers things still work (and although I agree with some people who say it's not the Random Number Generation that we're testing, I think at least some testing with the real random Number generation is worthwhile if nothing else to maximise the chance of catching a hitherto unthought of error)

    The part I was objecting to was:

    Now, if you have random numbers in the mix, most likely every run will be different. So how can you compare the output? Huh??

    See, if you'd ever done proper testing against random numbers, you'd know you have to generate a known repeatable random number (or sequence) during this type of testing.

    Which seemed to forbid testing with random numbers and insist on using a fixed set of predetermined numbers. And testing with ACTUAL random numbers should be part of the regression.

  • (cs)

    Damn this site code

  • (cs)

    I do that sometimes, when the individual numbers have some meaning to them. Although generally I'd leave a comment saying that too.

    I guess more correctly you should define the two numbers as constants with meaningful names in their own right, and then define the third as a compound...

  • d (unregistered)

    I'm not necessarily seeing a WTF here. While 205 may be just as good as 199+6, it's not as readable - say 6 is a header size, 199 is the data size and such.

    As for constants in a class: Why not?

  • (cs) in reply to d
    d:
    I'm not necessarily seeing a WTF here. While 205 may be just as good as 199+6, it's not as readable - say 6 is a header size, 199 is the data size and such.

    As for constants in a class: Why not?

    The main WTF is that nowhere in this class is a message explaining exactly what these numbers actually mean. Unexplained magic numbers are a major WTF in my book, all the worse for being so common, the result of a programmer too lazy or impatient to exercise basic human politeness.

  • DanDan (unregistered) in reply to Mike

    It should be selected at random.

  • (cs) in reply to Dan Minjoc
    Dan Minjoc:
    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24; const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.

    In C / C++ on a 16-bit system, the first is wrong, because it says a day is 20864 seconds long.

    (Hint: undecorated integer constants have type int if possible, and int is allowed to be 16 bits in C and C++. The promotion to uint32 is done after the multiplication. Fix it as 60L60L24L, then do something to fix the dumb compiler's loss-of-precision warning on a system with 64-bit longs...)

  • Vamp (unregistered) in reply to dkf
    dkf:
    Vamp:
    I have done that with constants before. For example timeouts or similar:
    const int TWO_MINUTE_CONSTANT = 2 * 60;
    Makes it easier to read for me later. Maybe it was something similar for those 2 values :)
    Plus all the bonus fun you get when some manager decides that the timeout now has to be 5 minutes, so you update that to read:
    const int TWO_MINUTE_CONSTANT = 5 * 60;
    The moral is “use the meaning in names, not the value”…

    Oh wow, didn't think people here would take my sample so literally :P of course I don't name my consts that way in real code. I just named it like that so it would be clear why I used 2 * 60 and not 120. I guess i should've written SOME_RANDOM_CONSTANT_FROM_CODE, maybe then it would be clear.

  • BlackKnight (unregistered) in reply to The Great Lobachevsky
    The Great Lobachevsky:
    Speakign of sanity - am I the only one whose page up and page down keys inexplicably aren't working on this site anymore? (granted, I'm forced to use IE7, which causes all sorts of weird things)

    Working fine for me, but I'm using IE 8. Time you got a modern browser.

  • (cs) in reply to fs
    fs:
    Major DoucheBag:
    KattMan:
    Exactly, you know this, I know this, Lurch knows this, Brian seems to miss it. You are expecting a reasonable facsimili of randomness. How do you measure it? Well your specs should tell you how. Let's say you have a generator to give you a number between 1 and 100, if you get 100 different numbers you aren't random, you are picking from a pool and that pool is getting smaller each time. If you get 100 6's once again you aren't random, if you get the same 10 numbers, you aren't random.

    It's good to know that you have no concept of what random is.

    I agree - to a point.

    All of those results could be randomd (unlikely, perhaps, but possible). If you always got those result I'd start to worry, but still could be random....

    I don't knwo whether you're (@kattman not MDB) aware of this, but people do actually win the lottery occasionally. Some people win it multiple times. It would be possible to win it with the integers from 1 to n (where n= the number of numbers required to win).

    Wow is this captian douchbag and Fapper Sidkick? Yes these results all the time would not be random, even getting them once should throw a red flag for testing, but that does not mesn I have no idea what random is, it actually makes me think I know it more than you based off of a very small sample set, that set being the last posts by the two of you.

  • LittleChild (unregistered) in reply to Zylon
    Zylon:
    Vamp:
    I have done that with constants before. For example timeouts or similar:

    const int TWO_MINUTE_CONSTANT = 2 * 60;

    Makes it easier to read for me later.

    So, in case at some point in the future you forget what "TWO MINUTES" means?
    At some point in the future there'll be a Ministry of Love to remind us all about the 2 minutes.

    //sanity dump int ROOM = 101;

  • AGray (unregistered) in reply to Jim
    Jim:
    AGray:
    I am a .NET developer, but I don't see why you would want to kill the application unless the user has kindly asked the app to stop running.

    If they're there as a defensive measure, then this becomes TRWTF; Exceptions/Try/Catch/Finally can take care of that.

    CAPTCHA: Sagaciter - One who quotes sagas, I would guess...

    admittedly I'm mainly fmiliar with C so this new-fnagled exception type stuff might be a bit beyond me, however....

    One of the probelms (as I see it) with Exceptions is that some programmers decide (rather than shutting cleanly, and perhaps displaying a quasi-useful explanation for Tech Staff) they think they should try to recover the irrecoverable.

    We recently had an incident where a (fairly critical) database error occured (corrupt data file, I think). Whoever had written our code (thankfully about 12 years before me, so it wasn't I) had a check in place to break out of a loop on a Database (or any) error. Unfortunately, this meant that we exited the loop and assumed life was normal (ie DB transactions had successfully) and a whole lot of mess ensued.

    Granted, an Exception in the Java/C# sense might have meant that this was caught rather than ignored, however one way or another the behaviour has to be to do no more processing - even if that means the system doesn't work for the user!! If something is broke, then make it break for the user, don't try to pretend the world is happy...

    That said, not all errors/exceptions are (or should be) fatal, but I think there are times when you want them to be.

    I can agree to that.

    In the context of the story, though, when the app 'inexplicably' exits, that sounds to me like evidence of overuse of exiting the application.

    I can add that I think when an app enters an unrecoverable state, before it exits it should tell the user that the world is no longer happy and the app cannot continue operating. Inexplicable exits cause the user/customer huge WTF moments, which translate into those irritating 3 in the morning irate calls.

    CAPTCHA: Appellatio - the Harry Potter spell for turning naughty coders into apples!

  • Joe (unregistered) in reply to Lurch
    Lurch:
    Says Joe:

    "You run the test 10 billion times so that you know you're testing every random 32-bit number (to within 5%) that might come up in production.

    This also gives the advantage of never finding another problem during your career, and/or inflating the "number of tests passed" metric that you get a bonus on."

    10 billion times? But there are only 4 billion 32 bit numbers (float or integer, doesn't matter, we are counting bit patterns)! So, you get OVER 200% coverage.

    Learn something about randomness.

    With only 65000 randomly-selected 32-bit numbers, you have over 50% probability of a duplicate. The probability of getting all 4 billion different values by selecting only 4 billion samples is quite small.

    --Joe

  • rpl (unregistered) in reply to Joe
    Joe:

    Learn something about randomness.

    With only 65000 randomly-selected 32-bit numbers, you have over 50% probability of a duplicate. The probability of getting all 4 billion different values by selecting only 4 billion samples is quite small.

    Learn something about random number generators. The output of a PRNG is a deterministic function of its state vector. Therefore, a PRNG with a 32-bit state vector must generate every value it is capable of generating within 2^32 iterations (possibly far less, if the generator is a crappy one). This is undoubtedly what Lurch was referring to.

    On the other hand, Lurch might want to bear in mind that just because a PRNG outputs 32-bit values doesn't mean it has a 32-bit state vector. In fact, a 32-bit state would result in a very poor generator, since it will start failing tests for correlation within a few hundred million iterations, which is well within the range of normal usage.

  • Marc (unregistered) in reply to Christian
    Christian:
    in my opinion it makes perfect sense to encapsulate something like a random-number generator in your own class, this way you can replace this component with one that returns a "random" number which you can control in your unit-tests.

    Especially if you have a large application that contains bits written in a mix of languages. Having a random generator that can be called with a fixed seed might not be enough. You may run into situations where you need a random generator that behaves identical, regardless of the language a snippet of code was written in. Unfortunately, you can't rely on system libraries across languages to have the same implementation.

  • 7eggert (unregistered) in reply to Mike
    Mike:
    Other Nagesh:
    Or you could use multiple random number generators and randomly select the one to use for enhanced super-randomness.

    But which random number generator would you use to select which random number generator to use for your super random number generator?

    You'd use The One RNG.

  • Jack (unregistered) in reply to Oh dear
    Oh dear:
    Maybe there's no such thing as a truly random number.

    Weather phenomena and the like may be unpredictable because we don't fully understand all the factors that go into causing a particular event, not because there's some higher being rolling 14 sided dice...

    Perhaps a clearer example is traffic. Traffic is caused by coincidence, not randomness. A number of people make decisions that result in them being on the same transport infrastructure at the same time. Meanwhile, decisions dictating traffic light sequences (and other factors come into play).

    So what if "Random" is just our way of saying "inexplicable with our knowledge"? What if there is no random? What if Chaos Theory is the only truth? Sierpinski's Sieve is certainly an example of how even random events can be used to create predictable patterns. Even lotteries are not random (in fact I think they rarely even have "Random Distributions"), although I guess that movie's already been made....

    Short: Pillosophical - What is Random? If Random is simply "unpredictable" then perhaps there comes a time when more is understood and random ceases to exist.

    Maybe nothing is truly random. But all the best evidence at the moment is that quantum mechanics is: it is impossible to have any information before the event that will enable you to accurately predict the outcome.

  • (cs) in reply to Steve The Cynic
    Steve The Cynic:
    Dan Minjoc:
    Which would you rather have?

    const uint32 NUM_SEC_IN_DAY = 60 * 60 * 24; const unit32 NUM_SEC_IN_DAY = 86400;

    Both are correct, but the first one shows exactly where the calculation is coming from.

    In C / C++ on a 16-bit system, the first is wrong, because it says a day is 20864 seconds long.

    (Hint: undecorated integer constants have type int if possible, and int is allowed to be 16 bits in C and C++. The promotion to uint32 is done after the multiplication.

    Well in that case, the second one will also be truncated, won't it?

  • (cs) in reply to Turd Blossom
    Turd Blossom:
    const maxVolume = 10 + 1;
    (That's ridiculous. It's not even funny.)
  • Lacrymology (unregistered) in reply to Zylon

    well, no.. but you can do

    const int TIMEOUT_SECONDS = 2 * 60;

    because your API takes the timeout in seconds, and you want anyone who happens to read the code to know you're setting up 2min without having to do the math.

    Personally, I always initialize a double-buffered 32bit screen memory like so:

    buf = (byte *)alloc(640 * 480 * 4 * 2);

  • (cs) in reply to Jack
    Jack:
    Oh dear:
    Maybe there's no such thing as a truly random number.

    Weather phenomena and the like may be unpredictable because we don't fully understand all the factors that go into causing a particular event, not because there's some higher being rolling 14 sided dice...

    Perhaps a clearer example is traffic. Traffic is caused by coincidence, not randomness. A number of people make decisions that result in them being on the same transport infrastructure at the same time. Meanwhile, decisions dictating traffic light sequences (and other factors come into play).

    So what if "Random" is just our way of saying "inexplicable with our knowledge"? What if there is no random? What if Chaos Theory is the only truth? Sierpinski's Sieve is certainly an example of how even random events can be used to create predictable patterns. Even lotteries are not random (in fact I think they rarely even have "Random Distributions"), although I guess that movie's already been made....

    Short: Pillosophical - What is Random? If Random is simply "unpredictable" then perhaps there comes a time when more is understood and random ceases to exist.

    Maybe nothing is truly random. But all the best evidence at the moment is that quantum mechanics is: it is impossible to have any information before the event that will enable you to accurately predict the outcome.

    Quantum mechanics is probabilistic. You know that there is about a 25% the the electron will be in orbit x, or other such statement about a physical system. Probabilistic isn't the opposite of random but it's still pretty far away.

  • (cs) in reply to blowhole
    blowhole:
    G:
    like the System.Environment.Exit calls peppered throughout library code that causes the app to inexplicably exit.

    I'm no .NET expert, but it seems to me exits caused by a function called "Exit" seem perfectly explicable to me...

    I think he means without any explanation. A very common malpractice. Something went wrong? Go with the bare minimum exit strategy.

    Considerate programmers have the common decency to in the very least have a print() before exit() or use a procedure to the effect of printThenExit(message).

    Even then you should never ever use System.Environment.Exit directly unless you are dealing with the simplest of all terminal programs. The fact that the user account that is running the program requires SecurityPermissionFlag.UnmanagedCode to call Environment.Exit should tell you plenty about the nature of the problems surrounding it:

    Calling Exit does not shut down the process's application domain cleanly. It doesn't terminate processes started from your process, kills managed threads, doesn't call Dispose or run finalizers to take care of unmanaged resources and doesn't run code in finally blocks. It stops everything stone cold and can potentially leak a lot of system resources (Like file handles, window handles, sockets, memory from various types of in-memory stream, etc.)

  • (cs) in reply to Zylon
    Zylon:
    So, in case at some point in the future you forget what "TWO MINUTES" means?

    Must be ... since that is so much more likely than forgetting what "2*60" represented in that particular case.

    Sarcasm aside, there is something to be said for going even further and embracing seemingly over-engineered DSL-ish typesafing stuff. Like, this is a minute, and by definition it has 60 seconds. Rather than just chucking integers about (which is still what you are doing even if you define them as constants). Not something I've had much experience of but seems like it does what the constant-mongers are trying to do, but with more success.

  • Barf 4eva (unregistered) in reply to Not sure if Fry or just Philip
    Not sure if Fry or just Philip:
    airdrik:
    Not sure if Fry or just Philip:
    Really guys, use the fucking comments if you want to explain magic numbers.

    // length is 199 (because of foo) + 6 (because of bar) public final static or whatever length = 205;

    Even better, use javadoc.

    Oh, now that makes perfect sense, thanks!

    Since there seems to be a misunderstanding, here's my point: Don't rely on the compiler to do your math. Show what you meant in the comment, and store the calculated result in the const. On the other hand, generic variables like "foo" and "bar" are the most evil variable names ever. While they're perfectly acceptable in short and meaningless examples, they should never, ever appear in production code. Except when they mean something, like spacebar or meter bar.

    Or if you are writing production code for helping people with introductory software books...

  • SG_01 (unregistered)

    Pfft, this one is too obvious. The code is obviously there to check the programmer's sanity. If you're too sane you will be hung up on this line too much.

  • Friedrice the Great (unregistered) in reply to BlackKnight
    BlackKnight:
    The Great Lobachevsky:
    Speakign of sanity - am I the only one whose page up and page down keys inexplicably aren't working on this site anymore? (granted, I'm forced to use IE7, which causes all sorts of weird things)

    Working fine for me, but I'm using IE 8. Time you got a modern browser.

    My employer just upgraded us from IE6 to IE7 ...

  • Friedrice the Great (unregistered) in reply to DaveK
    DaveK:
    Turd Blossom:
    const maxVolume = 10 + 1;
    (That's ridiculous. It's not even funny.)
    "But MY amp goes to 11." - Spinal Tap

Leave a comment on “Sanity Check”

Log In or post as a guest

Replying to comment #:

« Return to Article