When writing unit tests sometimes it is necessary to artificially elevate a member to `internal` in order to make it visible to unit tests where it could otherwise be `private` or `fileprivate`. We could introduce an `@testable` attribute that could be applied anywhere an access modifier is used. This attribute would elevate the access modifier to `internal` when the module is imported using the `@testable import MyModule` syntax in a test suite.
Is this something that others have interest in? Is it something that might be considered for Swift 4 now that phase 2 has begun?
On Feb 18, 2017, at 12:26 PM, thislooksfun <thislooksfun@repbot.org> wrote:
Big +1 from me. I see no point in having to elevate access just to make sure everything is working.
-thislooksfun (tlf)
On Feb 18, 2017, at 12:14 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
When writing unit tests sometimes it is necessary to artificially elevate a member to `internal` in order to make it visible to unit tests where it could otherwise be `private` or `fileprivate`. We could introduce an `@testable` attribute that could be applied anywhere an access modifier is used. This attribute would elevate the access modifier to `internal` when the module is imported using the `@testable import MyModule` syntax in a test suite.
Is this something that others have interest in? Is it something that might be considered for Swift 4 now that phase 2 has begun?
What happens when you try to test `MyModel.parse(_:)`?
···
On Feb 18, 2017, at 10:14 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:
When writing unit tests sometimes it is necessary to artificially elevate a member to `internal` in order to make it visible to unit tests where it could otherwise be `private` or `fileprivate`. We could introduce an `@testable` attribute that could be applied anywhere an access modifier is used. This attribute would elevate the access modifier to `internal` when the module is imported using the `@testable import MyModule` syntax in a test suite.
@testable is already a hack. Why not just extend it to fileprivate members?
~Robert Widmann
···
On Feb 18, 2017, at 1:14 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:
When writing unit tests sometimes it is necessary to artificially elevate a member to `internal` in order to make it visible to unit tests where it could otherwise be `private` or `fileprivate`. We could introduce an `@testable` attribute that could be applied anywhere an access modifier is used. This attribute would elevate the access modifier to `internal` when the module is imported using the `@testable import MyModule` syntax in a test suite.
Is this something that others have interest in? Is it something that might be considered for Swift 4 now that phase 2 has begun?
@testable is already a hack. Why not just extend it to fileprivate members?
That would be fine with me if others prefer that solution. It certainly leaves the rest of our code a lot cleaner.
···
Sent from my iPad
On Feb 19, 2017, at 12:08 AM, Robert Widmann <devteam.codafi@gmail.com> wrote:
~Robert Widmann
On Feb 18, 2017, at 1:14 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:
When writing unit tests sometimes it is necessary to artificially elevate a member to `internal` in order to make it visible to unit tests where it could otherwise be `private` or `fileprivate`. We could introduce an `@testable` attribute that could be applied anywhere an access modifier is used. This attribute would elevate the access modifier to `internal` when the module is imported using the `@testable import MyModule` syntax in a test suite.
Is this something that others have interest in? Is it something that might be considered for Swift 4 now that phase 2 has begun?
When writing unit tests sometimes it is necessary to artificially elevate a member to `internal` in order to make it visible to unit tests where it could otherwise be `private` or `fileprivate`. We could introduce an `@testable` attribute that could be applied anywhere an access modifier is used. This attribute would elevate the access modifier to `internal` when the module is imported using the `@testable import MyModule` syntax in a test suite.
I recently wrote a class with methods that do some complicated logic that isn't used anywhere else. I'd like to define them as private, but I also want to unit test the individual methods without having to generate verbose inputs for the class initializer (which calls the other methods).
There's also an auxiliary class which I'd like to be fileprivate since it's not relevant anywhere else, but it can't be because one or two unit tests are much simpler by accessing it directly.
So yeah, I get the "unit tests should only test the public API" argument. It makes sense. But it also makes sense to unit tests individual methods without having to worry about the context in which they are called.
Making private members visible in unit tests would be great, we have a lot of private @IBOutlets in our code which we either have to make internal just for unit testing or get them via KVC (which I consider a hack and it breaks if we e.g. rename the outlet.
My favourite solution to this is to allow tests in the same scope of the function (as previously mentioned by someone like D does). Though it is quite a big language feature to implement which I don't even know if Swift wants, and if so it might even need to move away from XCTest...