tags:

views:

148

answers:

5

I work in a company where OOP is... well, not fobidden, but at least frowned upon as "too complex". My coworkers write lots of 100+ lines functions and they are usually all in a "funcs.inc.php" or "something.inc.php", if they use any functions at all, often they don't since copy-paste is faster.

I would love to start using TDD at least for the code i write but as i have to interface with their code i can't see how to begin.

It's not legacy code as they are actively developing it and i don't want to modify their code as i don't want to provoke conflicts.

Which approach would you suggest, except for changing the company?

+3  A: 

Use TDD for all of your modules and write tests when you use their modules for something. Eventually, everybody else will notice that you produce high quality code much faster than anybody else and they will be curious as to why. That will be the perfect opportunity to educate them.

If they never ask, well, at least you made your life a little more easy.

Aaron Digulla
+3  A: 

I'd suggest with starting with whatever next thing you have to write and trying to get some tests done first and then write the code for that thing. It could be fixing a bug, implementing an enhancement or new feature, but the idea is to try to find a way to get the tests done before the change.

Alternatively, you could take some of your co-workers code and wrap tests around some of it and try to refactor it, but I'm not sure how well that'll go over.

JB King
+2  A: 

You probably want to test your code in isolation of their code. This will change how you design your code - but that is probably why you want to do TDD anyway.

Create Mock functions for the libraries you want to isolate yourself from.

Daren Thomas
+2  A: 

Can you write unit tests on your own code first? Don't be bother by other people; make sure your code is fully Tdded and unit tested.

To simulate the interaction with other libraries, you can try the tried and true techniques such as mocks and stubs.

Ngu Soon Hui
+7  A: 

I've been in that position, both in an out of actual TDD. What I normally do is write tests for other people's interfaces, whenever possible. I then know before I run my code if they did one of the many common things that people do:

  1. Broke an API by re-naming or completely doing away with something
  2. Broke an API with subtle type changes that did not get noticed
  3. Pushed a toxic revision without testing it
  4. Sprung memory leaks (my test suite is Valgrind aware)
  5. Block where they never blocked before

Any of those failing would usually result in me saying "Hey, can you check on (module), I think it broke in the last revision"

This got ugly only one time. Someone else got really upset that I was writing tests for their code and insisted that I was out for their job. I could not make the person understand that I was just out to make my job easier.

It's never a good idea to come right out and say "Look, I'm spending more time debugging your code than working on my own", unless you absolutely have to (i.e. your boss is asking about your performance). Most of the time, if you just send people the tests, they're happy to have them. If you're already meeting resistance with the idea, just try to not offend anyone or seem condescending.

Mock functions / stubs are ok, but what remains is the program as a whole is still likely to break if real tests aren't run. At least, when that happens, you can quickly rule out your stuff and (likely) point right at the problem.

Tim Post
Good suggestion, but my problem with it is: how can i test functions that do 6 different tasks depending on the parameters or sometimes (less often recently) global variables or global defines and that consist to 80% of mysql queries?
dbemerlin
@dbemerlin: your situation seems a little more icky than I thought :) All you can do is test with _your_ use cases, which does narrow it down a bit. You can set the globals yourself as needed, but I get your point with them, you still end up wondering why a test failed when a class is used as advertised / directed and doesn't advertise its dependence on a global. There really is no 'great' way to implement testing when nobody else is doing the same. As for the query data, the functions don't make the expected input obvious?
Tim Post
+1 for diplomacy, particularly "I think **it broke** in the last revision." Blaming never helps morale.
Carl Manaster
@Carl, blaming seldom helps _anything_. Identifying problems is another matter :)
Tim Post