Comments (14)
I'm hesitant to add a feature that allows users to control the seed beyond the initial seed in the checker arguments structure. It's an implementation detail of the underlying RNG that it exists at all.
from swiftcheck.
I'll note that if you have a deterministic idea of how something should be constructed, write out the function that describes it.
from swiftcheck.
Here it is:
extension Gen {
/// Initializes the generator's internal Random Number Generator with a specified seed.
public func withSeed<S : BinaryInteger>(_ seed : S) -> Gen<A> {
...
}
}
If you do not want to implement this, can you provide a workaround or some other way to achieve the deterministic/reproducible behavior that I'd like to see for this case?
i.e., the case is:
"where the length of an array that I need to generate will be determined dynamically by the code under test". i.e., SwiftCheck generates some values, I run some of my code-under-test and verify that it is correct. Then I need to generate an array of values the length of which is functionally determined by the already verified correct output of the code-under-test.
from swiftcheck.
I’m still confused by this setup. You have a property that generates a size to pass to a generator so it can build you an array of that size to feed to your program, right? Where along this chain do you capture the RNG’s seed to make it generate “deterministic” outputs?
from swiftcheck.
As I mentioned previously, the seed would be passed as input to the property via an Arbitrary.Int. This way there would still be randomness (otherwise I could just fix the values via the repro CheckerArg).
from swiftcheck.
But why use an arbitrary integer to generate a seed value at all? Could you show me a little pseudo-code of your setup, I think it'll help me comprehend this better.
from swiftcheck.
So that it will be random yet repeatable if needed.
from swiftcheck.
Here is some pseudo-code for it:
property("findCorrelations produces correct results.") <-
forAll(CustomEntityArrayGen(upperBound: 100),
CustomEntityArrayGen(upperBound: 75),
Int.arbitrary) {
let (array1, array2, checkIndicesSeed) = $0
let res: Array<AnotherCustomEntity> = CodeUnderTest.f(array1, array2)
// res is not easily predictable without generating a lot more data and doing
// basically a reimplementation of `CodeUnderTest.f` in the tests.
// res is also not able to be exhaustively checked.
// thus, I'd like to generate a random sampling of indices into `res`
// to perform swaps on and see if some function g(swapped_res) is less
// than g(res). (f is supposed to produce a res that maximizes g(res)).
let last = res.index(before: res.endIndex)
let indexGen = Gen<Int>.choose((0, last))
// note that i'm using `variant` in the following. I'd prefer to use `withSeed`
// as that would make the code fully deterministic/repeatable.
//
let swapGen = indexGen.flatMap { (i) in indexGen.suchThat { $0 != i }.flatMap {
Gen.pure((i, $0))
}.variant(checkIndicesSeed)
let numSwaps = h(res.count) // numSwaps is some function of res.count
// generate numSwaps swaps with swapGen, do the swaps on res and
// check g() values thereof.
}
from swiftcheck.
@CodaFi Have you had enough time to digest that code yet?
from swiftcheck.
@johanatan I'm sorry for neglecting this. I'm a student in university and it's exam season. I owe you a comprehensive reply, and I simply haven't found the time to do so.
from swiftcheck.
Oh, gotcha. No worries. Just wanted to make sure it was still slated for attention at some point.
from swiftcheck.
Let me try something quick and dirty: It seems like you have an unexpressed dependency between the collection generator and the indices generator:
property("findCorrelations produces correct results.") <-
forAll(CustomEntityArrayGen(upperBound: 100),
CustomEntityArrayGen(upperBound: 75),
Int.arbitrary) {
let (array1, array2, checkIndicesSeed) = $0
let res: Array<AnotherCustomEntity> = CodeUnderTest.f(array1, array2)
// res is not easily predictable without generating a lot more data and doing
// basically a reimplementation of `CodeUnderTest.f` in the tests.
// res is also not able to be exhaustively checked.
// thus, I'd like to generate a random sampling of indices into `res`
// to perform swaps on and see if some function g(swapped_res) is less
// than g(res). (f is supposed to produce a res that maximizes g(res)).
let indexGen = Gen.fromElements(of: res.indices)
return forAll(Gen.zip(indexGen, indexGen)) { (i, j) in
// Apply swap, check properties
}
}
from swiftcheck.
Ah, so forAll
can be nested? Yea, that should work if so.
from swiftcheck.
Going to close this due to inactivity. Please feel free to reopen it if there is an update.
from swiftcheck.
Related Issues (20)
- How to define arbitrary extensions for recursive datatypes? HOT 5
- Preferred idiom for testing exception-throwing code HOT 1
- Generator is not used during shrinking. HOT 2
- no Gen.let or heterogeneous sequence/tuple? HOT 7
- `forAll` doesn't support explicit generator being passed HOT 9
- Gen.frequency seems to fixate on a single generator for a single run HOT 1
- passing any checkerargs results in only a single test case running HOT 8
- How exactly to rerun failed examples? HOT 5
- Doesn't compile with Xcode 10.2 HOT 1
- String generator breaks if test not always true HOT 2
- StdGen.genRange seems to have wrong value HOT 2
- Xcode canvas for SwiftUI always fail HOT 1
- Code from README doesn't compile
- Asynchronous Testing
- Integer partition generator
- Xcode 12 or swift 5.3 incompatibility
- SwiftCheck
- Unable to run Playground HOT 1
- (U)Int `arbitrary` implementation provides limited values with `.proliferate(withSize:)`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swiftcheck.