Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

The company I used to work for before we had automated unit tests to test our work. However the coding standards and architecture was not very important for tests. Of course you had to indent code correctly and put your braces where you are supposed to put your braces, but no one would go nit picking through your tests code. This seemed reasonable to me as the tests were usually changed frequently and the idea was to quickly write a test and then start seriously writing the code.

The new company has just got the hang of unit testing our work, but they expect you to spend time making sure the test code looks as pretty and well thought out as the code it is testing. I personally think it a waste of time since tests are internal and while test code should be neat, it does not have to be as perfectly engineered as the code that goes out the door to the customer.

Am I wrong in my belief? What is the right thing to do here fellow programmers?

Frequency of how often our programmers have to modify / extend / reuse existing unit tests varies, some more often and others less often. We are using Python Django and most of the test architecture is built-in and most tests are just simple functions. Very less setup/teardown needed.

share|improve this question

closed as not constructive by gnat, Walter, Martijn Pieters, Glenn Nelson, Jim G. Jan 16 '13 at 20:56

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

    
it depends on how often do programmers have to modify / extend / reuse existing unit tests –  gnat Jan 16 '13 at 12:21
    
varies, some more often and others less often. We are using Python Django and most of the test architecture is built-in and most tests are just simple functions. Very less setup/teardown needed. –  Ali Jan 16 '13 at 12:23
    
well for test code that is frequently reused / modified, it could be rather easy to justify the prettifying. Does your company have documentation / resources (eg team wiki) where their expectation could be justified? did you search through these resources to find out if there was a justification there or not? –  gnat Jan 16 '13 at 12:28
    
I put the same amount of effort and professionalism into writing tests as I do production code. All code should be good code. Doesn't matter what it's used for. –  Mathew Foscarini Jan 16 '13 at 17:32
    
Why was this closed? Why exactly is a question about how to write test cases is not constructive on a programming site? According to the FAQ, the question is perfectly on-topic. –  user29079 Jan 17 '13 at 10:49

7 Answers 7

You should strive to build quality software. Unit tests are software.

share|improve this answer

Some parts of a coding standard should apply equally to the production code and the unit test. Most notably, the naming conventions, brace placement and indentation style.
The reason for that is that it gives all the code a consistent look.

Some parts do apply to unit tests, but you never tend to violate them anyway. Think about stuff like the complexity of functions.

Some parts, I would ignore for unit tests, such as requirements about moving similar code into functions. For me, a certain amount of copy-paste is acceptable in unit tests, but less so in production code.

So, in the end, yes coding standards mostly apply also to unit tests.

share|improve this answer
1  
I agree with your 3rd paragraph. For tests, especially those which are intended as behavioral specifications, it is more important to be DAMP (Descriptive And Meaningful Phrases) than DRY. –  Jörg W Mittag Jan 16 '13 at 15:24

The reason why you create pretty code is because it makes the code easier to maintain at a later stage.

When the requirements of your software change during the development, all unit-tests need to be changed to test correctness according to the new requirements instead of the old. To make this possible, the unit-tests need to be maintainable.

Also, when one of your tests fails, the programmer who broke the test will certainly want to know why it failed. To do that, he needs to look at your tests and find out what they are actually testing. That will be considerably easier when the test code is easy to understand.

So yes, you should aim for a high quailtiy standard when writing unit-testing code.

share|improve this answer
1  
I would add from @Bart van Ingen Schenau's answer that you should make it pretty, but unit tests should be forced into the all the same coding conventions as your regular production code. –  ArtB Jan 16 '13 at 15:15

Should I spend time prettifying unit tests?

If prettifying means to make the unit test more consistent and easier to understand then yes.

As I have not written a book or interviewed many people I can only pass along my personal experience in this matter. Recently I spent a week on an F# project making a several hundred unit test consistent, easier to read and more comprehensive. In the process I learned a few things and developed a philosophy.

  1. In making the unit test consistent, I began to see test cases that needed to be added to make the test for a function comprehensive. Because the unit test were consistent it was easy to spot the cases that needed to be added. Basically I tried to move the parameters and result for a function into an array element with all of the test cases for a function in one array one after the next. It made seeing the patterns of this input causes this output easy because you only had to look at the input and output, not all of the overhead needed for a test case. Then the mechanics of the test case followed pulling out the parameters and result and passing them through the test function.

