sonar-java 手写一个规则-单元测试分析

sonar8.5版本安装及规则自定义和使用 sonar8.5版本安装及规则自定义和使用前言为什么要整sonar8.51.安装postgresql数据库2.升级java版本3.解压sonar8.5安装包4.规则自定义xxxRule.java1、@Rule 注解2、scanFile 方法3、nodesToVisit4、visitMethod 方法RuleList.javagetJavaChecks方法5.配置并使用规则 前言 为什么要整sonar8.5 之前已经研究过sonar7.6版本的了,为什么还要继续研究,因为在做自定义规则的时候,我发现吧自己写的 阅读详情
AI摘要

本文分享了作者在定制SonarQube规则以检查Java代码质量时,如何使用自定义扫描逻辑和单元测试的心得。重点介绍了如何使用`BaseTreeVisitor`和`IssuableSubscriptionVisitor`,以及编写检查SQLDroptable语句的规则和单元测试的注意事项。

前言

最近做项目,定制sonar规则,提高Java代码质量,在编写的sonar规则,做验证时,使用单元测试有一些简单的心得感悟,分享出来。

自定义规则模式

sonar的自定义规则很简单,一般而言有2种模式可以使用:

1. 自定义扫描代码逻辑,并对分类的Tree的结构处理

2. 使用已扫描的分类,对分好类的Tree进行分析

BaseTreeVisitor&JavaFileScanner

extends BaseTreeVisitor implements JavaFileScanner

继承Tree的访问器,实现Java文件扫描器

TreeVisitor定义了很多Tree的读取过程,当然我们也可以扩展这个过程,Tree是哪里来的呢,scan的接口实现的

IssuableSubscriptionVisitor

extends IssuableSubscriptionVisitor

继承发布订阅访问器,意思是sonar的sdk默认扫描出来,我们需要定义那些是我们需要的,就订阅处理相关的Tree处理,推荐使用这种方式,开发便捷,性能可以得到保障,毕竟扫描文件的算法,如果写的性能差,扫描会很久。

比如我们写一个扫描检查Java代码里的SQL的drop table语句

@Rule(key = "DropTableSQLCheck")
public class DropTableSQLCheck extends IssuableSubscriptionVisitor {

  private static final String RECOMMENDATION_DROP_MESSAGE = "Make sure that drop table \"%s\" is expected here instead of sql platform.";

  private static final String DROP_TABLE_STR = "DROP TABLE";

  //告诉sonar插件,我需要访问这个,这里定义了字符串,插件定义了很多,如果不符合要求就需要自定义扩展,同时需要扩展扫描器
  @Override
  public List<Tree.Kind> nodesToVisit() {
    return Collections.singletonList(Tree.Kind.STRING_LITERAL);
  }

  // 访问我们刚刚要求的类型,已经安装Kind过滤了,扫描文件,归类的逻辑,已经sonar的API实现了,如果不符合要求才需要扩展
  @Override
  public void visitNode(Tree tree) {
    if (!tree.is(Tree.Kind.STRING_LITERAL)) return;
    SyntaxToken syntaxToken = tree.firstToken();
    if (syntaxToken == null) return;
    String str = syntaxToken.text();
    if (StringUtils.isBlank(str)) return;
    String originStr = str;
    str = str.trim().toUpperCase();
    if (str.contains(DROP_TABLE_STR)) {
      reportIssue(tree, String.format(RECOMMENDATION_DROP_MESSAGE, originStr));
    }
  }
}

这里没有考虑xml的SQL,包括字符串多个空格的考虑,理论上应该按照分析drop,然后为index逐个字符读取,如果是空格就读取下一个,如果是非t就return,如果下一个是非a就return,当然也可以使用正则。这里使用简化算法,做一个Demo

加上规则类,仿造写sonarqube的元数据

到此规则编写完成,后面分析单元测试逻辑

源码分析

