Skip to main content
A test suite is a class annotated with @HytaleSuite. It groups related test methods under a shared name and configuration. While @HytaleSuite is technically optional (any class containing @HytaleTest methods will be discovered), using it gives you control over naming, isolation, and tagging.

Basic Suite Declaration

import com.frotty27.hrtk.api.annotation.HytaleSuite;
import com.frotty27.hrtk.api.annotation.HytaleTest;
import com.frotty27.hrtk.api.assert_.HytaleAssert;

@HytaleSuite("Crafting System Tests")
public class CraftingTests {

    @HytaleTest
    void woodPlanksRecipeExists() {
        // ...
    }

    @HytaleTest
    void craftingRequiresCorrectMaterials() {
        // ...
    }
}
If you omit the value, the suite name defaults to the class’s simple name (e.g., CraftingTests).

Naming Conventions

Choose suite names that are descriptive and group-oriented. They appear in test output and JSON exports.
PatternExample
Feature-based"Crafting System Tests"
Component-based"HealthComponent Tests"
Layer-based"Command Integration Tests"
Suite names appear in the formatted console output under each plugin header. Keep them concise but meaningful — they are the first thing you read when scanning results.

Isolation Strategies

The isolation parameter on @HytaleSuite controls how the suite’s tests interact with live server state. This is critical for tests that mutate the ECS store or world.
import com.frotty27.hrtk.api.lifecycle.IsolationStrategy;

@HytaleSuite(value = "ECS Mutation Tests", isolation = IsolationStrategy.SNAPSHOT)
public class EcsMutationTests {
    // ECS state is snapshot before the suite and restored after
}

@HytaleSuite(value = "Block Placement Tests", isolation = IsolationStrategy.DEDICATED_WORLD)
public class BlockTests {
    // A temporary void world is created and destroyed
}

NONE

Tests run against live server state. Best for read-only and pure logic tests. Default.

SNAPSHOT

ECS state is captured before the suite and restored after. Best for component mutation tests.

DEDICATED_WORLD

A temporary void world is created for the suite and destroyed after. Best for block and spawn tests.
See the Isolation Overview for a detailed comparison.

Suite-Level Tags

Apply @Tag at the class level to tag every test in the suite. These tags combine with any method-level tags.
import com.frotty27.hrtk.api.annotation.Tag;

@HytaleSuite("Combat Tests")
@Tag("combat")
public class CombatTests {

    @HytaleTest
    @Tag("damage")   // This test has tags: ["combat", "damage"]
    void swordDamageIsCorrect() { }

    @HytaleTest       // This test has tags: ["combat"]
    void shieldBlocksAttack() { }
}
You can then filter runs by tag:
/hrtk run --tag combat
/hrtk run --tag damage

Suite-Level @Disabled

Disable an entire suite by annotating the class with @Disabled. All methods will be reported as SKIPPED with the provided reason.
import com.frotty27.hrtk.api.annotation.Disabled;

@HytaleSuite("Legacy Tests")
@Disabled("Pending migration to new ECS API")
public class LegacyTests {
    // All tests in this class will be skipped
}

One Suite Per Class

Each class is one suite. HRTK instantiates the class using its no-argument constructor before running any tests. Instance fields are shared across all tests in the suite (within a single run), but each suite gets a fresh instance.
HRTK requires a no-argument constructor on your test class. If your class has constructor parameters, the suite will fail to instantiate and all tests will be marked ERRORED.

Next Steps