Backend Handbook
Leapwise
  • đź‘‹Introduction
  • Software Design Principles & Clean Code
    • Atomicity
    • Modularity
    • Hierarchy
    • Loose coupling
    • Asynchronous programming
  • Development Practices
    • JavaDocs
    • Technical Debt
    • Testing Guidelines
      • The Importance of Test Automation
      • The Testing Pyramid
        • Unit Tests
        • Integration Tests
        • End-to-End Tests
      • Mutation Testing
      • Contract Tests
        • REST Controller Contract testing
        • OpenAPI Contract testing
      • Testing Frameworks
        • JUnit 5
        • Testcontainers
        • Mockito
      • Writing Clean Tests - Best Practices
    • Common library
    • Generic CRUD
    • Update Facade
  • Development Tools & Environment
    • Monitoring
    • Performance tuning
    • Multi-tenancy & Configuration Management
    • Git practices
    • CI/CD
    • Maven
  • Project Management
    • Jira
    • Confluence documentation
    • SCRUM
    • Our ways of working
  • LIFE AT LEAPWISE
    • Introduction
    • Who are we?
    • What do we do?
    • Our values
    • Hiring process
      • Hiring: A Mid Frontend Developer's Point of View
    • Benefits we offer
    • Onboarding process
      • Onboarding: A Senior Digital Marketing Specialist's perspective
    • Mentorship program
    • Career development
      • Trainings & certificates we offer
      • Career development: A Senior Software Developer's Insight
    • Community building
    • Juniorship
    • First-hand info from our first team member
    • Join our team
Powered by GitBook
LogoLogo

Company

  • About
  • Culture
  • Services

Insights

  • Leapwise Newsletter
  • Blog

© Leapwise

On this page
  • General
  • Structure
  • Naming
  • Test case naming convention

Was this helpful?

  1. Development Practices
  2. Testing Guidelines

Writing Clean Tests - Best Practices

As with writing clean code, there are some widely recognised best practices for writing clean Tests. It’s advised to follow such rules so that our tests look clear and cohesive, which makes code analysis for new team members much easier since analysis of application functionalities through clearly written tests is the best way to get a grasp on the applications logic.

In this article we will cover how to structure tests, best naming conventions and other general advice on Unit testing with Java in Spring.

General

Separate package

It’s a good idea to keep the test classes in a separate package from the source code.

Package naming convention

The package name of the test class should match the package name of the source class.

Write small and specific tests

Use helper functions, parametrized tests, AssertJ’s powerful assertions, asserting only what’s relevant and avoiding one test for all corner cases.

Write self-contained tests

Reveal all relevant parameters, insert data right in the test and prefer composition over inheritance.

Test close to production

Focus on testing a complete vertical slide. Testing each class in isolation by using mocks is a common testing recommendation. However, it has drawbacks: You are not testing all classes in integration and refactorings of the internals will break all tests, because there is a test for each internal class. And finally, you have to write and maintain multiple tests.

A careful balance should be made when deciding which part of the code to cover with Unit and which with Integration tests.

Mock external services

Although unit tests concentrate on specific and smaller pieces of code, there is a chance that the code is dependent on external services for some logic. Therefore, we should mock the external services and merely test the logic and execution of our code for varying scenarios.

Avoid In-memory DB

Structure

Arrange, Act, Assert (AAA)

A test should contain three blocks. Each block of code should be as short as possible. Use subfunctions to shorten these blocks.

  • Arrange (Input): Test data preparation.

  • Act (Action): Call the method or action that you like to test, mock the services you need to mock.

  • Assert (Output): Assertions to verify the actual against expected result.

Expected vs Actual

Prefix the variables with “actual” and “expected”. This increases the readability and clarifies the intention of the variable. Moreover, it’s harder to mix them up.

Specific Unit Tests

Avoid asserting multiple scenarios in the same test. Moreover, keep in mind what you have already tested in former tests. You usually don’t have to repeat assertions.

Avoid asserting multiple scenarios in the same test so in the case of test failures, it’ll be easier to determine which specific scenario failed. Therefore, write a unit test to test a single specific scenario.

Naming

Test case naming convention

The test names should be insightful, and users should understand the behavior and expectation of the test by just glancing at the name itself.

For example, the name of our unit test was testUserAccess doesn’t provide any meaningful information on what is actually being tested.

However, if we rename the test method into ifUserAccessAdmin_thenOk we know what the test method is testing just by looking at the method name which increases readability.

PreviousMockitoNextCommon library

Last updated 11 months ago

Was this helpful?

We can use for mocking external services.

Using an in-memory database (e.g. ) for tests reduces the reliability and scope of your tests. The in-memory database and the database used in production behave differently and may return different results.

The solution is to use for executing against a real database. Fortunately they are really easy to set up with Spring Boot.

Refer to this article for additional Unit test naming conventions:

7 Popular Strategies: Unit Test Naming Conventions - DZone
Mockito
H2
Testcontainers