[swift-corelibs-dev] URLSession test fest!

Tony Parker anthony.parker at apple.com
Fri Jan 27 17:31:29 CST 2017


Hi Paul,

> On Jan 27, 2017, at 12:51 AM, Paul Stringer via swift-corelibs-dev <swift-corelibs-dev at swift.org> wrote:
> 
> Hi Tony,
> 
> First post and excited to join the party.

Great, welcome!

> 
> I'm sure this may have been solved many times over by the community already. Maybe we can collect some ideas on this. In the spirit of a small step to get things moving forward I'm sharing my own approach which has proven very effective for making URLSession extremely testable and it's amazingly little code with zero weirdness. All credit for the technique comes from Michael Feathers "Working Effectively with Legacy Code"
> 
> Here's the Gist:
> 
> https://gist.github.com/paulstringer/7f60e446c8b8b6be3647e42936b44877
> 
> And an explanation:
> 
> Leveraging the 'Subclass and Override Method' Technique I create a subclass e.g. 'NSURLSessionTestable'. I then expose any hidden dependancies using NSURLSession.sharedSession() in the code and make this dependancy injected to create a seam. Under test we are then able to substitute uses of sharedSession with an instance of NSURLSessionTestable.
> 
> NSURLSessionTestable is trivial in that we simply override dataTaskWithRequest() -> NSURLSessionDataTask()
> 
> The returned instance of NSURLSessionDataTask() does nothing. Instead we immediately invoke the completionHandler returning local instance variables of Data & URLResponse - these are provided by the test.
> 
> With this approach you have completely removed any network calls and asynchronous behaviour. This leads to extremely concise easy to setup and run tests.
> 
> It's so trivial I wonder if it would even be worth adding to the corelib - I'm personally a little wary of special 'knobs and dials' intended for making it more testable that could be hard to find or worse become used for doing odd stuff in production.
> 
> I've never seen any explicit 'Testable' classes so this would certainly mark a break from tradition but I personally have found the approach to work extremely well and through use of an explicitly named class it's intention revealing + easily discovered.
> 
> - Paul
> _______________________________________________
> swift-corelibs-dev mailing list
> swift-corelibs-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-corelibs-dev

This all sounds very interesting. I think that ‘testable’ subclasses would be totally reasonable as part of this test tool or our testing framework.

I have had some challenges in the past trying to carefully manage the public API surface vs. what is required for testing. This is easier in ObjC, where there are a lot of interesting hacks one can do to get at internal stuff. =) If an outcome of this is that we can figure out how to leverage @testable for ourselves in swift-corelibs-foundation then that would be awesome as well.

Looking forward to seeing more ideas,

- Tony



More information about the swift-corelibs-dev mailing list