-
Notifications
You must be signed in to change notification settings - Fork 680
Use test TimeSource in continually tests #4109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use test TimeSource in continually tests #4109
Conversation
TimeMarkCompat was only necessary because of a breaking change in Kotlin 1.7 - but that was 2 years ago and Kotest now requires more recent versions, so TimeMarkCompat can now be removed. timeInMillis is only used for measuring times, so it can be replaced with stdlib `measureTime {}`/`measureTimedValue {}`
# Conflicts: # kotest-common/api/kotest-common.api
… they're pretty-printed using Duration#toString)
b4cf86b
to
28bf237
Compare
/** | ||
* Store the [TimeSource] used by [continually]. | ||
* | ||
* @see getContinuallyTimeSource | ||
*/ | ||
internal class ContinuallyTimeSource( | ||
val timeSource: TimeSource | ||
) : CoroutineContext.Element { | ||
|
||
override val key: CoroutineContext.Key<ContinuallyTimeSource> | ||
get() = KEY | ||
|
||
internal companion object { | ||
/** | ||
* Retrieves the [TimeSource] used by [continually]. | ||
* | ||
* For internal Kotest testing purposes the [TimeSource] can be overridden. | ||
* For normal usage [TimeSource.Monotonic] is used. | ||
*/ | ||
internal suspend fun getContinuallyTimeSource(): TimeSource = | ||
coroutineContext[KEY]?.timeSource | ||
?: TimeSource.Monotonic | ||
|
||
internal val KEY = object : CoroutineContext.Key<ContinuallyTimeSource> {} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the 'retry' tests PR #4101 I added a val timeSource
to the RetryConfig.
Here I'm trying a different approach and storing the TimeSource in the CoroutineContext.
I think using the CoroutineContext is better, because it makes it easier to test any continually()
functions without modifying the ABI, and it doesn't expose any options for users (even the option is guarded with @KotestInternal
).
I'd like to revisit the retry
tests, and refactor the eventually
tests, to do the same.
"Test failed after \\d+ms; expected to pass for 3000ms; attempted 100 times\nUnderlying failure was: 100 should be < 100".toRegex() | ||
e.message?.matches(r) ?: (false shouldBe true) | ||
n shouldBe 11 | ||
failure shouldHaveMessage "Test failed after 360ms; expected to pass for 3s; attempted 10 times\nUnderlying failure was: expected:<true> but was:<false>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor note: previously the regex assertion wasn't triggered, and wasn't correct.
I changed the expected message from Underlying failure was: 100 should be < 100
to Underlying failure was: 10 should be < 10
.
# Conflicts: # kotest-assertions/kotest-assertions-core/src/jvmTest/kotlin/io/kotest/assertions/nondeterministic/EventuallyTest.kt # kotest-assertions/kotest-assertions-shared/src/jvmTest/kotlin/com/sksamuel/kotest/assertions/until/UntilTest.kt
- The test TimeSource uses a virtual time, so the tests run faster. - The elapsed duration is reproducible, so the tests can assert the specific elapsed time. - Use CoroutineContext to store & retrieve the TimeSource (This helps with testing both `continually(duration)` and `continually(config)` functions, and doesn't require adding an option in `ContinuallyConfiguration`)
28bf237
to
7c8ebc6
Compare
…n-continually-tests # Conflicts: # kotest-assertions/kotest-assertions-core/src/commonMain/kotlin/io/kotest/assertions/nondeterministic/continually.kt # kotest-assertions/kotest-assertions-core/src/jvmTest/kotlin/io/kotest/assertions/nondeterministic/ContinuallyTest.kt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing import. Style consideration optional. Otherwise looks good!
...-assertions-core/src/jvmTest/kotlin/io/kotest/assertions/nondeterministic/ContinuallyTest.kt
Outdated
Show resolved
Hide resolved
...t-assertions-core/src/commonMain/kotlin/io/kotest/assertions/nondeterministic/continually.kt
Outdated
Show resolved
Hide resolved
Use a test TimeSource in `eventually` tests. - The test TimeSource uses a virtual time, so the tests run faster. - The elapsed duration is reproducible, so the tests can assert the specific elapsed time. - Use CoroutineContext to store & retrieve the TimeSource (This helps with testing both `eventually(duration)` and `eventually(config)` functions, and doesn't require adding an option in `EventuallyConfiguration`) Depends on: #4105 Related: #4109 --------- Co-authored-by: OliverO2 <Oliver.O456i@gmail.com>
Use a test TimeSource in
continually
tests.continually(duration)
andcontinually(config)
functions, and doesn't require adding an option inContinuallyConfiguration
)Dependencies