Jump to content

[Answered, not solved] Automated testing in Forge


GenElectrovise

Recommended Posts

Hi all, I've been wondering recently about how one would go about testing mods (I mean testing in a unit-testing sense here).

Took a look around the MinecraftForge GitHub repo and found the expected src/test/java folder, but most of the tests in here seem to be standalone mods (activated individually with booleans) designed to test a specific behavior.

Some, however, such as the LazyOptionalTest use JUnit. I suppose this is because game behaviours are really hard to mock-up for testing?

What's Forge's testing ethos?

Edited by GenElectrovise

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

Right then. I've tried some thing out over the last few days and come to the following verdict:

 

Unit-testing Minecraft and Forge classes is really hard. Let me give you an example:

 

For context, I'm using JUnit 5 with Mockito 3.8

I have a custom implementation of a fluid tank. I first tried writing a simple unit-test to check that "when there is no fluid in the tank and I try to drain some, drain zero units". I used to extend FluidTank, but in trying to write a simple test, I niow implement IFluidHandler and IFluidTank directly. The reason for this is that creating my object to test, it constructs a FluidTank, which contains this field:

@Nonnull
protected FluidStack fluid = FluidStack.EMPTY;

When FluidStack.EMPTY (a static field) is called on, the JVM tries to also load FluidStack's other static field, FluidStack.CODEC. This in turn causes a cascade of other static initialisations which  culminates in crashing the JVM with a NullPointerException sometime around it trying to either load a World or access a Registry. So not good.

I tried to @InjectMocks on that field, but the injection occurs after the object is instantiated, so the JVM has already crashed.

 

In order to get around this, you have to implement the aforementioned interfaces directly because: 1) They are the required interfaces so they have to be there anyway; 2) They contain no static fields, so they won't start a cascade.

 

The upshot? Forge and Minecraft are not designed to be tested in this way (not surprising), and have interlinking fields with will cause crashes.

What can we do? Well, you can test anything that you write. You can't test a FluidTank, but you can test an IFluidTank. Try to not have unnecessary static fields, and use constructor injection when possible. (This would fix the problem above: see my code below)

 

// How to fix that crash
// In FluidTank.java:

// Don't initialise the field now!
protected FluidStack fluid;

// Add a new constructor to allow modders to specify a starting stack.
public FluidTank(int capacity, Predicate<FluidStack> validator, FluidStack initialFluid)
  // Using constructor injection here means that a tester *can* inject a mock object for the initialFluid. This means that no initialisation 		cascade occurs!
    {
        this.capacity = capacity;
        this.validator = validator;
  
  		// Probably a good idea to test the stack for safety.
  		if (!validator.test(initialFluid)) throw new IllegalStateException("Whatever kind of error you want");
  		this.fluid = initialFluid;
    }

// Changing the current constructor to just use the overloaded one.
public FluidTank(int capacity, Predicate<FluidStack> validator)
    {
  		// This time it's safer to default to EMPTY
  		this(capacity, validator, FluidStack.EMPTY);
    }

 

I realise that this all sounds very... ahhh... something? (can't think of the word) I'm certainly not the expert on this and I'm not a professional tester so I've probably made some errors or assumptions here.

I would put this in as a pull request on the Forge Github if I could actually clone it (never works for some reason...)

 

Best,

GenElectrovise

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

There'd also be a small startup time tradeoff but I don't know how much of a difference that would make. Interesting idea with running tests later on... I hadn't thought of that... Might try that out just to satisfy curiosity!

How to ask a good coding question: https://stackoverflow.com/help/how-to-ask

Give logs, code, desired effects, and actual effects. Be thorough or we can't help you. Don't post code without putting it in a code block (the <> button on the post - select "C-type Language"): syntax highlighting makes everything easier, and it keeps the post tidy.

 

My own mod, Magiks Most Evile: GitHub (https://github.com/GenElectrovise/MagiksMostEvile) Wiki (https://magiksmostevile.fandom.com/wiki/Magiks_Most_Evile_Wiki)

Edit your own signature at https://www.minecraftforge.net/forum/settings/signature/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • 천왕패티쉬 ☆BCGAME4·COM♩ 장사패티쉬 하월곡패티쉬 용답패티쉬 노원패티쉬 kio88 개화패티쉬 숭인패티쉬 개봉패티쉬 의주패티쉬 qgv51 안성패티쉬 장충패티쉬 안산패티쉬 제기패티쉬 rtr66 압구정패티쉬 포천패티쉬 와룡패티쉬 쌍문패티쉬 jwq25 사근패티쉬 가평패티쉬 여수패티쉬 하남패티쉬 rcm93 연남패티쉬 강남패티쉬 나주패티쉬 광장패티쉬 phd77 삼성패티쉬 마포패티쉬 돈암패티쉬 도선패티쉬 mbu39 동두천패티쉬 상주패티쉬 장교패티쉬 응암패티쉬 nsd73 삼선패티쉬 안양패티쉬 선릉패티쉬 견지패티쉬 nrv63 장위패티쉬 포천패티쉬 당진패티쉬 개포패티쉬 hxh17 노고산패티쉬 안양패티쉬 신공덕패티쉬 보광패티쉬 jjn69 김해패티쉬 개포패티쉬 안산패티쉬 중화패티쉬 pfb96 궁정패티쉬 하남패티쉬 합정패티쉬 수표패티쉬 rnh67 남현패티쉬 행당패티쉬 예산패티쉬 노량진패티쉬 qhs52 문배패티쉬 보령패티쉬 북아현패티쉬 홍은패티쉬 nrh24 춘천패티쉬 창신패티쉬 경주패티쉬 하월곡패티쉬 baa72 청량리패티쉬 남대문패티쉬 관악패티쉬 익선패티쉬 pxo21 고양패티쉬 인사패티쉬 춘천패티쉬 내자패티쉬 bhl54 연지패티쉬 연건패티쉬 오산패티쉬 신사패티쉬 qtx10 갈월패티쉬 응봉패티쉬 등촌패티쉬 광주패티쉬 bgk64 청량리패티쉬 효자패티쉬 봉래패티쉬 제기패티쉬 yxw64 한강패티쉬 화곡패티쉬 김포패티쉬 홍성패티쉬 gfk29 남대문패티쉬 양재패티쉬 성남패티쉬 궁동패티쉬 xxe08
    • 양화유흥업소 ‡BCGAME4·COM☏ 청파유흥업소 율현유흥업소 염곡유흥업소 오산유흥업소 gyq52 적선유흥업소 만리유흥업소 상월곡유흥업소 하남유흥업소 wnh82 인천유흥업소 오쇠유흥업소 김포유흥업소 중화유흥업소 gut06 한남유흥업소 경산유흥업소 진주유흥업소 완주유흥업소 mlm93 용두유흥업소 당산유흥업소 공덕유흥업소 대전유흥업소 mte10 고창유흥업소 운니유흥업소 누하유흥업소 금산유흥업소 mgo09 영등포유흥업소 신내유흥업소 화방유흥업소 남양주유흥업소 jgn81 후암유흥업소 이방유흥업소 구수유흥업소 강북유흥업소 adu50 구로유흥업소 화동유흥업소 칠곡유흥업소 의정부유흥업소 ixr87 남양주유흥업소 행당유흥업소 충주유흥업소 송월유흥업소 nol97 서빙고유흥업소 청진유흥업소 천왕유흥업소 홍은유흥업소 lgg83 안산유흥업소 대치유흥업소 김제유흥업소 율현유흥업소 mwu46 대전유흥업소 마장유흥업소 여수유흥업소 여의도유흥업소 fiq06 의주유흥업소 성수유흥업소 창원유흥업소 군포유흥업소 qpd01 순천유흥업소 구수유흥업소 의정부유흥업소 고창유흥업소 anj43 산방유흥업소 속초유흥업소 강동유흥업소 묵동유흥업소 csj26 잠원유흥업소 파주유흥업소 동해유흥업소 홍익유흥업소 qfq11 양재유흥업소 안성유흥업소 거여유흥업소 포천유흥업소 axw60 중림유흥업소 여의도유흥업소 양산유흥업소 우이유흥업소 tfa85 인현유흥업소 하중유흥업소 효제유흥업소 명일유흥업소 cmg62 예장유흥업소 서소문유흥업소 사직유흥업소 목포유흥업소 wwn05 통영유흥업소 도곡유흥업소 평택유흥업소 충정로유흥업소 uml81 하계유흥업소 오류유흥업소 잠원유흥업소 안암유흥업소 iqe63
    • 메이져 경륜 놀이터‡BCGAME88·COM☞ 마다가스카르 경륜 검증 메이져 마리나베이 경륜 영상 [본사문의 텔레 JBOX7]메이져 경륜 ↖¶ 게임 영국 경륜 방법 메이져 인도 메이져 경륜 게임 [총판문의 카톡 JBOX7]메이져 경륜 〓→ 방송 트럼프타지마할카지노 경륜 바카라펍 메이져 예멘 메이져 경륜 홀덤바 [각종 오피 커뮤니티 제작]메이져 경륜 ↕▽ 모집 오세아니아 경륜 총판 메이져 미크로네시아 메이져 경륜 검증 [마케팅문의]메이져 경륜 ▦▼ 홀덤바 튀니지 경륜 전략 메이져 남아시아 메이져 경륜 캐쉬게임 [카지노본사]메이져 경륜 *♩ 토너먼트 그레나딘 경륜 바카라펍 메이져 세이셸 메이져 경륜 추천 [스포츠본사]메이져 경륜 ª▷ 리그 알바니아 경륜 본사 메이져 동티모르 메이져 경륜 검증 [토토본사 문의]메이져 경륜 ¶# 총판 잠비아 경륜 주소 메이져 슬로베니아 메이져 경륜 전략 [토토총판 구매]메이져 경륜 ⊙♪ 홀덤바 마다가스카르 경륜 놀이터 메이져 벨라지오카지노 메이져 경륜 커뮤니티 [카지노총판]메이져 경륜 ▥→ 포커대회 이란 경륜 카지노펍 메이져 코소보 메이져 경륜 싸이트 [야마토본사]메이져 경륜 ⊙㉿ 전략 아이티 경륜 단톡방 메이져 크라운카지노 메이져 경륜 여행 [바카라총판]메이져 경륜 ◐† 게임장 캐나다 경륜 싸이트 메이져 네덜란드 메이져 경륜 중계 [경마총판]보스니아 경륜 캐쉬게임 몬테카를로 경륜 캐쉬게임 [BCGAME 비씨게임 총판문의]알림 설정 추천 구독 좋아요
    • 실시간 축구 검증¶BCGAME4·C0M♠ 북키프로스 축구 사이트 실시간 캐나다 축구 주소 [본사문의 텔레 JBOX7]실시간 축구 ↗☆ 중계 타이완 축구 도박장 실시간 산마리노 실시간 축구 싸이트 [총판문의 카톡 JBOX7]실시간 축구 ↕▥ 리그 아르메니아 축구 경기 실시간 중앙아프리카 실시간 축구 카지노펍 [각종 오피 커뮤니티 제작]실시간 축구 ■← 캐쉬게임 선시티 축구 토너먼트 실시간 서유럽 실시간 축구 방송 [마케팅문의]실시간 축구 ㏘● 전략 미얀마 축구 본사 실시간 시에라리온 실시간 축구 캐쉬게임 [카지노본사]실시간 축구 ◎♩ 업체 모나코 축구 캐쉬게임 실시간 독일 실시간 축구 경기 [스포츠본사]실시간 축구 ♡@ 동영상 팔라우 축구 중계 실시간 중앙아시아 실시간 축구 방송 [토토본사 문의]실시간 축구 ℡㏇ 커뮤니티 아틀란티스카지노 축구 주소 실시간 크라운카지노 실시간 축구 단톡방 [토토총판 구매]실시간 축구 ↑☜ 놀이터 파나마 축구 검증 실시간 엘살바도르 실시간 축구 검증 [카지노총판]실시간 축구 ▧△ 접속 베트남 축구 도박장 실시간 자메이카 실시간 축구 중계 [야마토본사]실시간 축구 ‡◁ 유투브 덴마크 축구 게임 실시간 캄보디아 실시간 축구 쿠푼 [바카라총판]실시간 축구 ◐¶ 리그 아틀란티스카지노 축구 영상 실시간 카자흐스탄 실시간 축구 캐쉬게임 [경마총판]카보베르데 축구 경기 룩셈부르크 축구 동영상 [BCGAME 비씨게임 총판문의]알림 설정 추천 구독 좋아요
    • 사행성 카지노 동영상☜BCGAME88·COM§ 기니 카지노 리그 사행성 가이아나 카지노 본사 [본사문의 텔레 JBOX7]사행성 카지노 ↘○ 게임 덴마크 카지노 리그 사행성 모나코 사행성 카지노 영상 [총판문의 카톡 JBOX7]사행성 카지노 ◈♭ 카지노펍 리히텐슈타인 카지노 투어 사행성 북마케도니아 사행성 카지노 사이트 [각종 오피 커뮤니티 제작]사행성 카지노 ™◎ 영상 중앙아프리카 카지노 주소 사행성 카타르 사행성 카지노 리그 [마케팅문의]사행성 카지노 ㏇♡ 쿠푼 차드 카지노 방송 사행성 겐팅하이랜드카지노 사행성 카지노 방송 [카지노본사]사행성 카지노 ☜♤ 홀덤펍 니제르 카지노 방송 사행성 슬로베니아 사행성 카지노 커뮤니티 [스포츠본사]사행성 카지노 ◀↗ 싸이트 콩고민주 카지노 접속 사행성 크라운카지노 사행성 카지노 포커대회 [토토본사 문의]사행성 카지노 ♨# 추천 네팔 카지노 주소 사행성 카자흐스탄 사행성 카지노 주소 [토토총판 구매]사행성 카지노 ℡㏂ 유투브 레소토 카지노 방송 사행성 타지키스탄 사행성 카지노 토너먼트 [카지노총판]사행성 카지노 ㈜▒ 방송 알제리 카지노 전략 사행성 그랜드리스카지노 사행성 카지노 영상 [야마토본사]사행성 카지노 ▼¶ 홀덤펍 아리아카지노 카지노 접속 사행성 동남아 사행성 카지노 주소 [바카라총판]사행성 카지노 ○@ 유투브 북마케도니아 카지노 포커대회 사행성 산마리노 사행성 카지노 유투브 [경마총판]북키프로스 카지노 추천 자메이카 카지노 카지노펍 [BCGAME 비씨게임 총판문의]알림 설정 추천 구독 좋아요
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.