OctoPerf has been built from the ground with one unique idea: writing code that’s pleasant to work with. Code quality is our number one priority. When you create your own startup, you quickly understand that the number one enemy are not your competitors: it is yourself!
When creating a startup you realize that your product:
- must be released as quickly as possible on the market,
- needs as many features as possible to catch back the competitors,
- must be bug free to give your users the best possible experience.
The ‘Test is worthless’ myth
What makes most developers think that writing crappy code goes faster than writing well designed and tested code?
Probably because they think it’s better to spend time on coding rather than testing. Testing doesn’t add any feature and takes time. Testing is sometimes tedious. Why would i spend time on something that hasn’t any added value for my customers? Because, in fact, there is an added value to test. What’s the point of delivering a feature that doesn’t work? If the requirement is that the feature doesn’t need to work, features could be delivered instantly.
Testing is the starting point of code quality. When you test your code, you start to think differently. You write simpler code because it simpler to test. You split big functions into smaller ones. Testing code affects the way you write your code.
Bad code cannot be tested. The worse the code is, the harder is it to test it. Developers then argue that they didn’t test it because it’s not possible.
We try to stick to this as much as possible:
Refactor your code until it is fully testable.
Learning the hard way …
As being developers ourselves, we have been through a number of companies where code quality was like
Eh, don’t you have anything else to do?
We tried hard to explain how important it is to write good software, and failed miserably many times. Probably because we are bad at explaining things to other people.
Code quality doesn’t slow a company, it makes it faster in fact. Well designed code is easy to understand, and to refactor. It’s easily testable, so regressions are avoided during development iterations. Developers are pleased to work with well-designed code. Well tested code allows you to spend less resources on other forms of Quality Assurance before you deliver an application.
In contrast, bad code, full of code smells, just gets worse with time.
- How many hours did you spend debugging your code base?
- How many times did you encounter classes / functions / code that you could not easily modify, for fear of breaking things?
Writing untested code is like driving blindfolded!
Gave us our motivation
Many people were telling us that when you create a startup, you must write bad code to get quickly on the market. We don’t want to work in such an environment anymore. Nor we want to repeat this, and feel like Sisyphus.
This gave us a strong goal: create our own and prove this is simply not true. We’re just average developers. We’re not bad, nor perfect. But, we don’t want to repeat what we have seen in so many software companies so far. And we’re proud to announce that we did it.
SonarQube is an open source platform for continuous inspection of code quality. Its supports many languages and offers reports on:
- coding standards,
- code coverage,
- code complexity and potential bugs,
- and more.
It’s a very handy tool to quickly get a view of your application’s code health. We use it to check both our frontend, the GUI of OctoPerf, and our backend, the Java platform used to run the stress tests.
The screenshot below shows our frontend SonarQube analysis:
Some improvements can be made :
- Our AngularJs resources and directives are not unit tested … not a single one of them. That is why we only have 69% of unit test coverage.
- Most critical issues are Sonar complaining about too long function or functions with too many parameters. AngularJs controller are declared as functions, and with dependency injection it leads to very long functions with many parameters. We should find a way to either filter them in Sonar or to write our controllers a different way.
- Nevertheless, some functions are really too long / complex and should be refactored. A few controllers and services could be splitted into smaller ones.
- We must write *end-to-end tests using protractor.
There is still some work to be done!
The screenshot below shows our Sonar analysis on our Java backend:
You could argue that Sonar just gives an overview of the code quality of your project. It’s probably true. SonarQube can’t see everything, but it’s really better than nothing. Could you drive your car safely without tachometers?
Let me explain some of the metrics:
- Technical Debt: it’s an estimate of the time it takes to fix issues, and test uncovered code.
- Lines of codes: we have almost 25k lines of code so far. This doesn’t include Unit tests code. We probably have another 25k lines of code of tests. The entire 25k lines of Java code, including tests, have been written by a single person between September 2014 and April 2015. 25k lines of code in 8 months, roughly 3k lines of code per month (and probably the same amount of code has been written and trashed away).
- Code Complexity: it shows how hard it is to understand the code. We tried to keep complexity as low as possible. Usually, a complexity lower than 5 per class is great. Code should be as kept simple as possible,
- Unit Tests Coverage: it shows the percentage of lines of code and branches being tested. We have almost 2900 tests, for 25k lines of code. That’s 1 test method per 10 lines of code.
- Code Duplications: it’s speaks by itself. Code duplication is the ultimate evil in software development. It should never go above zero.
The whole code with tests has been written by a single developer in 8 months. Needless to say that the code has been refactored many times. Some parts of the project have been refactored up to 7 times. It takes only 11 minutes to run the 2800 tests to go through 99.8% of the code on a simple m3.large Amazon instance. This process is automated with Jenkins:
It’s easier to have good code quality when starting a project from scratch. When working on legacy systems, like we did in the past, it’s almost impossible to get this level of quality.