Does your brain hurt too?

posted in Verg-o-nomics
Published August 09, 2007
Advertisement
Sometimes things just get ugly.

I'm TDDing a larger (delegating) class, and it got fugly.

Fugly Fixtures


First of all... I tried to set up too complicated a fixture, I think, and it took way too long.

The reason why? I think the cause of the problem was I was trying to use "pseudo-real" data to drive the tests. But it doesn't seem to work when talking about "delegator" types, because the inputs and outputs for delegators should actually be simpler...... I *think*.

I believe what ended up happening was the creation of Integration tests instead of unit tests, because in the end the data I was feeding in was meant to elicit proper outputs from delegatees instead of just the SUT (the delegator).

Who's driving this bus?


I'm confused, though, as to what to think. TDD is supposed to drive the development of your "system under test". In this case, I'm talking about a delegating class that either aggregates, or has as policies previously TDD'ed classes/components.

What does this mean about using "specific examples" to drive development, in this case? In other words... what type of "specific example" would be needed to TDD a delegator type?

Do I need to just fall back and test that the "depended-on components" are called, through stubs/spies/mocks?

? ? ?


I realize the end result *should be* an algorithm in code form, which utilizes the delegatee classes. There's just a disconnect in my brain somewhere about what type of "specific example" would drive this development.

Sigh.

And I leave for Philadelphia tonight at 10PM.
0 likes 4 comments

Comments

gutzofter
Hey Verg,

Sometimes when TDDing and I run into this type of problem. I stop and remember to ask, what am I doing? What is the intention of the SUT, not what is the implementation. How come you need a class that acts like a facade for your aggregates. Maybe something else is screaming to get out? Did you just say to your self I need to have this class? This is what they say is is BUFD writ small. I'm not saying that your shouldn't do this, but it can trap you into making a least effective design decision. Something the Continuous Integration Crowd talks about, is that you always turn in your code at the end of the day only after your tests pass. If you can't do that. Just delete the code and start over the next day. For me, if it's not the end of the day I will delete the code and go someplace else for a bit. Maybe look to refactor my code base. Spend 15-30 minutes refactoring, then go back to writing the code again.

Hope this helps!

gutzofter@yahoo.com
August 10, 2007 12:16 AM
Verg
Quote:Original post by gutzofter
Hey Verg,

Sometimes when TDDing and I run into this type of problem. I stop and remember to ask, what am I doing? What is the intention of the SUT, not what is the implementation. How come you need a class that acts like a facade for your aggregates. Maybe something else is screaming to get out? Did you just say to your self I need to have this class?


Hey thanks for the insight, gutzofter... its quite helpful.

The intention of the "software", in this case, was to take a raw bitmap and convert it into a "useable" bitmap... meaning 1) flip it 2) convert it to the current screen res.

There are several sub-responsibilities... and those mapped to separate classes.

But the "glue" code, in this case, is what delegates these responsibilities... the "BitmapTransform" class, if you will.

Quote:This is what they say is is BUFD writ small. I'm not saying that your shouldn't do this, but it can trap you into making a least effective design decision. Something the Continuous Integration Crowd talks about, is that you always turn in your code at the end of the day only after your tests pass. If you can't do that. Just delete the code and start over the next day.


Wow... guess that works :)

Quote:For me, if it's not the end of the day I will delete the code and go someplace else for a bit. Maybe look to refactor my code base. Spend 15-30 minutes refactoring, then go back to writing the code again.

Hope this helps!


Surely it does.

However, I think my problem can be traced directly back to not using stubs/spies correctly.

Instead of fully controlling the outputs and inputs of the stubs, like I should have, the stubs were subclassed from the real components, (meaning the SUT would call actual components instead of spies through virtual functions) ...making my unit tests more into integration tests... because I had to come up with real data to feed in!

I had to fake some bitmaps at 16-bits, for instance, and then come up with real "result" bitmaps at 32-bit, for instance. THAT's what took so long.

I retraced my steps a bit these last couple days... and created FULL spies that are fully configurable to 1) record all their inputs and, based on the inputs 2) return a value that I've set up for the input. (std::map takes care of the mapping).

This (of course) means I can feed the spies complete nonsense data... (which is much easier)... because all that really matters is what the SUT does with those indirect inputs/outputs.

The work seems to be much easier when it's more configurable like that.

There are still some tricky bits... like how to "sense" through mock APIs... ("memcpy", for instance)... to figure out if the bitmap was actually "flipped"... but I figured out a way to handle that.

...

More in a later entry... and thanks for your input!

Uprate for you.


Chad


August 10, 2007 02:41 PM
gutzofter
It is good that you are working your way through the testing paradigm. Is there some way to get a copy of your source code? I'm interested in testing graphic renderers. I would like to see some code to see if TDDing one makes it easier to unit test the code that utilizes the renderer.

Joe Gutierrez
August 12, 2007 11:49 AM
Verg
Quote:Original post by gutzofter
It is good that you are working your way through the testing paradigm. Is there some way to get a copy of your source code? I'm interested in testing graphic renderers. I would like to see some code to see if TDDing one makes it easier to unit test the code that utilizes the renderer.


Hey Joe...

Sorry I didn't get back to you right away (class reunion over the weekend)...

I can't release the code to you (not mine [smile]) but I've been thinking about showing an example (step by step) of what I'm doing, including the building of spies/stubs (which example is sorely lacking on the web or in print, IMO).

I'll have to figure out how to capture a session (VCR?) and then I'll translate that to print and put it here for you.

Thanks again.


Chad

August 13, 2007 01:49 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement