Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Enhancing Project Integrity: A Modernization fo...

Enhancing Project Integrity: A Modernization for Bug-Free Code

Embarking on a Java project involves employing the best strategies, patterns, and architectural decisions, all geared towards a customer-centric.

Yet, there exists an often overlooked facet: quality assurance. While not entirely disregarded, we, as developers, sometimes limit ourselves to performing the basic unity and integration tests, which may leave room for bugs.

Fortunately, several straightforward approaches and tools can be implemented to deliver a bug-free project with minimal effort.

During this presentation, you'll gain practical knowledge of the application of the following tools and approaches:

- ArchUnit: Ensuring consistent adherence to architectural patterns, even when multiple developers making changes to the project
- FindBugs: Employing static analysis to proactively identify potential bugs in your code, effortlessly.
- SonarQube: Offering a suite of diverse metrics and enabling the establishment of quality gates to maintain a predetermined standard of quality
- PiTest: Enabling the power of mutation testing to uncover bugs that may otherwise remain concealed.
- TestContainers: Streamlining the process of running various components such as databases, services, and extensions, thereby minimizing the need for manual intervention

Elias Nogueira

March 06, 2025
Tweet

More Decks by Elias Nogueira

Other Decks in Technology

Transcript

  1. AGENDA Demonstrate the usage of 5 tools to enhance the

    project integrity by the usage of moder testing tools, like: • SpotBugs • ArchUnit • PiTest • Sonar • TestContainers 80% hands on, 20% boring slides.
  2. COMMON PITFALLS IN SOFTWARE QUALITY Developers often rely on basic

    unit and integration tests but may overlook deeper issues. Code complexity and architectural introduce hidden risks over time. Late-stage bug discovery leads to higher fixing costs and delays. ⑴ ⑵ ⑶
  3. THE PROJECT Simple API that creates a Payment request with

    an id, amount and timestamp and process the payment simulating that someone is paying the request. The objective of the project is focusing on the tools, not in the validity of the use case as it is for educational purpose only.
  4. SPOTBUGS – DETECTING CODE ISSUES EARLY ❑ Static code analysis

    tool to detect common programming errors. ❑ Identifies potential null pointer, concurrency, and performance issues. ❑ Helps maintain cleaner, more maintainable code.
  5. SPOTBUGS – BUG DESCRIPTIONS ▪ Bad practice ▪ Correctness ▪

    Experimental ▪ Internationalization ▪ Malicious code vulnerability ▪ Multithread correctness ▪ Bogus random noise ▪ Security ▪ Dodgy code
  6. STATIC ANALISYS – OTHER TOOLS Static code analyzer from Google

    implemented as a javac compiler plugin, so checks are performed during code compilation. It can detect over 400 bug patterns, but they need to be enabled as most of them emit only warnings. There is an overlap between SpotBugs and Error Prone. ERROR PRONE Cross-language static code analyzer that has over 300 rules for Java. Rules should be enabled in an XML file (ruleset), but it can be done per category. PMD
  7. ARCHUNIT – ENFORCING ARCHITECTURAL RULES ❑ Ensures adherence to architectural

    patterns and constraints. ❑ Prevents undesirable dependencies between packages/modules. ❑ Enables automated checks to maintain consistency across teams.
  8. ARCHUNIT – ENFORCING ARCHITECTURAL RULES UI Layer Application Layer Domain

    Layer DDD Infrastructure Layer Domain Model Adapter Adapter Clien t Clien t Hexagonal
  9. ARCHUNIT – HOW TO 1. Add the library 2. Create

    the test 3. Import the package and determine the architectural constraints @Test void shouldRestrictAccessFromService() { ArchRule myRule = classes() .that().resideInAPackage("..service..") .should().onlyBeAccessed() .byAnyPackage("..controller..", "..service.."); }
  10. ARCHUNIT – HOW TO If you want to run the

    ArchUnit Tests first, there’s a workaround 1. Name the tests starting with ArchUnit 2. Include the test in the maven-surefire-plugin execution unit-test execution id 3. In the configuration section, set the runOrder to alphabetical <runOrder>alphabetical</runOrder> includes> <include>**/*Test.java</include> <include>%regex[.*(ArchUnit)*.*Tests.*]</include> </includes>
  11. PITEST – MUTATION TESTING FOR STRONGER TESTS ❑ Goes beyond

    traditional unit testing by introducing mutations in code. ❑ Ensures test cases actually catch faulty logic. ❑ Helps improve test effectiveness and reduce false positives.
  12. PITEST – HOW TO Add the plugin and exclude the

    Model objects <plugin> <groupId>org.pitest</groupId> <artifactId>pitest-maven</artifactId> <version>1.18.2</version> <configuration> <excludedClasses>com.eliasnogueira.paymentsystem.model.*</excludedClasses> </configuration> </plugin>
  13. SONARQUBE – CODE QUALITY ANALYSIS ❑ Provides code metrics, technical

    debt analysis, and security insights. ❑ Establishes quality gates to enforce predefined standards. ❑ Supports continuous integration by integrating into build pipelines.
  14. TESTCONTAINERS – TESTING REAL DEPENDENCIES ❑ Provides lightweight, disposable containers

    for integration testing. ❑ Tests with real databases, message brokers, and external services. ❑ Eliminates the need for complex manual setup.
  15. TESTCONTAINERS – USE CASE 1 When multiple databases must be

    supported the following approach can be applied: 1. Create additional application properties with the specific datasources 2. Add specific profiles in the pom.xml activating the application properties 3. Add the spring.profile.active in the maven-failsafe plugin for the integration-test phase 4. Add in the database-related tests the @ActiveProfiles 5. Run the tests using the profile Multi-database support @ActiveProfiles("${spring.profiles.active}") mvn verify -Pmssql
  16. TESTCONTAINERS – USE CASE 2 It’s important to run the

    tests using all the supported databases during any merge request. Using GitHub Actions we can set a parallel job execution based on all supported databases as a matrix Multi-database support with parallel execution in GHA
  17. TESTCONTAINERS – USE CASE 2 Multi-database support with parallel execution

    in GHA database-tests: needs: integration-tests runs-on: ubuntu-latest strategy: matrix: profile: [ mysql, mssql ] steps: - name: Run Database Tests with Profile ${{ matrix.profile }} run: mvn verify -P${{ matrix.profile }} -DskipUnitTests database tests (mysql) database tests (mssql) build unit and integration tests
  18. ELEVATING CODE QUALITY WITH MINIMAL EFFORT Quality assurance is an

    ongoing process, not an afterthought Automating testing and code quality analysis reduces maintenance overhead These tools help build robust, scalable, and maintainable applications Next Steps: Adopt these tools incrementally and refine your quality strategy