Automated tests

All changes to Adobe Commerce projects should be covered by automated tests to meet the "Definition of Done" (DoD).

Understanding black, white, and gray tests

For example:

Assume there is a method with the signature function removeLetterFromString(string $letter, string $string): string:

Automated tests

Code changes must be covered by automated tests according to Classification of Magento Automated Tests. When choosing how to cover your changes, pick the most lightweight (execution-time wise) test type that will provide sufficient coverage. If you encounter an existing test that insufficiently covers your changes, you can delete that test but you must write a proper test to replace it. For example, a method that interacts with database has a unit test. You can replace it with an integration test.

Be aware that while high-level tests may provide coverage to code, it is only indirect coverage. Tests with more direct usage of the changed code will likely still needs to be written to ensure that regardless of the which components are actually used in the black box, the individual components still have coverage.

High level testing policy:

These tests must test the concrete implementation's behavior in a way that can not be inadvertently changed outside of the test itself.

For example: testing a concrete class through DI preference is not safe because it could be overridden via configuration of another loaded module. The test should not ask for the interface but rather the concrete implementation.

Integration tests

An integration test should be used to cover any code that does not meet the requirements of a unit test or functional test and should be thought of as essentially the default test type.

Integration tests come in many forms and can drastically vary in definition depending on what the intention of the test is. Generally speaking an integration test verifies that two or more things work together correctly; we are testing the integration of one thing with another thing. For the purpose of Magento testing, there are essentially two broad categories of integration tests: narrow-form and broad-form.

Integration test policy:

For example, Magento\Framework\SomeClassFilter may contain a FilterPool that comes with default FilterInterface's from Magento\Framework. Each of these implementations would have their own coverage pursuant to this document. However, there should also be some basic assertions within the test coverage for Magento\Framework\SomeClassFilter that ensure each of the default filters are loaded correctly. This should not be explicit coverage such as $filter->isLoaded('someDefaultFilter').

See: Running Integration Tests.

Functional tests

UI functional tests are inherently unstable regardless of platform or testing framework. For this reason, along with reasons of maintainability and quality assurance delivery time, these tests should be prioritized below all other tests types.

Functional test policy:

However, aside from those cases, UI functional tests should only be used to cover P0/P1 testing scenarios. If there are no scenarios available to make this decision, a product owner must be consulted for approval of new tests.

If there is a scenario that is not classified as a P0/P1 but should be, have a discussion with the product owner to get it elevated.

See Functional Tests.

Unit tests

There are a small number of use cases for unit tests in Magento. The nature of our code and development practices make it increasingly hard to write and maintain high-quality unit tests. Many of them end up being replaced by integration tests or are practically useless from the beginning due to how much mocking is needed to make them pass. Generally, an integration test is the preferred test type.

A unit test may be preferred when you have classes or methods that:

Examples:

And by explicit contrast here are some things NOT to cover:

Examples:

Integrity tests

Code to cover:

Expected code coverage:

For example:

Static tests

Code to cover:

Expected code coverage:

The static tests should be delivered to the Magento Coding Standard repository.

See code contributions for details.

Not all changes can be covered. For example, it is possible to scan a file for literals, but it is unfeasible to analyze string concatenation or any other dynamic way of building a variable.

Functional Manual Tests

Must cover new or changed application behavior (functional). Added/updated functionality should be covered by a functional Zephyr test(s) related to current sprint commitment.

The work cannot be considered as complete unless all the criteria are verified.