🇺🇦 Українська (Ukrainian - Ukraine)
🇺🇦 Українська (Ukrainian - Ukraine)
Зовнішній вигляд
🇺🇦 Українська (Ukrainian - Ukraine)
🇺🇦 Українська (Ukrainian - Ukraine)
Зовнішній вигляд
Ця сторінка написана для версії:
1.21.4
Ця сторінка написана для версії:
1.21.4
На цій сторінці пояснюється, як написати код для автоматичного тестування частин вашого мода. Є два способи автоматично перевірити ваш мод: модульні тести за допомогою Fabric Loader JUnit або ігрові тести за допомогою фреймворку Gametest від Minecraft.
Модульний тест слід використовувати для тестування компонентів вашого коду, таких як методи та допоміжні класи, тоді як ігрові тести запускають реальний клієнт і сервер Minecraft для запуску ваших тестів, що робить його придатним для тестування функцій і ігрового процесу.
WARNING
Наразі цей посібник стосується лише модульного тестування.
Оскільки модифікація Minecraft покладається на інструменти модифікації байт-коду під час виконання, такі як Mixin, просто додавання та використання JUnit зазвичай не спрацює. Ось чому Fabric надає Fabric Loader JUnit, плаґін JUnit, який дає змогу проводити модульне тестування в Minecraft.
По-перше, нам потрібно додати Fabric Loader JUnit до середовища розробки. Додайте наступне до блоку залежностей у вашому build.gradle
:
testImplementation "net.fabricmc:fabric-loader-junit:${project.loader_version}"
Потім нам потрібно сказати Gradle використовувати Fabric Loader JUnit для тестування. Ви можете зробити це, додавши наступний код до свого build.gradle
:
test {
useJUnitPlatform()
}
Перезавантаживши Gradle, ви готові писати тести.
Ці тести написані так само, як звичайні тести JUnit, з деякими додатковими налаштуваннями, якщо ви хочете отримати доступ до будь-якого залежного від реєстру класу, наприклад ItemStack
. Якщо вам зручно працювати з JUnit, ви можете перейти до налаштування реєстрів.
Тести записуються в каталозі src/test/java
.
Однією з угод про іменування є показ структури пакета класу, який ви тестуєте. Наприклад, щоб перевірити src/main/java/com/example/docs/codec/BeanType.java
, ви повинні створити клас у src/test/java/com/example/docs/codec/BeanTypeTest..java
. Зверніть увагу, як ми додали Test
в кінці назви класу. Це також дозволяє вам легко отримати доступ до приватних методів і полів пакета.
Інша угода про іменування полягає в наявності пакета test
, наприклад src/test/java/com/example/docs/test/codec/BeanTypeTest.java
. Це запобігає деяким проблемам, які можуть виникнути під час використання того самого пакета, якщо ви використовуєте модулі Java.
Після створення тестового класу натисніть ⌘/CTRLN, щоб відкрити меню «Згенерувати». Виберіть Test і почніть вводити назву методу, зазвичай починаючи з test
. Натисніть ENTER, коли закінчите. Щоб отримати додаткові поради та підказки щодо використання IDE, перегляньте поради та підказки IDE.
Ви, звичайно, можете написати підпис методу вручну, і будь-який екземпляр методу без параметрів і типом повернення void буде ідентифіковано як тестовий метод. Ви повинні отримати наступне:
Зверніть увагу на зелені стрілкові індикатори в жолобі: ви можете легко запустити тест, і натиснувши по ньому. Крім того, ваші тести запускатимуться автоматично для кожної збірки, включаючи збірки CI, такі як GitHub Actions. Якщо ви використовуєте GitHub Actions, не забудьте прочитати налаштування GitHub Actions.
Тепер настав час написати ваш справжній тестовий код. Ви можете стверджувати умови за допомогою org.junit.jupiter.api.Assertions
. Перегляньте наступний тест:
public class BeanTypeTest {
private static final Gson GSON = new GsonBuilder().create();
@BeforeAll
static void beforeAll() {
BeanTypes.register();
}
@Test
void testBeanCodec() {
StringyBean expectedBean = new StringyBean("This bean is stringy!");
Bean actualBean = Bean.BEAN_CODEC.parse(JsonOps.INSTANCE, GSON.fromJson("{\"type\":\"example:stringy_bean\",\"stringy_string\":\"This bean is stringy!\"}", JsonObject.class)).getOrThrow();
Assertions.assertInstanceOf(StringyBean.class, actualBean);
Assertions.assertEquals(expectedBean.getType(), actualBean.getType());
Assertions.assertEquals(expectedBean.getStringyString(), ((StringyBean) actualBean).getStringyString());
}
@Test
void testDiamondItemStack() {
// I know this isn't related to beans, but I need an example :)
ItemStack diamondStack = new ItemStack(Items.DIAMOND, 65);
Assertions.assertTrue(diamondStack.isOf(Items.DIAMOND));
Assertions.assertEquals(65, diamondStack.getCount());
}
}
Щоб отримати пояснення того, що насправді робить цей код, перегляньте кодеки.
Чудово, перший тест спрацював! Але зачекайте, другий тест провалився? У журналах ми отримуємо одну з таких помилок.
java.lang.ExceptionInInitializerError
at net.minecraft.item.ItemStack.<clinit>(ItemStack.java:94)
at com.example.docs.codec.BeanTypeTest.testBeanCodec(BeanTypeTest.java:20)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: java.lang.IllegalArgumentException: Not bootstrapped (called from registry ResourceKey[minecraft:root / minecraft:game_event])
at net.minecraft.Bootstrap.createNotBootstrappedException(Bootstrap.java:118)
at net.minecraft.Bootstrap.ensureBootstrapped(Bootstrap.java:111)
at net.minecraft.registry.Registries.create(Registries.java:238)
at net.minecraft.registry.Registries.create(Registries.java:229)
at net.minecraft.registry.Registries.<clinit>(Registries.java:139)
... 5 more
Not bootstrapped (called from registry ResourceKey[minecraft:root / minecraft:game_event])
java.lang.IllegalArgumentException: Not bootstrapped (called from registry ResourceKey[minecraft:root / minecraft:game_event])
at net.minecraft.Bootstrap.createNotBootstrappedException(Bootstrap.java:118)
at net.minecraft.Bootstrap.ensureBootstrapped(Bootstrap.java:111)
at net.minecraft.registry.Registries.create(Registries.java:238)
at net.minecraft.registry.Registries.create(Registries.java:229)
at net.minecraft.registry.Registries.<clinit>(Registries.java:139)
at net.minecraft.item.ItemStack.<clinit>(ItemStack.java:94)
at com.example.docs.codec.BeanTypeTest.testBeanCodec(BeanTypeTest.java:20)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Це тому, що ми намагаємося отримати доступ до реєстру або класу, який залежить від реєстру (або, у рідкісних випадках, залежить від інших класів Minecraft, таких як SharedConstants
), але Minecraft не має. Нам просто потрібно трохи його ініціалізувати, щоб реєстри працювали. Просто додайте наступний код на початок вашого методу beforeAll
.
SharedConstants.createGameVersion();
Bootstrap.initialize();
INFO
У цьому розділі передбачається, що ви використовуєте стандартний робочий процес GitHub Action, який входить до прикладу мода та шаблону моду.
Ваші тести тепер виконуватимуться на кожній збірці, включно з тестами постачальників CI, таких як GitHub Actions. Але що, якщо збірка не вдається? Нам потрібно завантажити журнали як артефакт, щоб ми могли переглядати звіти про випробування.
Додайте це до свого файлу .github/workflows/build.yml
під кроком ./gradlew build
.
- name: Store reports
if: failure()
uses: actions/upload-artifact@v4
with:
name: reports
path: |
**/build/reports/
**/build/test-results/