Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Assert that the java code of a project satisfies certain checks.

License

NotificationsYou must be signed in to change notification settings

nidi3/code-assert

Repository files navigation

Build StatuscodecovLicenseMaven Central

Assert that the source code of a project satisfies certain rules.

Nobody follows rules that are not checked.If they are only checked periodically / manually by an "architect", it's often too late because there are already too many violations.
A better way is to define coding rules in JUnit tests.This way, they are asserted automatically and regularly.Violations of rules break the build and therefore, one is forced to eitheradjust the code to comply with the rules or to adapt the rules in a reasonable way.

code-assert supports rules on the package structure and the test coverage.It also integrates several static code analysis tools.

Language independent checks

Java checks

Kotlin checks

Other


Dependency

This is based on code fromJDepend.It checks if the package structure contains cycles and/or follows the defined rules.

publicclassDependencyTest {// Analyze all sources in src/main/javaprivatefinalAnalyzerConfigconfig =AnalyzerConfig.maven().main();@TestpublicvoidnoCycles() {assertThat(newDependencyAnalyzer(config).analyze(),hasNoCycles());    }@Testpublicvoiddependency() {// Defines the dependency rules for package org.projclassOrgProjextendsDependencyRuler {// Rules for org.proj.dep, org.proj.model, org.proj.utilDependencyRuledep,model,util;@OverridepublicvoiddefineRules() {base().mayUse(util,dep.allSubOf());//org.proj may use org.proj.util and all subpackages of org.proj.depdep.andAllSub().mustUse(model);//org.proj.dep and all subpackages thereof must use org.proj.modelmodel.mayUse(util).mustNotUse(base());//org.proj.model may use org.proj.util but not org.proj            }        }// All dependencies are forbidden, except the ones defined in OrgProj// java, org, net packages may be used freelyDependencyRulesrules =DependencyRules.denyAll()                .withRelativeRules(newOrgProj())                .withExternals("java.*","org.*","net.*");DependencyResultresult =newDependencyAnalyzer(config).rules(rules).analyze();assertThat(result,matchesRulesExactly());    }}

Test coverage

Maven Central

To verify the test coverage of a project,JaCoCo can be used.The following steps are needed:

  • Add this to the<build><plugins> section ofpom.xml:
<plugin>    <groupId>guru.nidi</groupId>    <artifactId>code-assert-maven-plugin</artifactId>    <version>0.9.14</version>    <executions>        <execution>            <goals>                <goal>prepare</goal>                <goal>assert</goal>            </goals>        </execution>    </executions></plugin>
  • prepare sets up the surefire plugin to run the tests with the JaCoCo agent which collects coverage data.
  • assert generates a coverage report and runs a coverage test(default issrc/test/java/CodeCoverage.java, configurable through thetestClass property).
  • Write a code coverage test:
publicclassCodeCoverage {@Testpublicvoidcoverage() {// Coverage of branches must be at least 70%, lines 80% and methods 90%// This is checked globally and for all packages except for entities.JacocoAnalyzeranalyzer =newJacocoAnalyzer(newCoverageCollector(BRANCH,LINE,METHOD)                .just(For.global().setMinima(70,80,90))                .just(For.allPackages().setMinima(70,80,90))                .just(For.thePackage("org.proj.entity.*").setNoMinima()));assertThat(analyzer.analyze(),hasEnoughCoverage());    }}

FindBugs

RunsFindBugs on the code and finds questionable constructs.

publicclassFindBugsTest {@TestpublicvoidfindBugs() {// Analyze all sources in src/main/javaAnalyzerConfigconfig =AnalyzerConfig.maven().main();// Only treat bugs with rank < 17 and with NORMAL_PRIORITY or higher// Ignore the given bug types in the given classes / methods.BugCollectorcollector =newBugCollector().maxRank(17).minPriority(Priorities.NORMAL_PRIORITY)                .just(In.everywhere().ignore("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"))                .because("It's checked and OK like this",In.classes(DependencyRules.class,PmdRuleset.class).ignore("DP_DO_INSIDE_DO_PRIVILEGED"),In.classes("*Test","Rulesets")                                .and(In.classes("ClassFileParser").withMethods("doParse"))                                .ignore("URF_UNREAD_FIELD"));FindBugsResultresult =newFindBugsAnalyzer(config,collector).analyze();assertThat(result,hasNoBugs());    }}

Checkstyle

Runscheckstyle on the code and finds questionable constructs.

publicclassCheckstyleTest {@Testpublicvoidcheckstyle() {// Analyze all sources in src/main/javaAnalyzerConfigconfig =AnalyzerConfig.maven().main();// Only treat issues with severity WARNING or higherStyleEventCollectorcollector =newStyleEventCollector().severity(SeverityLevel.WARNING)                .just(In.everywhere().ignore("import.avoidStar","javadoc.missing"))                .because("in tests, long lines are ok",In.classes("*Test").ignore("maxLineLen"));//use google checks, but adjust max line lengthfinalStyleCheckschecks =StyleChecks.google().maxLineLen(120);CheckstyleResultresult =newCheckstyleAnalyzer(config,checks,collector).analyze();assertThat(result,hasNoCheckstyleIssues());    }}

PMD

RunsPMD on the code and finds questionable constructs and code duplications.

publicclassPmdTest {// Analyze all sources in src/main/javaprivatefinalAnalyzerConfigconfig =AnalyzerConfig.maven().main();@Testpublicvoidpmd() {// Only treat violations with MEDIUM priority or higher// Ignore the given violations in the given classes / methodsPmdViolationCollectorcollector =newPmdViolationCollector().minPriority(RulePriority.MEDIUM)                .because("It's not severe and occurs very often",In.everywhere().ignore("MethodArgumentCouldBeFinal"),In.locs("JavaClassBuilder#from","FindBugsMatchers").ignore("AvoidInstantiatingObjectsInLoops"))                .because("it'a an enum",In.classes("SignatureParser").ignore("SwitchStmtsShouldHaveDefault"))                .just(In.classes("*Test").ignore("TooManyStaticImports"));// Define and configure the rule sets to be usedPmdAnalyzeranalyzer =newPmdAnalyzer(config,collector).withRulesets(basic(),braces(),design(),empty(),optimizations(),codesize().excessiveMethodLength(40).tooManyMethods(30));assertThat(analyzer.analyze(),hasNoPmdViolations());    }@Testpublicvoidcpd() {// Ignore duplications in the given classesCpdMatchCollectorcollector =newCpdMatchCollector()                .because("equals",In.everywhere().ignore("public boolean equals(Object o) {"))                .just(In.classes(DependencyRule.class,Dependencies.class).ignoreAll(),In.classes("SignatureParser").ignoreAll());// Only treat duplications with at least 20 tokensCpdAnalyzeranalyzer =newCpdAnalyzer(config,20,collector);assertThat(analyzer.analyze(),hasNoCodeDuplications());    }}

ktlint

Runsktlint, a kotlin linter.

publicclassKtlintTest {@Testpublicvoidanalyze() {// Analyze all sources in src/main/kotlinAnalyzerConfigconfig =AnalyzerConfig.maven(KOTLIN).main();KtlintCollectorcollector =newKtlintCollector()                .just(In.classes("Linker").ignore("no-semi"));KtlintResultresult =newKtlintAnalyzer(config,collector).analyze();assertThat(result,hasNoKtlintIssues());    }}

detekt

Runsdetekt, a static code analysis tool for kotlin.

publicclassDetektTest {@Testpublicvoidanalyze() {// Analyze all sources in src/main/kotlinAnalyzerConfigconfig =AnalyzerConfig.maven(KOTLIN).main();DetektCollectorcollector =newDetektCollector()                .just(In.classes("Linker").ignore("MaxLineLength"));DetektResultresult =newDetektAnalyzer(config,collector).analyze();assertThat(result,hasNoDetektIssues());    }}

Configuration reuse

Collector configurations can be defined separately and thus reused.Some configurations are defined inPredefConfig.

privatefinalCollectorTemplate<Ignore>pmdTestCollector =CollectorTemplate.forA(PmdViolationCollector.class)        .because("It's a test",In.classes("*Test")                .ignore("JUnitSpelling","AvoidDuplicateLiterals","SignatureDeclareThrowsException"))        .because("It's compiler generated code",In.languages(KOTLIN)                .ignore("BC_BAD_CAST_TO_ABSTRACT_COLLECTION"));@Testpublicvoidpmd() {PmdViolationCollectorcollector =newPmdViolationCollector().minPriority(RulePriority.MEDIUM)            .apply(pmdTestCollector)            .because("It's not severe and occurs often",In.everywhere().ignore("MethodArgumentCouldBeFinal"));PmdAnalyzeranalyzer =newPmdAnalyzer(config,collector).withRulesets(rules);assertThat(analyzer.analyze(),hasNoPmdViolations());}

Standard tests

A test can inherit fromCodeAssertTest. It should override one or moreanalyzeXXX methods.If it does so, these standard checks will be executed:

  • dependency rules
  • circular dependencies
  • PMD
  • PMD - unused actions
  • CPD
  • CPD - unused actions
  • FindBugs
  • FindBugs - unused actions
  • Checkstyle
  • Checkstyle - unused actions
//extend CodeAssertTest if you still use JUnit 4publicclassCodeTestextendsCodeAssertJunit5Test {privatestaticfinalAnalyzerConfigCONFIG =AnalyzerConfig.maven().main();@OverrideprotectedDependencyResultanalyzeDependencies() {classMyProjectextendsDependencyRuler {DependencyRulepackages;@OverridepublicvoiddefineRules() {//TODO            }        }finalDependencyRulesrules =denyAll().withExternals("java.*").withRelativeRules(newMyProject());returnnewDependencyAnalyzer(CONFIG).rules(rules).analyze();    }@OverrideprotectedFindBugsResultanalyzeFindBugs() {finalBugCollectorbugCollector =newBugCollector().just(In.classes("*Exception").ignore("SE_BAD_FIELD"));returnnewFindBugsAnalyzer(CONFIG,bugCollector).analyze();    }@OverrideprotectedCheckstyleResultanalyzeCheckstyle() {finalStyleEventCollectorbugCollector =newStyleEventCollector().just(In.everywhere().ignore("javadoc.missing"));returnnewCheckstyleAnalyzer(CONFIG,StyleChecks.google(),bugCollector).analyze();    }@OverrideprotectedPmdResultanalyzePmd() {finalPmdViolationCollectorcollector =newPmdViolationCollector().just(In.everywhere().ignore("MethodArgumentCouldBeFinal"));returnnewPmdAnalyzer(CONFIG,collector).withRulesets(basic(),braces()).analyze();    }}

About

Assert that the java code of a project satisfies certain checks.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp