-
Notifications
You must be signed in to change notification settings - Fork 31
[Chore] Validate uniqueness of UI test keys #103
Conversation
func validate(keys: Set<String>) { | ||
guard self.keys.isDisjoint(with: keys) else { | ||
fatalError("Key duplication: \(keys)") | ||
} | ||
|
||
keys.forEach { | ||
self.keys.insert($0) | ||
} | ||
} |
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.
Shouldn't we add some locking?
Not sure if tests are executed in parallel right now, but it might be the case in the future
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.
Good call, done.
/// the method fatally errs. | ||
func validate(keys: Set<String>) { | ||
guard self.keys.isDisjoint(with: keys) else { | ||
fatalError("Key duplication: \(keys)") |
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.
Here we should print the intersection between self.keys and keys, not the whole keys
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.
Done.
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.
I left a couple of improvements, so that the usage of this is a bit more ergonomic. I have however some concerns:
- are we sure that this is the best way to solve this problem? I feel that detecting these at runtime is too late (i.e. waiting for the uitest to finish before finding out). I feel that implementing a simple script that does a similar job in the linting phase is much more useful, as it wouldn't even let the project build
- this is not thread safe. this is super bad, since test might (and will!) run in parallell
- are your sure that a singleton is the best approach here? probably yes (since we are not the ones launching the tests) but it might be worth to investigate
static let singletonInstance = UITestCaseKeyValidator() | ||
|
||
/// Set of keys with which the `validate` method of this instance has been invoked. | ||
private var keys = Set<String>() |
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.
private var keys = Set<String>() | |
/// The keys are the uitest keys, the values are the test case that implements them | |
private var knownKeys: [String: String] = [:] |
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.
Done.
|
||
/// Validates that the given `keys` are disjoint from any keys previously provided to this method. If a duplicate key is found, | ||
/// the method fatally errs. | ||
func validate(keys: Set<String>) { |
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.
func validate(keys: Set<String>) { | |
func validate(keys: Set<String>, testCaseName: String) { |
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.
Done.
guard self.keys.isDisjoint(with: keys) else { | ||
fatalError("Key duplication: \(keys)") | ||
} | ||
|
||
keys.forEach { | ||
self.keys.insert($0) | ||
} |
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.
guard self.keys.isDisjoint(with: keys) else { | |
fatalError("Key duplication: \(keys)") | |
} | |
keys.forEach { | |
self.keys.insert($0) | |
} | |
keys.forEach { | |
if let kownTestCaseName = self.knownKeys[$0] { | |
fatalError("Duplication detected. Key \($0) used both in \(testCaseName) and \(knownTestName)") | |
} | |
self.knownKeys[$0] = testCaseName | |
} |
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.
Done.
public extension ViewControllerTestCase where Self: XCTestCase { | ||
func uiTest(testCases: [String: VC.V.VM], context: UITests.VCContext<VC>) { | ||
|
||
UITestCaseKeyValidator.singletonInstance.validate(keys: Set(testCases.keys)) |
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.
UITestCaseKeyValidator.singletonInstance.validate(keys: Set(testCases.keys)) | |
UITestCaseKeyValidator.singletonInstance.validate(keys: Set(testCases.keys), testCaseName: "\(Self.self)") |
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.
Done.
Tempura/UITests/ViewTestCase.swift
Outdated
public extension ViewTestCase where Self: XCTestCase { | ||
func uiTest(testCases: [String: V.VM], context: UITests.Context<V>) { | ||
UITestCaseKeyValidator.singletonInstance.validate(keys: Set(testCases.keys)) |
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.
UITestCaseKeyValidator.singletonInstance.validate(keys: Set(testCases.keys)) | |
UITestCaseKeyValidator.singletonInstance.validate(keys: Set(testCases.keys), testCaseName: "\(Self.self)") |
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.
Done.
@FEC-bendingspoons Great comments, thanks!
|
Also, @danyf90 thanks for pointing out the lacking thread-safety, I should have noticed this myself. |
Why
Executing the
uiTest
methods with duplicate keys causes previously created images to be overridden. This is usually undesirable and should be prevented programmatically.Changes
A singleton
UITestCaseKeyValidator
instance for validating the uniqueness of UI test keys is introduced and used in the relevant methods.