For example:

let private butLastValues : (int list * int list)[] = [| 
(
    // idx 0
    // lib.butLast.01
    // System.Exception - butlast
    [],
    [] // Dummy value used as place holder
);
(
    // idx 1
    // lib.butLast.02
    [1],
    []
);
(
    // idx 2
    // lib.butLast.03
    [1; 2],
    [1]
);
(
    // idx 3
    // lib.butLast.04
    [1; 2; 3],
    [1; 2]
);
|]

[<TestCase(0, TestName = "lib.butLast.01",     ExpectedException=typeof<System.Exception>, ExpectedMessage="butlast")>]
[<TestCase(1, TestName = "lib.butLast.02")>]
[<TestCase(2, TestName = "lib.butLast.03")>]
[<TestCase(3, TestName = "lib.butLast.04")>]

[<Test>]
let ``List butlast`` idx = 
    let (list, _) = butLastValues.[idx]
    let (_, result) = butLastValues.[idx]
    butlast list
    |> should equal result
  1. In making the unit test easier to read it became obvious that they were good enough to use for learning because the comprehensiveness of the unit test for a function became better than some of the documentation; it was real working examples that not only demonstrated a case but also showed what the result would be, be it a valid result, exception, or failure to complete.

  2. Since our project was a translation of OCaml code from "Handbook of Practical Logic and Automated Reasoning" by John Harrison, we created both a direct translation version and an optimized version. Having made the test comprehensive it was easier to additionally test the optimized code and the normal code using the same test case.

So by spending time working with the unit test by hand and in detail, I learned more about how the code worked than just by reading the code. I began to see patterns in the test data that I would not be seen in the code and leveraged that to learn more about how the code worked.

If you view unit test as something that should be created and then left in a box only to be used by automated tools then I think you are missing something significant.

share|improve this answer

The complaint that the tests don't have to be "[as] well thought out as the code it is testing" is not a valid one.

If you are using the the tests to define the expected behaviour of the code, then if your expectations are created without rigour, the code which meets those expectations will be sloppy and badly thought out. You also may fail to cover all important cases or bake in badly thought out assumptions.

Someone should be able to come to the unit test and see what the test is saying about the behaviour of the unit under test, what the constraints on that behaviour are and how the unit is expected to be used. Add whatever architecture and documentation to the test is necessary to achieve that.

share|improve this answer

In my experience, good programmers are perfectionists. Good programmers write all their programs in the same, consistent manner. They keep to the same coding style consistently and they avoid the same bad practices no matter what kind of program they are making.

Potentially bad programmers do the opposite. They always go looking for excuses to make the programs sloppy. Some warning signs are comments like "nobody will read this code but me", "this code will never be re-used", "I'll tidy it up later", "I obfuscated it to avoid extra typing" etc. Such programmers tend to write sloppy code not only in the quick & dirty tests, but also where it matters the most.

Consider this: how likely is it that you are going to re-use code from an old test when you are writing a new one? The answer is hopefully "quite likely".

Then of course, you may not need to produce the same amount of "overhead tasks" when coding some quick & dirty case. Source code and other documentation doesn't need to be detailed, quality checks like manual code review, static analysis etc needn't be rigorous, version handling and publishing don't need to be as formal. But there are no obvious reasons why the source code in itself should be more sloppy

share|improve this answer
    
Shout it on the mountain brother! :) –  Mathew Foscarini Jan 16 '13 at 17:33

If the unit tests run flawlessly, but the main code doesn't run, then the project is a failure. If the main code runs flawlessly, but the unit tests don't, then the project is a success (albeit with imperfect methodology).

If you're doing something that spends a significant amounts of time and only results in the unit tests being prettier, you're wasting time.

share|improve this answer
    
Downvoter: why did you bother downvoting without a comment? I can't promise that I'd agree with you if you explained why, but I can promise that I won't if you don't. –  Michael Shaw Jan 17 '13 at 7:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.