Welcome toTencent Cloud + community, get more Tencent mass technology practice dry goods oh ~

This article comes from cloud + community column, the author of Tencent Mobile Quality center TMQ

When the word “quality” is mentioned, our first reaction is often “how many bugs?” “Is the performance good? “Questions like that. We define the quality of software products or services to see whether they can meet users’ needs, including indicators of function, performance and experience. We can measure the quality of software products or services through various types of testing methods. But what if you put a piece of source code in front of you and ask how good it is?

One person said, “Good code is like a Good joke: It needs no explanation.” People with experience in coding have a certain “taste” for code and can make subjective judgments about how good code is by feeling. They may feel uncomfortable seeing “spaghetti code”, but this is too personal and arbitrary. Is there an accepted standard for code quality?

Uncle Bob cites this cartoon in the preface to his book The Code Clean Way:

The use of the comic’s “crudeness per minute” to measure code quality is a fun joke, emphasizing “inherent” quality attributes such as readable code. As opposed to “external” quality attributes such as meeting requirements specifications, “internal” code quality attributes emphasize the quality of the internal structure of the code that supports the implementation of functional requirements. Sonar Code Quality Testing Essential defines this inherent quality of code from seven dimensions, dubbed the seven Deadly SINS of developers by the Sonar development team:

  • Coding specifications: Are coding specifications followed and best practices followed?
  • Potential bugs: Code that could go wrong in the worst case, and code that has security holes.
  • Documentation and comments: too little (lacking necessary information), too much (without information), outdated documentation or comments.
  • Duplicate code: Violates the Don’t Treat Yourself principle.
  • Complexity: Code structures are too complex (e.g., cyclomatic complexity) to understand, test, and maintain.
  • Test coverage: Write adequate unit tests, especially for complex code.
  • Design and architecture: High cohesion, low coupling, and minimal dependencies.

Martin Fowler, in his book Refactoring: Improving Design with Code as It Is, vividly uses the term “Bad Code Smells” to describe the “symptoms” of poor Code design and implementation. The book lists 22 bad code smells and refactoring techniques.

With this information in mind, we can now measure code quality in terms of testability, readability, comprehensibility, tolerability, and other quality attributes of the code maintainability dimension. Code quality refers to the intrinsic quality of non-functional, the user cannot directly experience to the quality of the code quality is bad, is the most direct “victims” developers or organization itself, because the code quality directly determines the maintainability of the software cost of high and low, such as duplicate code can cause maintenance cost multiplied; Non-standard code, bad comments, and overly complex code will increase the difficulty of reading and understanding code, and too high complexity will greatly increase the difficulty of test coverage and consume too much manpower, while the lack of test coverage will make it more difficult to locate and fix problems. Poorly structured, low-cohesion, high-coupling code makes even minor requirements changes or functional extensions impossible, and the cost of modification is likely to outweigh the cost of rewriting.

At this point, we have some qualitative ways to measure code quality, code scanning tools to expose code quality issues, and refactoring methods and techniques to address these issues. However, it is still difficult to answer the questions of how good or bad a piece of code is, and which one is better than the other, because we still have not completely solved the quantification of code quality: it is a code quality problem, and the harm of repeated code and too many comments is definitely different. Similarly, the method is too complex. Compared with the method with cyclomatic complexity of 10, the damage and modification difficulty of the method with cyclomatic complexity of 20 are also very different. Therefore, we cannot directly use the quantity of problems to measure the quality, but need to find a more precise and reasonable quantitative measurement method.

Quality model of SQALE method

SQALE(Software Quality Assessment Based on Lifecycle Expectations) provides a set of scientific measurement and analysis methods and effectively responds to this challenge. The SQALE method integrates the ISO-25010 standard with the code specification. Its goals are: to provide support for evaluating the source code of software applications in an objective, accurate, reproducible, and automated manner; It provides an effective way to manage technical debt. SQALE is currently the reference standard for many of the major code analysis tools, including SonarQube, as well as commercial code scan analysis tools such as CoderGears and SQUORE.

