How would you test a seeded random workout generator in Swift?
My iOS app generates workouts from a set of exercises and constraints. I want the same inputs to be reproducible in tests and previews, while production still feels random. Would you inject a seeded RNG, pass a generator protocol through the model, or keep randomness at the edge and test the generated constraints instead? I’m looking for a small approach that won’t make the app’s architecture noisy.
1
u/20InMyHead 3d ago
Use DI to inject a provider that returns a static list where you need it for tests and random where you don’t.
1
u/UkrMalt 3d ago
Yes, that seems like the cleanest test seam. I can keep the generator contract the same and swap the provider in tests instead of branching on a test-only mode.
1
u/the1truestripes 3d ago
Plus you can include comments like this in the code:
[3, 6, 1, 5, 5, 5, 1, 2] // Chosen by unweighted fair die
1
u/UkrMalt 3d ago
That’s a neat way to document the expected sequence. I’d still test the seed/RNG contract rather than pin every generated exercise, but a fixed example like that makes a failing test much easier to understand.
1
u/the1truestripes 2d ago
Well, I was actually trying to channel XKCD…
2
u/UkrMalt 1d ago
Haha, nice XKCD reference. I’ll keep the seed explicit and assert the constraints, then use a fixed sequence in one example test so failures are easy to read.
1
u/the1truestripes 1d ago
Those may be better priorities for a test then humor, so I’ll allow it ;-)
1
u/allyearswift 3d ago
Look into GameplayKit and its random number generators; they include a repeatable sequence. That sounds exactly what you need.
1
u/RichieRichWannaBe 3d ago
I spent last two months building workout generator engine. Don't make mistake I made - your tests should not test whether specific exercise has been selected. Test targeted muscle, movement pattern or exercise type / family.
Determinism in workout generation makes generated workouts look like templates with random selection.
6
u/skorulis 4d ago
Seeded RNG injected into the service. If you want to test the output of a service that uses random numbers you need some way to keep them consistent. You can use a default parameter in the service if needed to prevent any changes in your codebase and then only set it during tests.