Is It Worth Writing Unit Tests?

  • I think what a lot of people have missed here is that sometimes you won't be the only person to touch that code.

    you may write exceptional code the first time around, but if a future developer joins (after you have left) and decides to optimise that code (or do other things) then the unit tests may help to prevent future build issues or defects in the code.

    the unit tests eventually become the most granular level of functional requirement

    MVDBA

  • MVDBA (7/27/2015)


    I think what a lot of people have missed here is that sometimes you won't be the only person to touch that code.

    you may write exceptional code the first time around, but if a future developer joins (after you have left) and decides to optimise that code (or do other things) then the unit tests may help to prevent future build issues or defects in the code.

    the unit tests eventually become the most granular level of functional requirement

    Heh... but ONLY if the reason for the change wasn't in the form of a requirements change. Otherwise, the existing unit test is totally useless and actually may cause either bad code to be released or good code to be held back until the unit test is properly updated to test for the new requirement.

    And, that's why I don't care for what people are calling "Unit Tests". It doesn't make sense to have two pieces of code to maintain and get both right.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Heh... but ONLY if the reason for the change wasn't in the form of a requirements change. Otherwise, the existing unit test is totally useless and actually may cause either bad code to be released or good code to be held back until the unit test is properly updated to test for the new requirement.

    And, that's why I don't care for what people are calling "Unit Tests". It doesn't make sense to have two pieces of code to maintain and get both right.

    If the requirements are changing, you already know that your test is no longer valid and you fix your test so that it is testing for the proper thing. That's part of what let's everyone else know that the change is deliberate and it's doing what is intended and not a mistake.

    I've not seen bad code being released where a unit test is at fault, maybe you have? I have used them to discover bad code that's not behaving as advertised, however.

    You're correct about delays though, it generally delays code being released for several minutes in a case where the requirements have changed. In those cases, most of the tests are still valid and only one or two need changing.

    Anyway, I'm not suggesting that unit tests are right for everyone or the only answer, but it does seem like people are throwing out straw man arguments and jumping to a lot of conclusions. They do require additional work and they don't test every situation. They're not meant to be a replacement for that. That doesn't mean they're not useful.

    Yes, people have been testing code for decades without unit testing. People have also cooked delicious meals without a microwave and survived without the internet. That doesn't mean we can't benefit in some way with a newer methodology. Yes, you can write great code without it. There has also never been a shortage of bad code with or without unit testing.

  • It seems management weighs the cost of post-corrective action to hiring those needed to manage the testing and keeping a flow of new code. Once the acceptable failure rate has been reached, everything stays as it is.

  • Hi

    it's an interesting approch but does it works in my context ?

    For example, my app is made of SQL queries in C# Code (more than 800). I don't use stored procedures.

    That's to say, I must "duplicate" the business value in unit tests.

    Is it true ?

    Thank you for your vision

    Kind regards

    Arnaud

  • chris geswein wrote:

    Heh... but ONLY if the reason for the change wasn't in the form of a requirements change. Otherwise, the existing unit test is totally useless and actually may cause either bad code to be released or good code to be held back until the unit test is properly updated to test for the new requirement.

    And, that's why I don't care for what people are calling "Unit Tests". It doesn't make sense to have two pieces of code to maintain and get both right.

    If the requirements are changing, you already know that your test is no longer valid and you fix your test so that it is testing for the proper thing. That's part of what let's everyone else know that the change is deliberate and it's doing what is intended and not a mistake.

    I've not seen bad code being released where a unit test is at fault, maybe you have? I have used them to discover bad code that's not behaving as advertised, however.

    You're correct about delays though, it generally delays code being released for several minutes in a case where the requirements have changed. In those cases, most of the tests are still valid and only one or two need changing.

    Anyway, I'm not suggesting that unit tests are right for everyone or the only answer, but it does seem like people are throwing out straw man arguments and jumping to a lot of conclusions. They do require additional work and they don't test every situation. They're not meant to be a replacement for that. That doesn't mean they're not useful.

    Yes, people have been testing code for decades without unit testing. People have also cooked delicious meals without a microwave and survived without the internet. That doesn't mean we can't benefit in some way with a newer methodology. Yes, you can write great code without it. There has also never been a shortage of bad code with or without unit testing.

    Just to be clear, I'm not against unit testing.  I also don't care if unit testing causes a delay.  In fact, I'm a big supporter of "If it hasn't been tested properly (Unit testing before QA, Integrated Testing at QA and UAT), it doesn't get deployed to production".  We even do "emergency fixes" the same way but at a greatly accelerated pace.  It's a rare thing to need an "emergency fix" because we test the hell out of everything before it goes to production as well as making sure that we're not deploying any regressions in code.

    My concern is what happens when a requirement changes and the unit test code must also be changed to accommodate the new requirement... who's double checking to make sure the unit test code is actually testing the right things?  I realize that question could lead to never ending expansion of who or what tests the test code.

    And then, if the unit tests passes the code, you MUST do an integration test, as well.

    What I'm really getting at is that a lot of Developers that I've worked with at other companies think that they don't need to test their own code as they develop it because someone is going to "unit test" it and that usually leads to a vicious "throw it against the wall until it sticks" circle of spaghetti code and huge unnecessary amounts of rework and retest time compared to the Developer doing their own tests to make sure it actually works before it goes to unit test.

    The other point is that unless someone is doing configuration control on the unit tests, then the tests are frequently "not valid".

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • What I'm really getting at is that a lot of Developers that I've worked with at other companies think that they don't need to test their own code as they develop it because someone is going to "unit test" it and that usually leads to a vicious "throw it against the wall until it sticks" circle of spaghetti code

    Jeff, unit testing is done at build time by either the compiler or the build engine, I think you are talking about functional testing.

    MVDBA

  • MVDBA (Mike Vessey) wrote:

    What I'm really getting at is that a lot of Developers that I've worked with at other companies think that they don't need to test their own code as they develop it because someone is going to "unit test" it and that usually leads to a vicious "throw it against the wall until it sticks" circle of spaghetti code

    Jeff, unit testing is done at build time by either the compiler or the build engine, I think you are talking about functional testing.

    Call it what you will, it boils down to the same thing.  So far as I'm concerned, unit testing and functional testing of a unit are the same.  If you're testing it "insitu", then it's integrated testing.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Arnaud, how are you testing your app at present?  Do you have a unit testing approach to the non-SQL parts of your C# app?

  • MVDBA (Mike Vessey) wrote:

    What I'm really getting at is that a lot of Developers that I've worked with at other companies think that they don't need to test their own code as they develop it because someone is going to "unit test" it and that usually leads to a vicious "throw it against the wall until it sticks" circle of spaghetti code

    Jeff, unit testing is done at build time by either the compiler or the build engine, I think you are talking about functional testing.

     

    That something compiles or does not throw a syntax error is hardly the same thing as unit testing.  That is the bare minimum lazy developers do to say they've done their job and pass any issues on to someone else.

    • This reply was modified 5 years, 1 month ago by  ZZartin.
  • Interesting discussion. I'm a fan of unit testing for a few reasons, but not "over testing". Test what you are working on, which might be alter the test.

    Here's what I see at a lot of customers. Everyone tests their code. Someone says, sum the results by customer and if it's > x, apply a discount. Someone then goes:

    SELECT
    CustomerID
    , TotalSales = (SUM(ordertotal) - (CASE
    WHEN SUM(ordertotal) > 100 THEN
    SUM(ordertotal) * 0.1
    ELSE
    0
    END
    )
    )
    FROM Sales
    GROUP BY CUSTOMERID;

    They then do some select sum(ordertotal) from sales, look at some results, pick a customer, run their query, see if results match. Or if it's what they think. We're depending on a human to properly do some math here, or calculate things. What most developers do, even experienced ones, is assume the sum() works and they roughly look at the result. Sharp ones might ask if it should be [>] or [>=] or something else, but this is the type of calculation that's simple and full of mistakes over and over.

    This gets multiplied by the number of times we manipulate data in the db for some query.

    What a unit test asks, and what I'd ask, is that you set up 5 or 10 rows of data in a test, which is what many developers do by INSERT INTO SALES in their development process. Just put that in a test assemble section. Then calculate the results and stick them in the expected results section. That's what you do mentally anyway, though sometimes you don't do it well. Now, put the query in a test, or better yet, a proc that gets called in the test. That alone moves you along to better code that can be quickly tuned and captured in a central location rather than cut/pasted in multiple places.

    Now, does this guarantee the code is correct? As Jeff noted, no. This means we have, as David noted, captured the requirements as the developer sees them. That's a huge step. If we find things are wrong, we can now circle back with business people and discuss what's wrong. This is no different than not writing a test, except that the developer has codified the requirements, not likely mis-stated them in a comment, which might be interpreted differently later.

    If this where a SELECT customerid, sum(ordertotal) from sales group by customerid, I wouldn't test that. That's a relatively simple, core db function. If can't write this code, we have other training issues to deal with. I would see this as overtesting.

    Does it take longer to write tests? Yes, but not that much longer, especially as you develop some patterns and techniques for writing tests. More importantly, you can easily set up test data snippets that all developers share, so we are getting consistent testing and development from all of them. We can easily maintain these snippets in a VCS, just like we'd have other code. Again, this does take time, but the investment diminishes quickly once you start to build a habit. And, you find it's not much more time than developers spend manually testing code.

    Over time, a few customers say that because they maintain known testing sets, this actually saves time because all developers, especially new ones, don't have to think about data for many tests.

    More importantly, this gets developers to slow down and think about the code they are writing to achieve results. When we see clear results, we tend to write better code. I know when I see questions here on the forums, the explanation of how to get results pales in comparison to the actual results being seen themselves. We constantly ask posters to provide test data as inserts and a result set as results. This is what a unit test is.

    Ultimately, this is what helps a team of people stay more coordinated and understand regressions. Maintaining test code (and test data) along with other code is the price of doing business. Ideally, teams would function like these forums. One person write the tests based on requirements and give that to the other person to write the code. Now two people know what the requirements are and the team can see them codified later.

    I don't know that I think unit tests raise initial code quality much. They do get you to think in a more focused fashion , but really they prevent regressions, especially when a second person touches the code. Regressions are much less tolerable as we move to a more 24x7x365 world, asking for less downtime, and more reaction to changing customer requirements. Maybe more importantly, if I go to tune code, going from subselects or multiple nested views to a cleaner CROSS APPLY, the test provides some protection for me in refactoring.

    Does this mean the code is right? Again, no, but it does ensure my refactoring matches the original requirements, right or wrong.

  • Excellent post, Steve.  What we need now is someone that's an expert in QA or an expert system designer to provide people that write requirements with knowledge and techniques the write much better requirements.  It would make a great article and give us all a chance to hear from the people that have to put up with our code and, sometimes, our misunderstanding of the what requirements actually are.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff Moden wrote:

    Excellent post, Steve.  What we need now is someone that's an expert in QA or an expert system designer to provide people that write requirements with knowledge and techniques the write much better requirements.  It would make a great article and give us all a chance to hear from the people that have to put up with our code and, sometimes, our misunderstanding of the what requirements actually are.

    when you find that person, send me their CV.. I need them too

    MVDBA

  • ZZartin wrote:

    MVDBA (Mike Vessey) wrote:

    That something compiles or does not throw a syntax error is hardly the same thing as unit testing.  That is the bare minimum lazy developers do to say they've done their job and pass any issues on to someone else.

    I think you misunderstood me

    it's nothing to do with whether it compiles or not.

    for example if you decide to make a program to decide what type of triangle you have by putting in 3 lengths of sides.. your unit tests would automatically try negative values, zero length, impossible triangles etc... just to see if someone has broken the front end validation.  Unit testing does these when you write the function or (more importantly) modify it.

    I'm an ISEB ISTQB certified tester (although not all the time) - when the build engine tests for LOGIC errors inside a single block of code (as apposed to compile errors) then this is a unit test

    above that you have component tests (a group of blocks of code), then a component integration test (normally DLLs talking to each other) then a smoke/regression test to find what you broke while trying to fix it.

    then you have nonfunctional testing which is performance, durability and capacity

     

    MVDBA

  • David

    the non-SQL parts of our C# app are tested with a few unit tests and a lot of manual tests.

    We plan to reverse the quantity (unit testing first and manual testing for high value scenarios).

    We have no strategy for the SQL part. That's why I left my post here.

    Thank you for sharing your vision.

    Arnaud

Viewing 15 posts - 46 through 60 (of 86 total)

You must be logged in to reply to this topic. Login to reply