Software Quality Assurance (SQA): SonarCloud as Static Code Analysis (SCA) Platform — 3C Series

Achieva 'Cip' Gemilang
12 min readMay 5, 2024

--

Cloud Software Services. Tensor Art Generated Image.

Hey, everyone!

In the fast-paced world of software development, ensuring our creations are reliable and user-friendly is crucial, whether you’re a seasoned developer or just starting your programming journey. But with ever-expanding features and functionalities, complexity can creep in. Enter the hero of this story: Software Quality Assurance (SQA)! You might think SQA is just about catching bugs at the end. But it’s so much more! It’s a proactive approach that safeguards the quality of your software throughout the entire development process, from planning to deployment.

What is SQA, and Why Does it Matter?

Software quality refers to how well a software product conforms to its requirements and meets the needs of its users. It involves both the software product itself as well as the processes used to develop it.
— IEEE Computer Society

To put it simply, let’s imagine this: You’ve spent months meticulously coding an app. It compiles perfectly, but when you test it… disaster strikes! Bugs lurk everywhere, causing crashes and unexpected behavior. Here’s where SQA comes in as your knight in shining armor.

SQA is a systematic approach that ensures software meets specific quality standards throughout the development lifecycle. It’s not just about catching bugs (although that’s crucial!). It’s about proactively preventing them, improving performance, and ensuring the final product aligns with user needs.

Image by Qentelli

By implementing SQA, you’ll reap a harvest of benefits:

  • Reduced Costs: Early bug detection saves time and money compared to fixing issues later in the development cycle.
  • Improved User Experience: Fewer bugs and crashes lead to a smoother and more enjoyable experience for your users.
  • Enhanced Reliability: Robust software is less prone to failures and outages, boosting user confidence.
  • Faster Development: By catching issues early, developers can fix them quickly, keeping the project on track.

SQA Fundamentals: How Does SQA Work in Action?

Image by IMGFlip

According to Simplilearn, Software Quality Assurance (SQA) encompasses seven core fundamentals that require continuous monitoring. Let’s delve deeper into the seven fundamentals of SQA outlined by Simplilearn!

1. Quality Planning: Setting the Stage for Success

Think of quality planning as the blueprint for your software’s excellence. Here, you define the specific quality standards you’re aiming for, like performance benchmarks or user-friendliness goals. It’s also where you map out the processes needed to achieve these standards. This stage essentially establishes what “quality” means for your project and how you’ll measure it — think of it as setting the success criteria for your software masterpiece.

2. Quality Control (QC): The Vigilant Watchdog

Quality control acts as the vigilant watchdog, enforcing the established quality standards. It involves a two-pronged approach:

  • Testing: This is where the rubber meets the road. Software is meticulously tested to identify bugs and ensure functionalities align with the defined requirements.
  • Inspections and Reviews: Think of these as code walkthroughs with a magnifying glass. Formal and informal reviews, including code reviews, design reviews, and requirement reviews, help catch defects (such as technical debts) early on in the development process, preventing them from becoming bigger problems later.

3. Quality Assurance: Proactive Prevention

While QC focuses on the final product, quality assurance is all about preventing issues before they even appear. It’s like building a robust defense system for your software. Here’s how it works:

  • Process Standardization: Imagine standardized processes as well-oiled gears in a machine. By developing and following consistent procedures, you reduce variability and ensure predictability in your development journey.
  • Process Evaluation and Improvement: Just like any good system, SQA practices need continuous evaluation. This involves assessing their effectiveness and efficiency, often using established models and standards like CMMI (Capability Maturity Model Integration) and ISO 9001.

4. Quality Management: The Command Center

Quality management oversees the entire SQA operation, ensuring the smooth running of the quality initiatives. It’s the command center, strategically allocating resources and fostering leadership engagement. Here are some key aspects:

  • Leadership Engagement: Buy-in from the top is crucial. Quality management ensures that the organization’s leadership understands and supports the importance of SQA efforts.
  • Resource Management: Effectively allocating and managing resources, like skilled testers and the right tools, is essential for maintaining quality standards.
  • Risk Management: Proactive identification and mitigation of risks that could impact software quality is a key function. It’s like anticipating potential roadblocks and devising strategies to navigate them.

