Balatest is a framework for running unit tests on your Balatro mods. Avoid bugs and refactor with confidence!
https://github.com/BakersDozenBagels/Balatest/
#Balatest - Unit Testing for Balatro
1 messages · Page 1 of 1 (latest)
@heavy blaze 
Hey @cloud vine, how does this specifically hook into the game code?
Are you operating in the normal game flow or doing something weird?
I'm doing a VERY similar thing in https://discord.com/channels/1116389027176787968/1364331658261823589 but for remote control, so we might be able to share code
Mostly I'm calling G.FUNCS.start_run() and using the functions attached to buttons in a separate event queue, but sometimes it's been necessary to execute arbitrary code in a test (e.g. to test rental stickers, jokers with a use button, charms, etc)
With regards to Remotro in particular, these are currently non-goals for me:
- Defining or triggering tests from outside of a Balatro mod
- Interoperating with a language other than Lua
- Preventing the user from interacting with running tests
- Strictly defining/limiting the capabilities of tests
Feel free to steal any of my code, though, it's GPL-3.0 licensed
Ah, so Balatest is basically just starting a new game, forcing a particular state, and then testing something within that state only? Yeah our projects are p. different then, remotro is trying to model Balatro's entire game flow into a protocol
So in a sense remotro might be more capable of making integration/e2e tests than Balatest
if you are implementing more e2e-style tests lmk @cloud vine
Here's my current (unfinished) test suite running:
http://cdn.gdane.net/balatest3.mp4
@heavy blaze ? you could use this a lot, no? they have functions defined for a lot of actions
Would be useful for accelerating my RE efforts @astral whale
And unlike balatro's codebase I can pipe it into a sota llm and really speed up me being able to generate various hooks
ah right async vs sync is the issue here for you, i get it
or maybe i don't lol...i still think you could use this basically every action in game
noticed the reaction. if you dont want me sending ur code to an ai lab i wont do it and instead do it manually or use a on-device llm that cant use ur work as training data lol @cloud vine
I can't stop you either way, but it would make me a touch sad
It's not that much of an issue, especially if you provide proper attribution
Here I'm running Bakery's 292 unit tests via Balatest. These tests set up a game, perform some actions, and the automatically verify that the result is correct. They help me to avoid bugs and diagnose compatibility issues in my mods.
Relevant mods used:
Bakery: https://github.com/BakersDozenBagels/BalatroBakery
Balatest: https://github.com/Bake...
its own
alr good to know
it also automatically activates it
for most devices unsafe speed is overkill
but for my 13yo Mac it barely affords my needs
the point here is to run the tests as fast as it can because otherwise it takes forever
if i turned off the speedups in this these tests would easily take 3X as long
Ik that
as a Balatro modder, testing modded Balatro on a 13yo Mac is a masochistic move
yet I'm doing it
real
My 14 year old Mac agreea
my 1 year old macbook paid by my company is happy to jump in if any of you guys need it 😂
48 GB memory goes brrrrr
Well luckily I don't use that Mac that often
Just with some lovely development
Which is rough cause compilation is slow
this is really neat
I've already found a nice handful of bugs with these, too
im writing tests for morefluff right now and the api is really clean
...though i'm skipping Complexity Creep for now (probably the joker that needs to be tested the most), since i really dont want to get into that now
ill get to that at the end
big mood
i personally saved Proxy and Card Sleeve 'til near the end, haha
both of them have so many edge cases :agony:
the one slight issue i've had (which was my fault) is that .buy()ing a voucher results in it going to your joker slots which makes sense but feels off
😭
that is how the game works though so i can't complain
try .useing it?
yeah that's what i did and it worked
you should colour the pass/fail messages red/green btw
i should do way more with the results reporting tbh
this is very nice to see this early on in balatro's modding scene
this is incredible honestly
oh yeah if you have nopeus installed the unsafe speed doesn't work
which is proabbly a non-issue i just thought i'd mention it here for anyone who looks at the thread in future
that's fixable and i should fix it soon
writing the tests helped me find a bug in morefluff. thank you so much for making this
i found like half a dozen in bakery lmao
it's almost like testing for bugs finds bugs /positive
True...
the idea of unit testing mods at all is massive
we're lucky to have a well-documented API and testing
oh that's not what i thought you meant, probably not fixable and I don't want to think about the ramifications of that
it's called Unsafe for a reason; it can break shit
Also having an issue where cards slowly retract back into the deck
It only works for the first test, and then doesnt work again
Uninstalled talisman and it works fine now
can you be more specific on this? Do you mean before cash out when cards go from G.discard to G.deck?
G.hand to G.deck
that was this issue, i think
After scoring is complete, and blind is defeated. ^
it might just be a clash between the two mod's "skip all animations" settings
This is really cool
oh my god what the peak
Reminder: LMK if there's anything you want from this that it doesn't already do
(currently it's just output log coloring)
i feel like i'm stupid
i defined a test following the example in the readme
and it just doesn't select the blind?
okay well now it selected the blind but got stuck again
i feel like it's doing things too fast maybe?
oh it crashed at some point before and got stuck at this game speed
nvm, that wasn't the issue....
still gets stuck at blind select or hand drawn
Can you send your test definition and also your mod list
this is because it sets it ridiculously high and only tries to reset it once the tests complete. i think only one of the arrows works from this state
test definition:
Balatest.TestPlay({
jokers = {"j_joker"},
execute = function()
Balatest.play_hand({"2S"});
end,
assert = function()
Balatest.assert_chips(35);
end
});
mod list is literally just this code, too many jokers, smods and debugplus
and obviously balatest
i'll try without tmj
i'll try it with
This is working fine for me, what versions do you have?
how can i print this? or do i have to crash the game for it somehow?
Additional Context:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-0527d-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.7.1
Platform: OS X
Steamodded Mods:
1: DebugPlus by WilsontheWolf [ID: DebugPlus, Version: 1.5.0~dev, Uses Lovely]
2: Balatest by BakersDozenBagels [ID: Balatest, Priority: -1000, Version: 1.1.0, Uses Lovely]
3: Balafuzz by nnmrts [ID: Balafuzz, Priority: -999, Version: 1.0.0]
Lovely Mods:
with the above everything works
and, one sec
with this it doesn't:
Balatro Version: 1.0.1o-FULL
Modded Version: 1.0.0~BETA-0527d-STEAMODDED
LÖVE Version: 11.5.0
Lovely Version: 0.7.1
Platform: OS X
Steamodded Mods:
1: Too Many Jokers by cg [ID: toomanyjokers, Priority: 1000000, Uses Lovely]
2: Balafuzz by nnmrts [ID: Balafuzz, Priority: -999, Version: 1.0.0]
3: Balatest by BakersDozenBagels [ID: Balatest, Priority: -1000, Version: 1.1.0, Uses Lovely]
4: DebugPlus by WilsontheWolf [ID: DebugPlus, Version: 1.5.0~dev, Uses Lovely]
Lovely Mods:
okay wtf
just rechecked again
and that works
????
i'm soooo done
as a friend likes to say, "all technology is shit"
let me turn of vsync, maybe it was that
nah even with vsync off
ahhhh i don't even wanna know what that was
god just wanted to waste my time i guess
sorry for wasting yours
well, I'm glad it works now
there's a chance it was something something stale lovely cache something conflicting patches something
i'm not sure if i'm more curious what that means or more afraid of the answer
actually no lovely shouldn't be conflicting for this
the one lovely patch here is just for speed
then again i'm running balatro from source AND self compiled lovely
didn't lead to any issues so far but i guess that was it maybe
lmk if something like this comes up again
yup, thanks again
for the record, my test suite passes with this (minus #9, biased balance)
Hot tip for y'all:
If you have a file like this, you can watch lua it with DebugPlus to auto-run it on save
Balatest.run_test {
jokers = { "j_joker" },
consumeables = { "c_pluto" },
execute = function()
Balatest.use(G.consumeables.cards[1])
Balatest.play_hand { "2S" }
end,
assert = function()
Balatest.assert_chips(102)
end
}
You can now specify multiple categories for a test.
Also, the docs for Balatest.hook no longer lie about giving you an already-hooked function
I will also be deprecating requires since it's bad and dumb
i'm not too good at lua but i had to make a change to your source to get the mod to work for me
on line 470 and 479 of main.lua you had to_big(a):eq(b) which would throw
Error: [SMODS Balatest "src/main.lua"]:470: attempt to index a number value
I'm not sure why this dosn't work but i just replaced it with to_big(a) == to_big(b) and things started working
my test case is as follows
Balatest.TestPlay {
name = 'base_test_case',
requires = {},
category = 'base_test',
jokers = { 'j_joker' }, -- Start with a Joker
execute = function()
Balatest.play_hand { '2S' } -- Play a High Card
end,
assert = function()
Balatest.assert_chips(35) -- Total round score, *not* the last hand
end
}
my mod version is the latest from the github linked at the top.
i'd submit a pull request if i knew how to. thanks
What version of Talisman are you using?
and what number setting
no, it shouldn't be required
actually I might have an idea what's happening here
I'll put a proper guard in tonight
i have debugplus, flower pot, handy, cartomancer, balatest, 39joker, brainstorm, blueprint, card back injection, my mod and a few other texture mods
sick
i'm cooking so much with balatest
i used balatest to make benchmarks
Does balatest have support for testing save file reloading?
Like exiting to the menu and going back to the run
Not ATM but I can add support for that
That'd be great! Thank you so much
That's out now in version 1.3.0 as Balatest.reload()
i am now ready to take over the world
How do i run a set of tests with a category?
I can't seem to run them for some reason
Here are my tests by the way.
Balatest.run_tests('pkrm_gym', 'blind') should be correct. Can you eval Balatest.tests_by_mod_and_category.pkrm_gym for me?
Did you forget to actually run the file with your test definitions? What happens if you put a print next to them?
no no it runs fine when I do Balatest.run_tests('pkrm_gym')
i see
I think there's a mismatch between the mod_id and actual id used in naming the tests
oh of course
oh i'm dumb
yeah I use the mod ID not its prefix
how come the prefix still works when I use it to run though 🤔
it's falling back to running everything
I'll rework the error handling to be a bit more clear on this
thanks a lot!
The testing framework is really great. I enjoyed every single moment of using it.
Thanks! ✨
The default logging should be colored now. It also now pcalls anything you Balatest.q, which has a small chance of breaking things
I've pushed a small update for compatibility with bleeding-edge SMODS. As always, let me know if something breaks

... and another for no_auto_start (and also Balatest.exit_shop() without then starting a blind)
Another small update to account for more SMODS (smh my head)
Pushed a very small feature update (an optional parameter to Balatest.wait() to wait multiple times) and a bugfix
Balatest now has proper LSP-compatible documentation! Also, you can now face multiple distinct blinds in a test.
New feature: you can specify a set of mods required for a test to run, and Balatest will automatically skip that test if they're not all installed. This makes it easier to have tests for cross-mod content.