Let’s take a brief look at the SQALE method. SQALE method consists of two models: quality model and analysis model. The tree structure below shows the quality model of SQALE’s method: The root node represents software quality (in this case code quality) and is expanded from left to right. The first level defines the feature classification of code quality, followed by the subclasses of each feature, and finally the attributes/specific measures corresponding to each subclass.

From left to right, code quality is refined and broken down into smaller units, down to the smallest properties that can be directly measured; From right to left, the metrics are progressively aggregated to the root node, resulting in a measure of total code quality. Table 1 is an example of SQALE quality model decomposition. The first column in the table split code quality for maintainability, testability, alterability and reliability several dimensions, for each dimension and further details, such as the measurability and subdivided into unit testing measurability and integration level testability such child characteristics, further, the child characteristics can refine to directly measure the properties of the or called requirements (the third column in the table, Code scan rules), such as unit test testability is subdivided into rules such as “number of module test paths <11” and “number of module call parameters <6” :

Note: SonarQube we use does not fully follow SQALE’s quality model. In version 5.4 and earlier, there are dimensions such as testability, changeability, comprehensibility and readability similar to SQALE. The whole model has only two levels, that is, the first column and the second column are merged. For example, the testability dimension directly corresponds to “expressions should not be too complex”, “methods should not be too complex”, “methods should not have too many parameters” and so on. After 5.4, the current version is further simplified, and the scan rules corresponding to code quality can be directly classified into the “bad taste” category. Specific rules can be classified with multiple labels, making classification and configuration more flexible.

Measure code quality

So how should these rules be quantified? In other words, how to measure how much code breaks the rules, and this measure can be added up, because rules vary so much that, as explained above, it is not reasonable to sum them up directly.

What to do? SQALE’s analytical model solves this problem, which leads to the second important concept in this article: TechnicalDebts.

The concept of “technical debt” was first introduced in 1992. It refers to the additional development burden that developers incur in the future by switching from the best solution to the one that accelerates software development in the short term. This definition implies that such “debt” is a deliberate, rational and balanced behavior. When we further discuss the types of technical debt later in the paper, we will point out that this definition only represents a relatively benign type of technical debt, which is a relatively “moderate” definition. Our focus here is on using the technical debt metaphor to help you understand how to measure code quality.

Since we’re talking about debt, it should be about money. Thus, the “principal” of the technical debt is defined as an estimate of the human resources needed to fix code quality problems. For example, for the Java language, fixing a cyclomatic complexity method of 15 takes a developer 15 minutes (with the default setting of the Sonar Java analyzer as an example). This value is the principal of the debt. Every scanning rule corresponding to code quality in code scanning tool has a debt calculation method. Some rules set a fixed debt value, while others have corresponding calculation formula according to the degree of violation. After introducing the concept of technical debt, SQALE method can unify the code quality measures corresponding to different rules into a single indicator of human resource consumption.

According to the quality model shown in FIG. 2, the code quality measurement value of the software to be evaluated can be obtained by summarizing step by step from right to left. One of our measurement challenges, how to objectively evaluate the quality of our code, was answered.

Interest on technical debt

There is another concept worth emphasizing here about technical debt, namely the interest on debt. We know that borrowing usually pays interest, ranging from very low interest rates on debt (e.g., zero interest on housing plans) to high interest rates (e.g., credit card debt) to desperate high interest rates (e.g., loan sharks). It is also has the interest, the technical debt exist arbitrage, some violations immediately repair to 10 minutes, if there is no matter after a period of time, may need 20 minutes or more time to repair (because the code detailed knowledge over time, as well as the broken window code problem to accelerate the deterioration and so on). Some code-scanning tools, such as Coder Gears’ CppDepend, define how to calculate principal and interest for rules. The code-scanning plugin we’re currently using on SonarQube doesn’t support calculating interest, so we won’t discuss it in this article. Just remember that because interest exists, If technical debt is not repaid in time, it will show nonlinear growth in the future, resulting in unexpected losses. When discussing the harm of technical debt in subsequent articles, we will often mention the nonlinear characteristics of technical debt.