5. Software Metrics and Measurement: Quantifying Success

Metrics and measurements act as the yardstick for gauging the effectiveness of SQA activities. Just like tracking your fitness progress, these metrics help you understand where you stand. Common metrics include:

  • Defect Density: This measures the number of defects per unit of software size. A lower defect density indicates a more robust and reliable product.
  • Code Coverage: This metric tells you how much of your code is actually exercised through testing, helping you identify areas that might require more attention.
  • Customer Satisfaction: Ultimately, how happy your users are with the software’s performance and features matters the most. Gathering feedback from customers helps refine your SQA approach.

6. Preventive and Corrective Actions: Learning from Experience

SQA is all about continuous improvement. This includes:

  • Preventive Actions: Identifying and eliminating potential causes of problems before they even manifest.
  • Corrective Actions: Learning from past mistakes. Once an issue is identified, taking steps to prevent it from happening again is crucial.

7. Continuous Improvement: The Journey Never Ends

CI is aimed to constantly striving to refine processes based on feedback and ongoing learning. Techniques like retrospectives, where you analyze past projects, could help incorporate lessons learned and ensure your SQA approach continues to evolve.

Integrating SonarCloud: A Powerful Ally in Your SQA Arsenal

Image by Plain Concepts

We’ve explored the essential pillars of SQA, but the landscape offers even more tools to empower your software quality journey. Enter SonarCloud, a powerful cloud-based static code analysis platform that seamlessly integrates with your development workflow.

Think of SonarCloud as a proactive code reviewer on steroids. It analyzes your codebase line by line, even before you compile or run it. SonarCloud identifies potential bugs, security vulnerabilities, and code smells (areas that could be improved) early in the development process. This saves you time and effort compared to fixing issues later when they might be more complex and expensive to resolve.

To make it more awesome, SonarCloud automates much of the code analysis process, freeing you up to focus on more strategic tasks. It also provides detailed reports and metrics, helping you track your code quality progress over time.

Getting Started with SonarCloud: A Step-by-Step Guide

SonarCloud is a powerful tool for static code analysis, helping you identify potential bugs and improve your code quality early in the development process. Here’s a step-by-step guide to get you started:

1. Sign Up or Log In:

