CLOVIS
06/18/2025, 7:00 AMPoisonedYouth
06/18/2025, 8:24 AMhho
06/18/2025, 9:14 AMCLOVIS
06/18/2025, 9:42 AMCLOVIS
06/18/2025, 9:42 AMhfhbd
06/18/2025, 9:44 AMCLOVIS
06/18/2025, 9:47 AMhfhbd
06/18/2025, 9:49 AMCLOVIS
06/18/2025, 9:51 AMCLOVIS
06/18/2025, 9:52 AMVasily
06/18/2025, 3:01 PMvar UserTest by testSuite {
...
}
Is there any specific reason to use var
instead of val
in this example?CLOVIS
06/18/2025, 3:02 PMval
. var
won't even compile—thanks for noticing!Oliver.O
06/18/2025, 3:36 PMTestBalloon is able to run its own tests on most platformsActually, starting with 0.3.2, TestBalloon supports all Kotlin targets (with CI tests on all tiers). Unfortunately, the 0.3.2 release process was defective. Now I'm waiting for Maven Central support to help me publish a new set of releases, which is currently stuck with the publication status changing from "VALIDATED" to "FAILED" without giving a reason. 😖 Tags: • TestBallon has compartments, which I consider a better alternative to tags for major use cases, as they bundle in a tailored configuration. Compartments for specific use cases (
UI
, Concurrent
, RealTime
) come with a (hopefully) well-designed out-of-the-box implementation.
• Otherwise, tags would be a good example to demonstrate TestBalloon's extensibility, giving users the freedom to initialize tags by a mechanism of their choice:
package com.example.testLibrary
import de.infix.testBalloon.framework.TestAction
import de.infix.testBalloon.framework.TestConfig
import de.infix.testBalloon.framework.TestSuite
import de.infix.testBalloon.framework.disable
enum class Tag(val enabled: Boolean = true) {
SLOW,
FAST,
TOO_FAST(enabled = false) // <- or use a mechanism of your choice to initialize this, e.g. via Gradle properties
}
fun TestSuite.test(name: String, tags: Set<Tag>, action: TestAction) {
test("$name ($tags)", testConfig = TestConfig.tagDependent(tags)) {
action()
}
}
fun TestConfig.tagDependent(tags: Set<Tag>) = if (tags.all { it.enabled }) TestConfig else disable()
Skipping tests: TestBallon provides an example which documents skipped tests so that these won't be forgotten accidentally.
Your coverage of JUnit5 parameterization hell is excellent!
Fixtures: Can you point me to use cases for isolated (non-shared) fixtures? I'd love to learn more about those. Also, what's the use case for declaring a fixture outside a test suite?
Coroutines with `runTest`:
TestBalloon supports them but they are disabled by default (enable with TestConfig.testScope).That seems to be incorrect: TestBalloon uses `runTest`'s `TestScope` by default. Other integrations (randomness, files): A primary goal of TestBalloon is to provide extensibility by composition. TestBallon currently provides just two integrations, which are also intended to serve as examples for creating your own extensions. I wonder what other integrations might preferably come pre-packaged, and which ones would be better left to the framework's user, avoiding unnecessary (micro-)dependencies and feature creep. Again, an excellent article. Thank you for making the effort to write this up!
CLOVIS
06/18/2025, 7:58 PMCLOVIS
06/18/2025, 7:59 PMCLOVIS
06/18/2025, 8:08 PMCan you point me to use cases for isolated (non-shared) fixtures?Interestingly, that's kind of a hard question for me, because I basically never use shared fixtures. I think the best example I have is here: •
gradle.dir
is a fixture that refers to a temporary directory dedicated to this test. It is declared globally.
• by creating a new prepared value properties
that refers to gradle.dir / "gradle.properties"
, I know that it will refer to specifically the config for that test. It is declared in the suite, but could very well be declared globally.
Because each test gets its own instance of all prepared values, and thus their own temporary directory, it's safe to run all of these tests in parallel even though they use the same fixturesCLOVIS
06/18/2025, 8:10 PMCLOVIS
06/18/2025, 8:17 PMOliver.O
06/18/2025, 9:07 PMOliver.O
06/18/2025, 9:34 PMOliver.O
06/18/2025, 9:39 PMMervyn McCreight
06/19/2025, 12:51 AMCLOVIS
06/19/2025, 7:39 AM