-
-
Notifications
You must be signed in to change notification settings - Fork 906
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
Allow example groups to order tests either randomly OR as they are defined #766
Conversation
Generated by 🚫 Danger |
By the way, this pull request also solves #152 🎉 This may not be the most lightweight API to allow it, but it achieves it nonetheless. |
@modocache or @jeffh - This has been out here for about a week now, and has a couple of positive reactions. I'd love to hear feedback if you have any. Otherwise, I think this is ready to go! 😃 |
Sources/Quick/DSL/DSL.swift
Outdated
} | ||
|
||
/** | ||
Defines an example group. Equivalent to `describe`. | ||
*/ | ||
public func context(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { | ||
World.sharedWorld.context(description, flags: flags, closure: closure) | ||
public func context(_ description: String, order: Order = Order.defined, flags: FilterFlags = [:], closure: () -> Void) { |
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.
Nit: I would avoid duplicating the type in all these: order: Order = .defined
.
Sources/Quick/DSL/World+DSL.swift
Outdated
@@ -143,7 +143,7 @@ extension World { | |||
} | |||
let callsite = Callsite(file: file, line: line) | |||
let closure = behavior.spec | |||
let group = ExampleGroup(description: behavior.name, flags: flags) | |||
let group = ExampleGroup(description: behavior.name, order: Order.defined, flags: flags) |
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.
Nit: I’d use type inference here: .defined
.
Thanks for the review and suggestions @NachoSoto 👍 |
Just a small up to know if this feature is still considered or not. |
I'd like to know too. I have a few pull requests waiting to be merged. |
+1 for merging this 👍 |
+1 to merge this. Should be really helpful. |
4eff3ce
to
ceec9ca
Compare
Sources/Quick/ExampleGroup.swift
Outdated
#else | ||
let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount))) | ||
#endif | ||
let i = randomized.index(firstUnshuffled, offsetBy: d) |
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.
Identifier Name Violation: Variable name should be between 3 and 40 characters long: 'i' (identifier_name)
Sources/Quick/ExampleGroup.swift
Outdated
srandom(UInt32(time(nil))) | ||
let d: Int = Int(random() % (unshuffledCount + 1)) | ||
#else | ||
let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount))) |
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.
Identifier Name Violation: Variable name should be between 3 and 40 characters long: 'd' (identifier_name)
Sources/Quick/ExampleGroup.swift
Outdated
for (firstUnshuffled, unshuffledCount) in zip(randomized.indices, stride(from: randomized.count, to: 1, by: -1)) { | ||
#if os(Linux) | ||
srandom(UInt32(time(nil))) | ||
let d: Int = Int(random() % (unshuffledCount + 1)) |
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.
Identifier Name Violation: Variable name should be between 3 and 40 characters long: 'd' (identifier_name)
|
||
private var randomizedExamples: [Example] { | ||
var randomized = Array(groupUnits) | ||
for (firstUnshuffled, unshuffledCount) in zip(randomized.indices, stride(from: randomized.count, to: 1, by: -1)) { |
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.
Line Length Violation: Line should be 120 characters or less: currently 122 characters (line_length)
Since it looks like this feature is still in demand, I am in the process of updating this branch since it's a year old and had a couple merge conflicts. I currently have the tests all passing locally on my Mac. It's running through CI now. I'll fix any breakages that might find. |
+1 to merge this, would love to be able to use this 😃 |
I also believe this PR would benefit all of us greatly. To not include such a magnificent feature is nothing short of a sin. |
Any movement on this? |
Badly missing ordering. Looking forward to see this merged 🤩 |
What is the status for this? |
ee2058f
to
0574b3c
Compare
I have updated this PR now, resolving merge conflicts, and ensuring we still have a clean local |
+1 from the future. If you're still in the past, maybe stay there for a bit 😅 |
srandom(UInt32(time(nil))) | ||
let offset: Int = Int(random() % (unshuffledCount + 1)) | ||
#else | ||
let offset: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount))) |
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.
Since Swift 4.2, perhaps this could be replaced with the newer randomness API?
Hey there! 👋🏼 I'm a new maintainer for this project and I'm trying to get the next release out ASAP and also clean up old issues and old PRs. I'm closing all PRs older than 1-2 years, but that doesn't mean these changes are necessarily being rejected. If you are still interested in contributing these changes, please submit a new PR branching from the top of We appreciate your work here and acknowledge the time and effort you put in to contribute! You're awesome. 💯 However, we are all volunteers here with limited capacity working for free. Unfortunately, that means we must close out stale issues and PRs to move the project forward in a reasonable way. We apologize for the inconvenience and appreciate your understanding! 😎 ✌🏼 |
@jwfriese Hey, I'm coming back to this. I'm curious what you think about changing Quick's default behavior so that it always attempts to execute tests in the order they're defined in (as you've noted, XCTest will ignore that attempt whenever it desires). Additionally, we'll give the guidance that developers should enable "Randomize Execution Order" in the xctestplan when they want to randomize execution order. This is less configurable than what this PR specifies, but I think overall what I just outlined will be better/easier for people to understand. |
This PR attempts to add the ordering functionality requested in #759 .
As written, this PR adds a new argument to
describe
-type andcontext
-type DSL methods -- anorder
enum value, which can be one of.defined
or.random
..defined
will ensure that the examples are run in the order they are defined within thedescribe
orcontext
blocks. This includes respecting nesteddescribe
andcontext
blocks in turn. The new test file (ExplicitOrderingTests.swift
) shows you exactly how you can expect it to handle nested describes..random
will randomize the examples within the describe, although it takes care to respect theorder
values defined by nesteddescribe
andcontext
blocks.Now, there exist some caveats to note here. The most significant of these is the fact that XCode 9 appears to revert to using alphabetical-by-name ordering of tests only when you use the side tray candies to run the tests. In other words, XCTest does not appear to respect the ordering we set as the return value of
testInvocations
fromQuickSpec
. I suspect this is related to #744 and #745, but I'm not sure.I argue that this PR is still worth adding, because it's still giving many users (anyone using Cmd+U or the command line to run their tests) new goodness. Please let me know if you disagree!
Also, I chose to default the Order to
.defined
because of the principle of least surprise -- that's closest to how things work now.Technically, we should probably default to
.random
since having an explicit ordering to tests is not the best practice.Here's some stuff I still want to do with this PR once I get some feedback of the high-level design:
complete documentation of how to use the feature✅it's probably unnecessary to maintainTrue, but not an optimization that I feel is worth it for now.childGroups
andchildExamples
as separate collections now within theExampleGroup
classadd some✅context
blocks to the test