SonarCloud SignUp UI
  • Head over to the SonarCloud website (https://www.sonarsource.com/products/sonarcloud/).
  • If you’re new, click “Sign Up” and follow the on-screen prompts. You can use your existing GitHub or GitLab account to simplify registration. If not, you can simply log in with your credentials.

2. Create SonarCloud Organization (Optional):

This step is relevant if you’re working on a collaborative project or want to group multiple projects under a single organization. If you already have an organization or wanted to use it on your personal repository, you might want to skip this step. To create a new organization, you can follow this step.

Creating a New Organization
  • First off, after clicking “Import an Organization” follow up by clicking “create one manually” in the bottom right of the screen.
  • Provide name for your organization and an unique key. Remember, the key needs to be distinct across all SonarCloud organizations.
  • Select plan you wished to use for. There are two plans: Paid and Free.

3. Project Setup:

Project Configuration

Now, it’s time to configure your project, whether existing or newly created, within the “Analyze projects” section. Here, you can set a user-friendly display name for your project, visible on the SonarCloud dashboard. SonarCloud will automatically generate a project key for you, which you can keep or customize. Additionally, if you’re on a paid plan, you can choose to make your project private.

Defining “New Code”

Once you’ve finished configuring the project settings, you can optionally define how SonarCloud analyzes “new code” within your project. This configuration allows you to specify two criteria: previous version and number of days. Based on your choices, SonarCloud will determine which code changes are considered “new” for analysis. After finalizing these settings, you can create your project directly.

Getting SonarCloud Ready: NestJS Case Study

We’ll be using Jest for testing. To leverage SonarCloud’s magic for your NestJS project, you’ll need to configure two key elements, sonar-project.properties and .gitlab-ci.yml. Let dive deeper!

  1. sonar-project.properties: This file acts as the control center for your SonarCloud analysis. Create it in your project’s root directory and populate it with settings like project identification, code locations (source and tests), file encoding, and exclusions.

Try to adjust your sonar-project.properties similar to this:

sonar.projectKey=<your_project_key>
sonar.organization=<your_organization>

sonar.sources=src
sonar.sourceEncoding=UTF-8
sonar.exclusions=**/node_modules/**, **/dist/**, **/src/main.ts, **/src/tracer.ts
sonar.tests=test

# Include only .spec files in test scope
sonar.test.inclusions=src/*.spec.*, src/**/*.spec.*

sonar.javascript.file.suffixes=.js,.jsx
sonar.typescript.file.suffixes=.ts,.tsx
sonar.typescript.lcov.reportPaths=coverage/lcov.info

Here’s a breakdown of what the configuration file typically handles:

  • Project Identification: Defines a unique key for your project within SonarCloud.
  • Code Locations: Specifies directories containing your source code (.ts files) and test files (usually ending with .spec.ts).
  • File Encoding: Ensures consistent character interpretation for analysis (commonly UTF-8).
  • Exclusions: Tells SonarCloud to ignore specific folders or files, like node_modules or temporary build artifacts.
  • Test Inclusions: Focuses analysis on relevant test files, typically those ending with .spec.ts.
  • File Suffixes: Informs SonarCloud about the file extensions used for your project’s languages (.js/.jsx for JavaScript and .ts/.tsx for TypeScript).
  • Coverage Report Location: Points SonarCloud to the location of your test coverage report (often coverage/lcov.info for Jest).

2. .gitlab-ci.yml: This file is the heart of your GitLab CI/CD pipeline. Here’s where you’ll configure SonarCloud analysis to run automatically whenever changes are pushed to your repository.

Try to adjust your .gitlab-ci.yml similar to this:

image: node:lts-alpine

variables:
SONAR_USER_HOME: '${CI_PROJECT_DIR}/.sonar' # Defines the location of the analysis task cache
GIT_DEPTH: '0' # Tells git to fetch all the branches of the project, required by the analysis task

stages:
- build
- test
- sonarcloud-check

Build:
stage: build
before_script:
- npm ci
script:
- npm run build

Test:
stage: test
before_script:
- npm ci
script:
- npm run test
- npm run test:cov
artifacts:
paths:
- coverage/
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'


sonarcloud-check:
stage: sonarcloud-check
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: ['']
cache:
key: '${CI_JOB_NAME}'
paths:
- .sonar/cache
script:
- sonar-scanner
dependencies:
- Test
allow_failure: true

There are three stages to look upon, here’s a brief explanation:

  • Build Stage: This stage focuses on building the project.
    Before Script: Runs the command npm ci before the main build script. This ensures all project dependencies are installed before proceeding.
    Script: Executes the command npm run build. This assumes you have a build script defined in your package.json file that handles compiling or packaging your NestJS application.
  • Test Stage: Defines a stage named “test” responsible for running your project’s unit tests and generating test coverage reports.
    Before Script: Ensures all dependencies are installed using npm ci before test execution.
    Script: Executes two commands: npm run test to run unit tests and npm run test:cov to generate coverage reports.
    Artifacts: Specifies the coverage/ directory to be saved as an artifact, making it accessible for further analysis.
    Coverage: This section defines a regular expression that GitLab CI uses to parse the test coverage results from the logs.
  • SonarCloud Check Stage: Defines a separate stage named “sonarcloud-check” dedicated to running the Sonar Scanner CLI for code analysis.
    Image: Specifies a Docker image. Here, it uses the official sonarsource/sonar-scanner-cli:latest image, which provides the Sonar Scanner CLI tool needed for interacting with SonarCloud.
    Cache: Optimizes analysis speed by caching downloaded resources.
    Script: Executes the sonar-scanner command, which interacts with your SonarCloud instance using the project key and organization details.
    — Dependencies: Declares a dependency on the Test stage. This ensures the test stage runs successfully before proceeding with the SonarCloud analysis.
    Allow Failure: Sets this stage to allow failures. This means that even if the SonarCloud analysis encounters issues, the overall pipeline will still succeed. This can be useful for catching potential problems during early stages of integration.

Now that you’ve meticulously configured both the sonar-project.properties file and the .gitlab-ci.yml file, it's time to integrate them into your NestJS project. Simply push these files to your GitLab repository. With this setup in place, any changes you push to your codebase will automatically trigger a streamlined process not only automates code analysis but also empowers you to proactively address potential issues before they snowball into bigger problems.

Overview Example of SonarCloud Analysis

4. Review the Results:

Once you’ve pushed your latest code changes and the analysis completes, SonarCloud springs into action! Here’s what you can expect:

  • Detailed Reports: SonarCloud presents you with comprehensive reports that delve into the analysis of your codebase. These reports highlight potential issues categorized by severity (critical, major, minor, etc.). Each reported issue is clickable, allowing you to investigate its nature and pinpoint its exact location within your codebase. This granular detail empowers you to efficiently address the problem, such as fixing bugs, improving code structure, and adhering to best practices.
  • Metrics: SonarCloud goes beyond just highlighting issues. It also provides valuable metrics on code coverage, code smells, and overall code quality. These metrics offer a broader perspective on the health of your codebase.
Example of Good Codebase

The image above showcases a good codebase, boasting zero technical debt in the form of bugs, vulnerabilities, and code smells. Furthermore, it demonstrates impeccable code coverage, achieving a perfect 100%. This signifies that the generated test suite effectively validates every aspect of the feature’s functionality.

Achieving good metrics, such as 100% code coverage, doesn’t necessarily indicate the quality of your code. It’s possible to reach high coverage by focusing on positive scenarios while neglecting edge cases and error handling. To ensure comprehensive coverage and high-quality code, adopting Test-Driven Development (TDD) practices is beneficial. If you’re interested, you can explore my crash course on implementing TDD for more in-depth understanding.

Summary

Image by TeePublic

In the ever-evolving world of software development, ensuring the quality and reliability of your creations is mandatory. Software Quality Assurance (SQA) emerges as your knight in shining armor, safeguarding excellence throughout the entire development lifecycle. By proactively preventing issues, improving performance, and ensuring user satisfaction, SQA empowers you to deliver exceptional software.

The quest for quality software is an ongoing journey. By embracing SQA practices and leveraging powerful tools like SonarCloud, you can develop exceptional applications that meet user needs and stand the test of time. Remember, high-quality software isn’t just a goal, it’s a commitment.

Is SonarCloud Right for You?
SonarCloud offers both free and paid plans, making it accessible for projects of all sizes. Whether you’re a solo developer or part of a large team, SonarCloud can be a valuable addition to your SQA toolkit. By leveraging its capabilities, you can proactively identify and address code issues, ultimately leading to more robust and reliable software.

While SonarCloud shines as a comprehensive static code analysis (SCA) tool, it’s not the only option in your developer toolbox. The ideal choice depends on your project’s specific needs. For those starting out or on a budget, free and open-source options like ESLint (JavaScript/TypeScript) or Pylint (Python) offer excellent code quality checks and bug detection. For broader project needs, CodeClimate offers analysis for multiple languages. If security is a top priority, commercial SCA tools like Fortify provide in-depth vulnerability analysis alongside code quality assessments. Consider factors like programming languages, budget, desired features, and integration with your workflow to find the perfect SCA companion for your project!

To end this article, let’s wrap it up by mentioning an amazing quote:

”Quality is the result of an intelligent effort, not a chance happening”
— Nassim Nicholas Taleb

Keep learning and growing!

References

--

--