简单分析下,代码执行逻辑,类似Java agent插件

从main的class执行

上下文加扩展,这里是一个注册扫描规则,一个注册扫描元数据,当然也可以合二为一,架构建议分离,所以Demo是分离的

元数据规则是sonarqube server启动实例化,启动就可以看到检查类别,检查类规则是代码分析时实例化

注册规则类,这里又分了是否用于test,上面的手写规则需要注入这个里面

元数据信息是路径扫描读取的,所以只要放在那个路径就行,通过@Rule的名称匹配文件名

 这里的repository_key是sonarqube显式的规则名称,同时这里也可以扫描其他语言,比如xml

这里写好后,如果需要本地验证,则需要单元测试。

单元测试

编写单元测试代码,即使是不能编译的代码也可以扫描

class A {
  private final String SQL = "drop table xxx";
  void foo() {
    String SQL1 = "drop table xxx"; // Noncompliant
    doSomething(SQL1);

  }

  @SQL("drop table xxx")
  public void doSomething(String SQL){
    // do something
  }
}

 编写test

public class DropTableSQLCheckTest {
    @Test
    void test() {
        ((InternalCheckVerifier) CheckVerifier.newVerifier())
                .onFile("src/test/files/DropTableSQLCheck.java")
                .withCheck(new DropTableSQLCheck())
                .withQuickFixes()
                .verifyIssues();
    }
}

载入需要扫描的文件和使用那个规则类检查 

单元测试分析

单元测试写好后,出现这个错误

这并不是规则写的有问题或者规则没命中,而是一种断言,sonar的单元测试jar定义

如果扫描出问题,那么需要对有问题的行打上

// Noncompliant

开头的注释,否则断言不通过

规则来源于org.sonar.java.checks.verifier.internal.Expectations的

collectExpectedIssues

方法中

    private static final String NONCOMPLIANT_FLAG = "Noncompliant";
    private final Set<SyntaxTrivia> visitedComments = new HashSet<>();

    private Pattern nonCompliantComment = Pattern.compile("//\\s+" + NONCOMPLIANT_FLAG);
    private void collectExpectedIssues(String comment, int line) {
      // 此处断言,收集断言有问题的代码行
      if (nonCompliantComment.matcher(comment).find()) {
        ParsedComment parsedComment = parseIssue(comment, line);
        if (parsedComment.issue.get(QUICK_FIXES) != null && !collectQuickFixes) {
          throw new AssertionError("Add \".withQuickFixes()\" to the verifier. Quick fixes are expected but the verifier is not configured to test them.");
        }
        // 放进预估
        issues.computeIfAbsent(LINE.get(parsedComment.issue), k -> new ArrayList<>()).add(parsedComment.issue);
        parsedComment.flows.forEach(f -> flows.computeIfAbsent(f.id, k -> newFlowSet()).add(f));
      }
      if (FLOW_COMMENT.matcher(comment).find()) {
        parseFlows(comment, line).forEach(f -> flows.computeIfAbsent(f.id, k -> newFlowSet()).add(f));
      }
      if (collectQuickFixes) {
        parseQuickFix(comment, line);
      }
    }

同理,如果一个问题都没用,那么验证不了规则,直接断言失败