Comparison of different types of code

Now we are left with a measurement problem: how do we know the quality difference between the two pieces of code? Now we have the absolute value of technical debt principal, but how do different sizes and different types of code compare? The SQALE method continues to borrow the term “debt ratio”, which is calculated as the amount of resources needed to pay off the debt (the principal) divided by the estimated amount of resources needed to rewrite all the code. In the scanning tool implementation, the denominator is calculated by code volume and development productivity level, where productivity is a configuration item, such as SonarQube, which can configure the average estimated time to write a line of code. SQALE further uses the term “debt grade”, defining five grades from A (very good) to E (very bad), corresponding to different grades according to the range of debt ratio. For example, in SonarQube, [0, 5%] is A, (5%, 10%] is B, (10%,20%] is C by default. (20%, 50%) is D, and above 50% is E. When the debt ratio reaches 100%, that is, debts begin to exceed assets and become insolvent, this situation is called “technical bankruptcy”. Of course, when we encounter such situations in our daily work, we don’t use such scary terms. We usually rewrite them under the banner of “refactoring.”

Below is an example of a scan summary of CppDepend, containing all the concepts we discussed (using CppDepend as an example to show more comprehensive information).

The number of lines of code scanned by the tool in the figure above is 19,862. The total debt is 32 days, the annual interest of the debt is 9 days and 2 hours, the debt ratio is 6.39%, and the debt grade is B.

SonarQube is the tool platform we use in our daily work, as shown in the picture below:

The project is in debt for 12 days with a total of 923 bad smells (i.e. the number of violations), a debt ratio (translated as “technical debt ratio”) of 6.3% and a debt rating (SQALE rating) of B.

SQALE provides us with a set of methods and tools to measure code quality effectively and reasonably. The SQALE method process in the figure below clearly shows each link of the whole method process:

Photo credit: http://www.sqale.org

With the support of methods and tools (SonarQube), we can look at the quality of our own code. From the scan results, we still have some gaps compared to some good open source projects. The department EP(Engineering Productivity) picked out the following four rules that were important based on the scan results:

  1. Source files should nothave any duplicated blocks,

  2. Classes should not becoupled to too many other classes,

  3. Methods should not be toocomplex,

  4. Control flow statements”if”, “for”, “while”, “switch” and”try” should not be nested too deeply.

Note: some SonarQube languages do not support rule 2 in their scanning plug-ins, such as C++ and Python.

These four rules are the technical debts we need to pay first, and have been promoted and implemented in the whole department.

Reading this, many people may be tempted to ask, what’s the use of all this? The relatively low quality of the code doesn’t hurt the business. What good would it do to improve the quality of the code other than keep us busy? Or what is it worth? What does it have to do with my KPI?

Well, if bad code is “in debt”, then it’s only natural to pay back debt. After all, “if you’re out there, you’ll have to pay it back.” It’s clear that such a pale sermon won’t sell, so the focus of our upcoming articles will be a deeper understanding of technical debt and the need and urgency to improve code quality.

So: Readers, does your team or organization value code quality as well?


Question and answer

Are there tools available to calculate code metrics for a project?

reading

Meituan Takeaway Android Lint code checking practices

Here are some tips to help you write concise JS code

Web front-end performance basic indicators & Calculation methods


Has been authorized by the author tencent cloud + community release, the original link: https://cloud.tencent.com/developer/article/1151495?fromSource=waitui

Welcome toTencent Cloud + communityOr pay attention to the wechat public account (QcloudCommunity), the first time to get more massive technical practice dry goods oh ~