Checkin your code after every minor feature. This means you must be able to checkin quickly and easily. Find a way to do this. I do it like this:
- Always have a terminal in the project directory
- Only work on one feature at a time
git commit -a
- Verify the commit is correct.
Never commit files unrelated to your development feature. In this class you will lose points for such things. In industry your commit will be rejected. Always review the list of files in the changelist.
Sometimes new code for separate features accidentally mixes during development.
Do not checkin multiple features at once.
Instead, you can have your tools help you split the changes into separate commits.
git commit -p to commit partial patches.
Modern source control systems allow changes to be reordered easily.
git rebase -i and
git rebase --onto allow the source tree to be easily restructured as the developer sees fit.
If the changesets are truly independent sets of changes, the different combinations of features can be created for testing.
This can make finding bugs or resolving issues easier.
Building + testing
It is always best to commit code that builds and passes tests. Sometimes this cannot be done and still keep the commit changes small. You must use your best judgement for when to trade off between untested code and uncommited code.
Develop features in branches. When the feature is complete, merge it back to main branch. Branches in modern source control systems are very cheap and easy to maintain.
Once a feature is complete and tested, the branch should be merged back to the main branch. The feature must be tested in the branch before merging is allowed. Often the code must be reviewed by other developers before it is allowed to be merged back. After the feature is merged, it must be tested again.
Keep your functions small. If you have to scroll to understand your function, something is wrong. Same with indented code blocks. If you have more than 3 levels of indention, you need to try to understand your design better.
Name your functions and variable short and understandable. This is hard. Use very short names when it doesn't hurt understanding (e.g. loop indices). If your function names need to be long to understand property, maybe consider reorganizing your design.
All code must be tested. When writing tests, ensure the code is covered. There are varying levels of coverage:
- Each line is executed at least once
- Each path is executed at least once
- All possible paths are executed
Edges and boundaries should be tested. This means choosing test cases carefully to maximize benefit.
- test true and false
- test less than range
- test greater than range
- test lower boundary of range
- test upper boundary of range
- test multiple combinations of these
- test empty collection
- test one element
- test multiple element
- test maximum elements
- test first element
- test last element
- test no matches
- test with match outside search range
- test one match
- test multiple matches
- test match in first position
- test match in last position