How to make sure that code is still working after refactoring ( i.e, after variable name change)?
In static language, if a class is renamed but other referring class is not, then I will get a compilation error.
But in dynamic language there is no such safety net, and your code can break during refactoring if you are not careful enough. You can use unit test, but when you are using mocks it’s pretty hard to know the name changes and as a consequence, it may not help.
How to solve this problem?
Before you start refactoring you should create tests that will be able to test what you’re going to change – if you say unit tests will not be enought, or they will be hard to create, then by all means create higher level tests possibly even excersising the whole of your product.
If you have code coverage tools for your language use them to measure the quality of the tests that you’ve created – after it’s reached a reasonably high value and if the tests are kept up to date and extended you’ll be able to do anything with your code very efficiently and be rather sure things are not going in the wrong direction.
I’ve been teaching a class on unit tests, refactoring and so forth, and this is probably the thing that most people get wrong. Refactoring is not just changing the code. It is changing the code without changing the external functional behavior. That is a very important point.
In other words, you need to have some way to verify that the external functional behavior is intact after the refactoring. Lacking divine insight I find unit tests very useful for that. In his book on Refactoring, Martin Fowler stresses the use of automated tests for this verification.
If your code was developed using TDD you will have the necessary test suite as it is developed during the development of the code itself. If you need to refactor code for which no tests are available, your best approach would be to set up automated tests before you make any changes to the code. I realize that setting up tests for existing code can be hard, but you will learn a lot about the code while doing so.
You may also want to check Bruce Eckel’s essay on strong typing versus strong testing as it discusses the feedback you get from the compiler versus the feedback you get from your test suite.
Your code can break during refactoring even with a compiled language. Relying on that alone will get you into trouble. Automated testing is the best way to be sure that the program works as it should.
If you say what dynamic language you are using we can maybe offer some advice on tools that can help you with testing. Everything can be tested.
You responded and said you use PHP and Python.
If this is a web app use selenium to create the tests in the browser. At first you just need Selenium IDE. Put all your tests in a single Test Suite so that you can easily execute them all. As the list grows you can start looking into Selenium RC and Selenium Grid.
1) For Python use PyUnit for PHP phpunit.
2) TDD approach is good but also making tests after writing code is acceptable.
3) Also use refactoring tools that are available for Your IDE they do only safe refactorings.
In Python You have rope (this is library but have plugins for most IDEs).
4) Good books are:
‘Test-Driven Development by example’ Best
‘Expert Python Programing’ Tarek Ziade (explain both TDD and refactoring)
google tdd and database to find a good book about TDD approach for developing databases.
Add info for mocks you are using. AFAIK mocks are needed only when database or network is involved. But normally unit test should cover small pice of code (one class only) sometimes two classes so no mockup needed !!