org.sonar.java.checks.verifier.internal.InternalCheckVerifier

  private void assertMultipleIssues(Set<AnalyzerMessage> issues, Map<TextSpan, List<JavaQuickFix>> quickFixes) throws AssertionError {
    if (issues.isEmpty()) { // 没有错误示例,就断言失败
      throw new AssertionError("No issue raised. At least one issue expected");
    }
    List<Integer> unexpectedLines = new LinkedList<>();
    Expectations.RemediationFunction remediationFunction = Expectations.remediationFunction(issues.iterator().next());
    Map<Integer, List<Expectations.Issue>> expected = expectations.issues;

    for (AnalyzerMessage issue : issues) {
      validateIssue(expected, unexpectedLines, issue, remediationFunction);
    }
    // expected就是我们通过注释断言的sonar需要扫描出来的问题,如果有部分没有预计断言出来就会
    if (!expected.isEmpty() || !unexpectedLines.isEmpty()) {
      Collections.sort(unexpectedLines);
      List<Integer> expectedLines = expected.keySet().stream().sorted().collect(Collectors.toList());
      throw new AssertionError(new StringBuilder() //这里抛出断言缺失的错误或者错误断言的错误
        .append(expectedLines.isEmpty() ? "" : String.format("Expected at %s", expectedLines))
        .append(expectedLines.isEmpty() || unexpectedLines.isEmpty() ? "" : ", ")
        .append(unexpectedLines.isEmpty() ? "" : String.format("Unexpected at %s", unexpectedLines))
        .toString());
    }
    assertSuperfluousFlows();

    if (collectQuickFixes) {
      new QuickFixesVerifier(expectations.quickFixes(), quickFixes).accept(issues);
    }
  }

总结

sonar扫描实际上现在已经非常完善了,尤其是新API的提供,很大程度不需要我们写什么东西,专注核心的扫描算法与Tree的解析,甚至大部分扫描算法都不需要写了,使用发布订阅即可,得益于新API的提供,目前使用的很多API还是@Beta注解,但是开发效率极大的提升了,毕竟以前旧的sonar版本,需要我们自己写各种扫描与分析逻辑。不过sonar的单元测试与传统的单元测试是有一定区别的,sonar的测试逻辑是必须有一个问题测试案例,且需要打上

// Noncompliant

注释,注释的行既是命中的行,sonar使用行号作为map的key,这样sonar才认为是命中规则的。如果断言错误,或者断言的数量不对,那么也一样会单元测试失败。

sonar学习及简单使用 sonar学习及简单使用sonar简介: sonar是一个用于代码质量管理的开源平台,用于管理源码质量。目前通过插件的形式,可以支持包括java,c#,c,c++,PL/SQL,js,groovy等二十多种变成语言的代码质量管理与检测。sonar代码检测维度: 复杂度分布:文件、类或者方法等,如果复杂度过高将难以改变,这会是开发人员难以理解它们; 重复:检查程序中包含大量复制粘贴的代码,sonar 阅读详情

相关推荐

Sonar-Java 自定义规则实战:从零构建企业级代码质量检测方案

本文详细介绍了如何使用Sonar-Java自定义规则构建企业级代码质量检测方案。通过实战案例,展示了如何针对特定业务需求(如金融行业敏感数据访问)开发自定义规则,实现代码规范的自动化检查。文章涵盖环境配置、规则编写、测试调试及CI/CD集成全流程,帮助团队提升代码质量与开发效率。

weixin_28833069的博客 383

sonar自定义规则

Sonar并不是简单地把不同的代码检查工具结果(例如 FindBugs,PMD 等)直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。 sonarqubue默认的对java的检测规则不一定适合我们,可以自己去自定义rules。 禁...

weixin_34114823的博客 1965

Sonar——代码质量管理平台

一、基本认识           Sonar (SonarQube)是一个开源平台,用于管理源代码的质量。                                     Sonar 不只是一个质量数据报告工具,更是代码质量管理平台。通过插件机制,Sonar可以集成不同的测试工具,代码分析工具,以及持续集成工具,比如pmd-cpd、checkstyle、findbugs、Jen

程序媛~ 6331

sonar-java 自定义规则

最近在搞代码质量方面的项目,主要是针对Java语言,其他语言实际上也可以执行检查,核心原理是一样的,都是静态代码扫描,如果需要进行动态代码运行验证则可以通过单元测试的方式。以其中一个示例,实现自定义Java sonar规则。实际上这个很简单,如果需要考虑,那么需要考虑扫描算法怎么写,性能是否OK,毕竟一般执行扫描都是在代码编译打包的过程,本地很少单独执行扫描。

