[[Pre-requisites_-_test_quality_standards]]
= Test Quality Standards

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

All tests must follow these quality standards.

== Verify the Test Belongs in WildFly

Ensure the test validates current WildFly functionality.
Do not test the internal functionality of included libraries,
as those should be tested in the library's upstream test suite.
However, do test the integration of those libraries with WildFly.

== Add Only Correct and Understandable Tests

Tests must be clear and verifiably correct.
If a test is overly complex or uses questionable logic,
refactor it to use clear logic or consult with the original author to clarify intent.

== Avoid Duplicate Tests

Before adding a test, verify that the functionality is not already covered elsewhere.
Use tools like `git grep` to search for existing test coverage.

== Use Descriptive Test Names

Test class and method names should clearly describe what is being tested.
Jira IDs alone are not descriptive and require external lookup to understand the test purpose.
Jira references may be included in test comments or commit messages, e.g. in Javadoc `@see`.

== Document Tests with Javadoc

All test classes and non-trivial test methods must include Javadoc explaining what functionality is being tested and why.

== Expand Existing Tests When Appropriate

When adding test coverage for functionality similar to an existing test, consider adding test methods to the existing test class rather than creating a new class.
Each new test class adds overhead to execution time.
Only create a new class when the functionality is sufficiently different to warrant separation.

== Organize Tests by Subsystem

Place integration tests in subpackages under the relevant subsystem (e.g., `org.jboss.as.test.integration.ejb.async`).
When a test involves multiple subsystems, place it under the package for the specification that defines the primary behavior being tested.

== Document Non-Obvious Specification Requirements

When testing behavior mandated by specifications but not immediately obvious, include comments explaining the requirement (e.g., "Verifies Jakarta EE X.Y.Z - Description of requirement").

== Collocate Test Resources with Test Code

Place integration test resources (deployment descriptors, configuration files, etc.) in the same source directory as the test class.
This keeps all test artifacts together and makes tests easier to understand.

== Use Configurable Values for URLs and Ports

Do not hard-code URLs, hostnames, ports, or IP addresses.
Use configurable values provided by Arquillian or system properties to ensure tests work with different configurations and IPv6 addresses.

If a necessary configuration property is missing, file a Jira issue with component "Testsuite".

== Follow Best Practices for Commits

* Keep changes focused on the specific issue or feature being addressed.
* Do not include unrelated changes such as reformatting or typo fixes in feature commits.
Submit these separately.
* Prefer smaller, focused pull requests over large, difficult-to-review changes.
* Maintain consistency across commits (e.g., when renaming, update all references).
* Write clear commit messages that will be meaningful in the project history.
* Include the Jira ID in commit messages when working on a tracked issue.

== Avoid Blind Timeouts

Do not use `Thread.sleep()` without checking for the actual condition being awaited.
Use active waiting with timeouts or timeout mechanisms provided by the API being tested.

Make timeouts configurable with reasonable defaults.
For groups of similar tests, use a shared configurable timeout value.

== Provide Descriptive Assertion Messages

Always include descriptive messages in `assert*()` and `fail()` calls.
Clear messages make test failures easier to diagnose.

[source,java,options="nowrap"]
----
// Good
assertTrue("File config.xml should exist", configFile.exists());

// Bad - provides no context on failure
assertTrue(configFile.exists());
----

== Include Configuration Context in Exceptions

When tests fail due to possible misconfiguration, include the relevant configuration property names and values in exception messages.

[source,java,options="nowrap"]
----
File jdbcJar = new File(System.getProperty("jbossas.ts.dir", "."), "integration/src/test/resources/mysql-connector-java-5.1.15.jar");
if (!jdbcJar.exists()) {
    throw new IllegalStateException("Cannot find " + jdbcJar + " using ${jbossas.ts.dir} == " + System.getProperty("jbossas.ts.dir"));
}
----

== Clean Up Resources

* Close all sockets, connections, streams, and file descriptors in `finally` blocks or use try-with-resources.
* Avoid storing large objects in static fields.
If necessary, clear them in `finally` blocks.
* Do not modify server configuration unless you restore it in a `finally` block or `@After*` method.

== Keep Tests Configurable

Extract configuration values such as timeouts, paths, URLs, and counts into configurable properties defined at the beginning of the test class.
This improves test maintainability and flexibility.

== Follow Coding Standards

Coding standards for production code also apply to test code.
Please refer to link:Hacking_On_WildFly{outfilesuffix}[Hacking on WildFly] for the coding standards.
Just to mention the most frequent violations, always include the copyright header:

[code]
----
/*
 * Copyright The WildFly Authors
 * SPDX-License-Identifier: Apache-2.0
 */
----

and follow our import order for the project:

[code]
----
import static *

import java.*
import javax.*

import others.*
----
