testing/trino-product-tests/DEVELOPER_GUIDE.md
This guide covers how to add or change product tests in the JUnit/Testcontainers framework.
For CI-failure reproduction commands, see RUN_PRODUCT_TESTS.md.
@TestGroup.*) describe which product-test suites should run a test. Tags can be applied to classes or methods.SuiteRunner.Execution model:
Environment and test code both use inheritance heavily:
@RequiresEnvironment compatibility is assignability-based, so hierarchy design directly affects reuse.Tags are equally critical:
@ProductTest.@RequiresEnvironment(...).@TestGroup.* tags used by suites. Tags can be applied to test classes or individual test methods.Use @TestGroup.ProfileSpecificTests for tests that must only run in a suite that explicitly selects their
environment-specific tag. This preserves the legacy product-test behavior where broad suites exclude tests that require
a particular environment/profile, while targeted suites include them through tags such as @TestGroup.Mysql,
@TestGroup.Ldap, or @TestGroup.HdfsImpersonation.
Example pattern from current product tests:
@ProductTest
@RequiresEnvironment(MySqlEnvironment.class)
@TestGroup.Mysql
@TestGroup.ProfileSpecificTests
class TestCreateTableAsSelect
{
@Test
void testCreateTableAsSelect(MySqlEnvironment environment)
throws Exception
{
try (Connection conn = environment.createTrinoConnection();
Statement stmt = conn.createStatement()) {
stmt.execute("DROP TABLE IF EXISTS mysql.test.nation_ctas_tmp");
stmt.executeUpdate("CREATE TABLE mysql.test.nation_ctas_tmp AS SELECT * FROM tpch.tiny.nation");
}
}
}
@BeforeEach, @AfterEach, etc.)Prefer environment-owned lifecycle hooks for reusable setup/cleanup behavior. This keeps cleanup logic in one place and avoids repeating setup/teardown in every test class.
Use test-level lifecycle methods only when the setup is specific to that test class (for example, test-local fixture creation that is not shared with other classes). Keep these methods minimal and avoid storing environment objects in fields; pass the environment directly to test methods and helpers instead.
Default rule: reuse an existing environment if at all possible. Environments take significant time to start and stabilize.
Use an existing environment when:
Add a new environment when:
Environment compatibility in suites relies on class hierarchy/assignability. Keep environment class design explicit and predictable.
io.trino.tests.product.suite.includeTag(...) and excludeTag(...) plus explicit environment runs.pt matrix by calling suite main methods directly.Runtime expectations:
When adding new coverage:
Use flaky annotation only when:
Expectations:
Design and maintenance guidance:
Before finalizing changes:
@ProductTest, @RequiresEnvironment, and correct tags.