fenglllle的博客 3468

从零到一:手把手教你构建Sonar-Java自定义规则引擎

本文详细介绍了如何从零开始构建Sonar-Java自定义规则引擎,包括环境准备、AST语法树解析、实战编写自定义规则、高级技巧与疑难解决、规则部署与验证等内容。通过手把手教程,帮助开发者掌握Sonar-Java自定义规则开发的核心技术,提升代码质量管理能力。

weixin_28839549的博客 356

【项目实战】自定义设置Sonar的规则,要求DevOps工具链SonarQube只扫描指定模块

开发微服务项目,很多会基于网络上现成开源的微服务框架进行二开,公司有单元测试覆盖率的要求,往往会使用SonarQube 来实现扫描代码的单元测试覆盖率,但是因为网络上现成开源的微服务框架很大部分是已经现成的代码,因此补充单元测试工作会很痛苦,于是,可以自定义设置Sonar的规则,要求SonarQube 只扫描指定模块。

奶爸的编程之路,也就一周冷个三天 3031

【Sonar】Sonar理论篇

一、Sonar是什么     Sonar是一个用于进行代码质量管理的开源平台,用于管理源代码的质量,通过插件形式,可以支持包括java、C#、JavaScript等二十余种编程语言的代码质量管理与检测。 Sonar是从七个维度检测代码质量,而作为开发人员至少需要处理前5中代码质量问题。 1、不遵循代码标准     sonar可以通过PMD,CheckStyle,Findbugs等代码规则检

柠檬树 1万+

SONAR自定义检查规则插件 Java开发指南

SONAR是一个广泛应用的静态代码分析平台,它提供了许多内置的检查规则,以帮助开发人员发现潜在的问题并改进代码质量。使用自定义的SONAR检查规则插件,我们可以根据项目的需求定义我们自己的代码质量规则。通过编写自定义规则并将其集成到SONARQube中,我们可以提高代码质量、减少潜在的问题,并改善软件的可维护性和可扩展性。在上面的代码中,我们创建了一个名为"custom"的新规则存储库,并定义了一个名为"custom-rule"的自定义规则。中修改自定义规则的实现,以检测是否存在未注释的方法。

TechWhizZ的博客 1241

Sonar-Java插件开发详解:自定义代码检查规则实战指南

Sonar-Java是SonarSource提供的静态代码分析工具,专为Java代码质量和安全检测设计。通过自定义代码检查规则,开发者可以根据项目需求定制代码规范,提升代码质量和安全性。本文将详细介绍如何开发Sonar-Java插件,创建自定义代码检查规则,并提供实战案例指导。 ## 一、Sonar-Java插件开发基础 ### 1.1 环境准备 开发Sonar-Java插件需要以下环境:

gitblog_00174的博客 839

配电网故障重构/孤岛划分/故障恢复

程序主要复现《基于GA_BFGS算法的配电网故障恢复性重构研究_郑海广》,采用matlab编程软件实现,依据网络结构和DG供电方式对配电网进行孤岛划分,将含有 DG 的配电网拓扑结构看成一个树,搭建成连通图模型,使得将孤岛的划分变成了求取最小生成树,以网损和开关开断次数作为目标,采用 IEEE33 节点配电网为算例,通过遗传算法寻优计算,从而得到最佳的重构方案。

zhangxd212489的博客 2500

第1.1节 构网型 vs. 跟网型:根本区别与技术原理

构网型与跟网型变流器的本质区别在于控制哲学与等效模型。跟网型变流器采用"电压跟随,电流注入"策略,等效为受控电流源,依赖电网电压作为参考,在弱电网下存在稳定性问题。构网型变流器采用"自主同步,电压构建"策略,等效为受控电压源,能主动构建电压和频率,具备自主运行、黑启动和电网支撑能力。两者的核心差异体现在同步机制、电网依赖性、故障行为和系统支撑等方面。构网型变流器更适合高比例新能源、弱电网和微电网场景,是未来电力系统的重要发展方向。

