Explore Legacy Code Base Flashcards
What makes Legacy Code?
Maintenance is the most important part of the lifecycle. . We should modify legacy code safely. Software Maintenance cost is not fixing bugs, it is adding a new feature or a new value.
60% to maintenance 60% to new features within maintenance.
If it lacks good tests, then it is legacy!
Make a good test suite and then if you break something you know that you broke it since your tests won’t pass.
How Agile helps Legacy?
Identify: Where you need to make changes for your feature.
Refactoring: Decide if change point has good tests. If the functions are short and the code is in good shape you might be able to write tests from given functions.
Agile can help by adding tests to improve coverage. Tests will fail if we make bad changes. Good test coverage for the next person to add features.
What is the best thing when working with Legacy Code?
It is well covered by tests.
How to approach a legacy code problem?
Always have a scratch branch. Break stuff and mess it up so that you can poke around with different gems and such.
Then you can throw it away when you are done.
Try to find the customers or the user stories to talk you through what they are doing. Then you can tell what the code is doing.
Try to understand the database schema as well. Check the Schema file.
Check github logs to see how the code revolved over time.
Source Code comments.
What are CRC cards?
Class Responsibility Cards that tell us the responsibilities and collaborators of a given model object.
If you go through users stories and you highlight the nouns and the verbs, then you have your models as nouns and your verbs as relationships between the models.
Patrons make donations and buy tickets. For donations need to track which fund donated to so that we can create reports of fund’s activity. For Tickets we need to track what show they are for so we can run reports by show plus other things that don’t apply donations. Explain the design we need.
Donations and Tickets should subclass from a common ancestor.
There is a common behavior to be captured. If they subclass from a common behavior we can have the parent class have the purchasable and report functionality, but we don’t force it to inherit from the purchasing class. They key is that the tickets have separate things from donations and thus they shouldn’t inherit from the same parent.
What are characterization tests?
They establish ground truth on how the app works right now. Makes known behavior repeatable. You make the typical situation a repeated test so that should you break it you can quickly fix it. Make imperative then convert to declarative. You can use Capybara Mechanize.
In process vs. out of process integration test?
In process means it will run in memory. Out of process it will run out of the memory and on the server. When your test environment is outside of you environment, then you have to create your database items by actually creating them. If you want true remote tests then you must obey these constraints.
Which tests are used to understand how the actual code works?
Unit-and-functional-level characterization tests. You can make an assumed value. Then you run it and it will say I expected to get x, but i got y. Then you know what it should be.
- Figure out the collaborator method
- Get some random value
- Capture the true value by running the test and then use that true value. Like poking at it.
What are some facts about integration-level characterization tests vs. module or unit level characterization tests?
They are just as likely to be unexpectedly dependent on the production database.
They rely less on detailed knowledge about the code structure
If a customer can do an action, you can create a simple characterization test by mechanizing the action with brute force.
They are based on assumptions about how the code works.