Sunday, September 25, 2011

Reply: Some thoughts on tests' maintainability

This was to reply to an interesting post of my friend. Unfortunately, Blogger is not able to handle my long comment. Maybe it is too long, or may Blogger think I am a spammer. Anyway, the comment is long enough for me to dedicate one of my post here for it:

Interesting post. I'm in my first years practicing unit testing too. Won't miss leaving a long comment here!

It seems the very problem about unit testing for you is about maintainability of the test cases. It was a question for me too about how many tests to write for particular class. The lower number of tests you write, the lower maintainance problems, right?

There are some occassions I avoid writing tests for. I am not claiming these are right or wrong but it seems to work for me.

#1: During our undergrad years, I was introduced to unit testing (with JUnit.) What I remembered are that we are encouraged to write tests for as many methods as possible. We even generated the tests for plain getter/setters. Come to think of it now, that was totally unpractical!

So now I just skip the simple methods I am sure there are only silly test cases for it.

#2: Another thing is about writing test for private methods. When you design a class, you are giving your users some kind of contract by providng public methods. These are something that should be broken or be changed often. If you need to change these often, you may have to admit the class is incorrectly designed and thus rewrite/add the tests.

However, I do not test private methods. This give me some room of flexiblity where I can change/optimize/organize the inner working of the class. I can change the signature/working of private methods any way I would like to, but I just need to make sure the public methods do pass the tests.

#3: I do have some tests you referred to as 'small acceptance tests.' However, to perform 'unit' testing, you test one and only one class. If the class depends on some other concrete classes then you have to change them to abstract/interface instead. If you are testing more than one classes than that may be considered as 'integration' testing, or some other names.

That was quite hard core! While I know this, I don't mock out some dependencies for small classes. That would require some efforts. But still, I would write integration tests for it.

Clearly, innovations in our world do not start with requirements from users. So all these models starting from requirement gathering are all WRONG. If you want to introduce something now, use whatever you like and do whatever you want to. But if you are building something big, you must also need to look into the rear mirrors and you do need some confidence going forward. Unit tests, test coverage, etc. are some of the answers to that.


TAP said...

Interesting comment. I also have some comments on your comment.
- For #1, (I'm sure you know this but for other people who read this blog) getters/setters are smell of Feature envy(Surprise that I can remember name? No, just googled).
- For #2, you practice is quite dangerous for people who don't get/know SRP because some functionality may not be tested.
- For #3, I think it depends on how ugliest of the dependencies. But I think this problem is so language specific.

teerapap.c said...

Definitely, I don't write tests for #1 and #2 too.

For #3, yes, its name should be integration test in typical definition but I think we can define a group of classes as a unit too. It's about definition and perspective.

By typical definition, my point is writing 1 test per 1 class are painful for me. IMO, writing only integration test is enough for testing the behaviors of the software.
Unit test only help you inspect the cause easier and faster.

.:: m3rLinEz ::. said...

@TAP I actually wouldn't be surprised if you remember all those smell names :P

On testing private methods, this is a debatable topic. There is a trade-off here.

I see public methods as a window to privates. Clearly, it is easy for us to design test cases that do not exercise some parts of the privates. However, I do think this is enough in case unit test is used to verify the public behaviors of their classes under tests. In case ones want to exercise every possible paths of execution (and 100% coverage) they may go to test privates at the cost of lower flexibility in changing the implementation. I personally find this is rarely the case and prefer to have more flexibility in changing my class.

Some kinds of application may really need this though, e.g. financial app or health care. 100% test coverage would lift some confidence.

@tee Forgot to mention my another regular but probably not a good practice: I write 'unit' tests only for critical classes. I believe, if high % test coverage is not your concern, it is okay to be selective about the classes to test.

For last point, all kind of tests are about discovering the bugs early. Lone integration test may be enough if you can design the test cases such that it can reveal error in the system under test, exercise abnormal execution paths. Often, you can't (and I know, you can't :P)

By going further down to 'unit' level. It is easier to discover some weird paths you can't think of from system level. Some people (such as Tap, maybe :) are happy to go further down the 'private' level. It's just a matter of how far you are comfortable to go. At the cost of losing flexibility.

TAP said...

I'm OK with one test per group of classes as long as it run fast, easy to write(no too many setups, teardowns required) but when we work in team it hardly goes that way.

I think it's easy to tell them to write one class per test and waiting for them to ask how can I do with these dependencies than trying to tell them to avoid test preventor dependencies in testing group of classes.

One thing is most of other people classes I have seen, is already a combination of what I think it should be classes.

I have found many situations that when people write high-level class diagram(HL because they did't go deep to implementation) or layering component diagram, it always end up with that classes/components as one implementation class. These classes always named as "...Manager", "...Service".

karthireva said...

wow great,nowadays this type of blog is more important and informative technology,it was more impressive to read ,which helps to design more in effective ways

Dot Net Training in Chennai Guindy

Shalini said...

Superb i really enjoyed very much with this article here. Really its a amazing article i had
ever read. I hope it will help a lot for all. Thank you so much for this amazing posts and
please keep update like this excellent article.thank you for sharing such a great blog with
us. expecting for your updation.
seo company
in chennai

Jeffy said...

Wonderful bloggers like yourself who would positively reply encouraged me to be more open and engaging in commenting. So know it's helpful..
SEO Company in Chennai
Digital Marketing Company in Chennai