技术工作者 1391

Sonar Java 规则插件开发 (基于阿里开发手册)

引言 最近在做Sonar静态代码扫描管理,以此顺手接了Sonar的插件开发,基于阿里开发手册进行开发,在整体开发过程中,其中还是遇到不少坑位,也以此给大家做相应借鉴 官网Demo演示插件开发地址: https://docs.sonarqube.org/display/PLUG/Writing+Custom+Java+Rules+101 基于官网的我暂时不多说,基础框架按照官网的范例进行搭...

tigereg000的博客 6797

瑞萨 RL78 开发环境实战:从 CS+ for CC 到 e² studio 高效开发

本文详细介绍了瑞萨RL78单片机开发环境的选择与配置,对比分析了CS+ for CC和e² studio的特点及适用场景。内容涵盖环境安装、工程创建、调试技巧、外设驱动开发和低功耗设计等实战经验,为开发者提供全面的RL78入门指南,帮助快速上手并高效开发。

4k5l6j7h8的博客 241

由浅入深理解 Sonar 自定义规则开发 | 干货

本文非常详细的梳理了静态代码规则自定义写法,是测试开发工程师 hlylearner 孤独而勇敢的探索,值得学习,首发于 TesterHome 社区,链接:https://testerho...

霍格沃兹测试学院的博客 1873

生物信息学新手必备:5分钟搞定GEO补充数据下载(含西柚云代理配置)

本文为生物信息学新手提供了快速下载GEO数据库补充数据的完整方案。核心在于解析GEO文件存储逻辑,构造正确的FTP下载链接,并利用云端代理服务(如西柚云)解决国内访问NCBI速度慢、易中断的问题。通过分步教程,用户无需命令行即可在5分钟内稳定获取大型测序文件,极大提升数据获取效率。

weixin_28314575的博客 636

基于simulink的电动汽车电机驱动系统IGBT开路故障检测

本文介绍了基于Simulink的电动汽车电机驱动系统IGBT开路故障检测方法。通过搭建永磁同步电机(PMSM)驱动系统模型,实现IGBT开路故障注入,并设计基于电流平均值与PWM逻辑比较的故障检测算法。系统可实时采集三相电流信号,通过MATLAB Function模块实现故障诊断,当检测到PWM信号与电流不匹配时输出故障报警。仿真结果显示,系统能在2.05秒内准确识别A相上管开路故障,并通过Scope和XYGraph直观展示故障特征。该方法为电动汽车电力电子系统故障诊断与容错控制提供了实用解决方案,后续可扩

xiaoheshang_123的博客 149

关于sonar+gitLab+JaCoCo检查代码规范以及单元测试覆盖率的方案

打开/target/site/jacoco/jacoco-resources/index.html,我们可以看到覆盖率计数器,包含指令级(Instructions,C0 coverage),分支(Branches,C1 coverage)、圈复杂度(Cyclomatic Complexity)、行(Lines)、方法(Non-abstract Methods)、类(Classes),绿色代表覆盖,红色代表未覆盖。这项指标会统计所有的分支数量,并同时支出哪些分支被执行,哪些分支没有被执行。

sunjian885的博客 2768

SAP ABAP Cloud 发展简史

其中用于云开发的 ABAP,官方术语是 「ABAP in the Cloud」,本文后续叙述方便起见,简称为 「ABAP Cloud」. 它涵盖了标准 ABAP 语言范围的一个子集,只能访问受限的 API,用于构建 SAP BTP ABAP 环境以及 SAP S/4HANA Cloud ABAP 环境上的云解决方案。SAP ABAP 平台是用于 SAP ECC、SAP S/4HANA 和 SAP BTP 等产品的技术平台,也是 ABAP 应用程序的开发和运行环境。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1390

