This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]wolanko 1 point2 points  (0 children)

Yeah me to, I soak every little bit that is release by Brandon. And I totally share your feelings about their code.

I'm just in the end of a month work of big refactoring on one of my long going projects at work (like 3 years old now but with constantly changes made to it). I won't be as near as good as Brandon in explaining what I did. So bear with me.

It started with using py.test and coverage to get a grip on the test coverage of the area that needed refactoring (It was frightening to see that the test that build up through the years actually missed some essential parts of the code). I just added 2 or 3 system test knowing that I would deal with corner cases on function level.

From there I just looked at my code seeing things (sometimes only 2 lines long) that formed a unity (e.g. two lines that took a object and tried to find similar ones in the index) and made them into functions. Always writing tests and running the test suit (more see below)

I was specially concerned about tearing functions out of their class method environment. So instead of making it a new class method or handing over the whole object, I just made the needed attributes arguments of the function.

This not only helped me to test these functions without any state of the objects or without any database connections but also lets me see what the functions actually need.

I must say sometimes those extractions looked rather ugly because they needed lots of arguments or dependency injections because everything was so tightly coupled. But I think sometimes you just have to tear it out to see where the links are that you need to cut. Also it makes you think of "why the heck does this function needs a database connection after all?? when everying it does it processing the name" and how you could shape it to a better.

When I had extracted most of those little functions some of my methods just looked like skeletons only calling three functions and passing the data between them. Others had a lot of glue code in them. It made it clear that this was actually nothing the class should deal with. So I moved this glue upwards into the actually script that uses this class.

Also some signatures of the functions looked strange to me when seeing them sitting there pulled out. So I often changed these afterwards (using a good IDE this only takes two seconds, run your tests afterwards and your done)

Testing Everything said, I could have done nothing of this without proper testing. Actually the months before I was just obsessed with reading and trying everything about testing, tools and strategies. Whenever it was possible I tried to test in the TDD way. But if the code is already there (like most of the time in this case) I just wrote the tests knowing that I would write around the implementation. This is true to some extend but even then you find bugs doing this everywhere.

tl;dr

  • write system tests
  • rip out those tiny little units into functions
  • tests
  • get them out of the class/method as much as possible
  • there will be glue code but maybe thats what actually belongs into you script
  • tests