What is good code? That is not a question easily answered. But sometimes you need to do a quick assessment on the state of a software project. When I get my hands on a new collection of code, these are the steps I take for a first assessment on how easy the project will be to work with. How far I get depends on how much time I have and how the code is. Language and framework will also matter for how important each step is, and how well I can answer the questions. Some findings will make me entirely skip the rest of the section, as if there are no tests the rest of that section makes no sense. There are also not always a “right” and a “wrong” answer to the questions, not only objectively but also from my subjective view. For me, the most important thing is to know what I am getting myself into. I hope it can be helpful for others too. My steps are:
1. Get the code
- How are the dependencies managed?
- Are there a lot of deprecations and exploits found for the dependencies?
- Is the code “older” than its first commit? That can happen if the project starts as a copy of an older project.
- If it should compile, does it compile?
2. Run the code
- Is there a readme?
- If there is a readme and I follow it, will I have the project running on my computer?
- If the readme is missing, or is not leading to a running project, what is missing? How much work would it be to fix it?
- How are secrets handled?
- Do I need anything besides the code to run things on my computer?
- Is the setup extra complicated compared to similar projects?
- Is the project prepared for new developers in some other way than a readme?
- Are there tests?
- It there are tests, can I run them after following the readme?
- Can I run the tests on a computer not connected to the internet?
- What is the coverage for the tests, using metrics available?
- What is the proportion between unit tests and integration tests?
- Are the tests correctly labeled as unit/integration/system… tests depending on what they do test?
- How is sensitive information, as secrets, handled for tests?
- How is the test data managed?
- Can I break the tests by changing the code?
- If I change the code will it break any tests?
- How much work is it to write the next test?
4. Read the code
- Can I see the domain in the naming and/or the types?
- How much code is there? In how big chunks is it grouped (files, classes, functions)?
- Are there private/inner methods/functions/objects?
- Is there a linter? Does it produce any errors or warnings? What kind of rules are enforced?
- Does the code have the feel of the language it is written in or can I sense an “accent” from another programming language?
- How are external dependencies used? Are they isolated or intertwined with the business logic?
- How is data transfer done (network/storage)? Is it scattered over the code or done in one place?
- Are there a lot of dependencies/imports for each piece of code?
- How is error handling done?
- What does the cyclomatic complexity look like in general? How is control flow managed? How is iteration and data manipulation done?
- Are there global state, magic numbers or other implicit dependencies for objects and functions?
- How big portion of the code do I need to read more than once to understand what it does?
- If I try to refactor the code somewhere random, perhaps extracting a method, how hard is it?
5. Version control
- How big are the changes in the commits?
- How many files do each commit touch?
- Can i make sense of the messages?
Comment on the blog!
Create a comment by emailing me.
I will then add the comment to the post.