Ben Woodworth
10/11/2023, 1:01 PMBen Woodworth
10/11/2023, 1:18 PMBen Woodworth
10/11/2023, 1:18 PMBen Woodworth
11/06/2023, 9:51 PMCLOVIS
11/06/2023, 11:09 PMCLOVIS
11/08/2023, 10:04 AMparametrize {
val letter by parameter(…)
// …executes X times…
}
However, many test frameworks require to be able to discover all tests before executing them.
For Prepared, I would require a way to declare all parameters that can be executed once before executing any test, only to register the possible cases.
suite("My test suite") {
parametrize {
val letter by parameter(…)
test("Some dummy test for $letter") {
letter.uppercase() shouldNotBe letter
}
}
}
Do you think it is possible to get this behavior with your library? Maybe by using a different parametrize
function but the same parameter
functions?
Additionally, my library has an additional concept to allow declaring suspend test fixtures without evaluating them: prepared values. Ideally, I'd like parametrized values to be compatible with this pattern as well. What do you think?CLOVIS
11/09/2023, 1:40 PMCLOVIS
12/21/2023, 10:00 PMCLOVIS
12/31/2023, 11:48 AMCLOVIS
12/31/2023, 1:36 PMpreparedSuite {
parameterize {
val text by parameterOf("123456", "hello64")
val int by parameterOf(4, 6)
test("Prepared $text $int") {
(int.toString() in text) shouldBe true
}
}
}
When combined with prepared values, it looks like:
parameterize {
val first by prepared { 1.toString() }
val second by prepared { 2.toString() }
val int by parameterOf(first, second)
test("Lazy test for value $int") {
(int() in "123456789") shouldBe true
}
}
It's a bit verbose, but it works.CLOVIS
01/01/2024, 10:23 AMCLOVIS
01/09/2024, 10:03 PM@BeforeTest
would be in other frameworks.
If I write something like the following, then it looks like the values are re-created on each iteration.CLOVIS
01/09/2024, 10:05 PMCLOVIS
01/11/2024, 2:40 PMparameterize {
val number by any<Int>()
}
If not, I'll probably create a small helper on my side to import Kotest's Arb
etcCLOVIS
02/15/2024, 3:33 PMCLOVIS
02/24/2024, 1:10 PMBen Woodworth
02/29/2024, 10:00 PMCLOVIS
03/02/2024, 11:28 AMCLOVIS
06/23/2024, 2:22 PMimport org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
@OptIn(ExperimentalWasmDsl::class)
kotlin {
…
wasmJs {
browser()
nodejs()
}
wasmWasi {
nodejs()
}
}
since WASM is finally in stable versions of NodeJS. Since Parameterize is pure common code, it should be as simple as that.CLOVIS
07/31/2024, 10:35 AMval int1 by parameterOf(1, 2, 3, 4, 5)
val int2 by parameter(<http://Arb.int|Arb.int>(), 1000) // accept Arb instances with a number of samples (maybe with a default value?)
val int3 by parameter(<http://Exhaustive.int|Exhaustive.int>(0..128)) // accept Exhaustive instances without requiring a number of samples
Here are a few examples of how these could be used:
// Kotest syntax
checkAll<Int, String> { i, s ->
foo(i, s)
}
// Parameterized syntax
parameterize {
val i by parameter(<http://Arb.int|Arb.int>(), 100)
val s by parameter(Arb.string(), 150)
foo(i, s)
}
// Kotest syntax
val person = Arb.bind(
Arb.string(),
<http://Arb.int|Arb.int>(),
) { s, i -> Person(s, i) }
…
// Parameterized syntax
parameterize {
val s by parameter(Arb.string(), 100)
val i by parameter(<http://Arb.int|Arb.int>(), 100)
val person = Person(s, i)
…
}
If this is added, there should be a way to specify the seed without explicit code by the user. For example, Prepared includes seed management already, and it should be able to inject its configured seed into the parameterize
block (one way or another…) such that the user doesn't have to do it themselves and can't forget it.
What do you think? 👀dave08
09/18/2024, 11:44 AMCLOVIS
12/24/2024, 9:12 AMSequence
out of a parameterize
block? Basically, use each run as a sequence generator
If so, you may want to advertise your stuff here: https://kotlinlang.slack.com/archives/CQ3GFJTU1/p1735010170520839?thread_ts=1735008576.288699&cid=CQ3GFJTU1CLOVIS
03/22/2025, 11:02 AMfun ParameterizeScope.allValues() =
parameter(1..13)
So, far, easy.
fun ParameterizeScope.allCards(): Card {
val suit by parameter(Suit.entries)
val value by allValues()
return Card(value, suit)
}
Is this safe?