细说Sonar之——前端接入篇

1、sonar是什么 sonar是一个代码质量管理的开源平台,用于管理源代码的质量,通过插件形式,可以支持包括java、C#、JavaScript等二十余种编程语言的代码质量管理与检测。 sonar是从七个维度检测代码质量:  1) 不遵循代码标准sonar可以通过PMD,CheckStyle,Findbugs等代码规则检测工具规范代码编写  2) 潜在的缺陷sonar可以通过PMD,Check...

weixin_34221332的博客 6876

网页内容抓取的艺术:使用R语言解析动态网页

本文探讨了使用R语言处理动态网页数据的方法。针对AJAX加载的学术网站,传统的静态抓取和RSelenium方法存在会话终止、浏览器错误等问题。通过分析发现内容通过admin-ajax.php加载,提出使用httr2模拟POST请求获取数据,配合rvest解析HTML内容。该方法避免了浏览器自动化的弊端,实现了高效稳定的动态内容提取,为处理类似AJAX网站提供了通用解决方案。

m0_74337424的博客 52

手把手教你学Simulink——基于Simulink的无迹卡尔曼滤波(UKF)控制仿真建模示例

本文详细介绍了在Simulink中实现无迹卡尔曼滤波(UKF)控制倒立单摆系统的完整过程。通过对比扩展卡尔曼滤波(EKF),重点阐述了UKF在处理强非线性系统时的优势:采用无迹变换(UT)通过确定性采样捕捉非线性特性,精度可达三阶泰勒展开且无需计算雅可比矩阵。文章分步骤讲解了状态空间定义、UKF参数设计、Simulink实现方法,以及结合LQR控制器的闭环系统搭建,并通过仿真验证UKF在大角度偏移情况下具有更优的估计精度和控制性能。最后还讨论了工程实践要点和扩展方向,为非线性系统控制提供了实用解决方案。

MHD0815的博客 96

ali p3c规则扩展-集成sonar

最近公司需要完善检测机制,所以我这边对于原有的ali p3c的类进行了一次扩展,扩展主要分为两个部分。 第一:对于规则的编写

无缺的博客 1312

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Sonar使用介绍

cehsi123456

一个有趣灵魂的测试员,指点江山,挥斥方遒 2074

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Sonar简介及使用

Sonar简介 Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量 通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测 sonarQube能带来什么? Developers' Seven Deadly Sins 1.糟糕的复杂度分布 文件、类、方法...

香烟达人的博客 6万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Sonar,扫出你的不规范

介绍 Sonar(SonarQube)是一个开源平台,用于管理源代码的质量。Sonar 不只是一个质量数据报告工具,更是代码质量管理平台。支持的语言包括:Java、PHP、C#、C、Cobol、PL/SQL、Flex 等。 特性 idea在集成sonar插件后,就可以在代码提交前发现代码中的不规范和漏洞,即使进行修复,而不是等到提交到仓库后在进行代码质量扫描,然后重复提交–检测–修复的过程。 sonar目前可以扫除以下类型的问题点 不遵循代码规范 sonar可以通过PMD,CheckStyle,Findb

一只小码渣的博客 12万+

sonar是一款静态代码质量分析工具

sonar是一款静态代码质量分析工具,支持Java、Python、PHP、JavaScript、CSS等25种以上的语言;而且能够集成在IDE、Jenkins、Git等服务中,方便随时查看代码质量分析报告;sonar通过配置的代码分析规则,从可靠性、安全性、可维护性、覆盖率、重复率等方面分析项目,风险等级从A~E划- 分为5个等级;sonar设置了质量门,通过设置的质量门评定此次提交分析的项目代码是否达到了规定的要求;...

包磊磊的博客 4210
上一篇: sonar-java 自定义规则
下一篇: ubuntu 24.04LTS的一些使用心得
fenglllle
博客等级 码龄8年 461粉丝 242原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值