Mocking data for UI testing in Xcode 7

Over the passage of time working on different projects i’ve seen a lot of different automation frameworks to handle UI testing. Mostly quite similar, they rely on the concept of having deterministic mock data that will power your views, they then drive your views through a user journey to assert an expected outcome. Most of these frameworks follow the Behaviour Driven Development (BDD) approach to writing tests through their adoption of Cucumber, I won’t go into the details of these here as its not really relevant.

Xcode UI testing however takes a different stance and on my current project, we’ve used it more as a “no, don’t unit test that, its a view controller, write a UI test” style tool, rather than a fully fledged automation framework. What this really means is, we’re asserting things like “the menu only contains 5 items that match our mocked data” or “when you hit login an activity indicator view is displayed”; whereas in UI Automation land we’d be testing things like “given i’m a logged out user, then I enter text into username and text into password, then I hit login, I should be presented the welcome screen”… Or similar. So effectively we’re testing small discreet units of UI within our application.

The two things we soon discovered we’d need for this are:

 The ability to inject dependencies where possible so we can load views without always necessarily progressing through a user journey to them.

The ability to test our views deterministically. This means we require MOCK data.

Why don’t we just go to the network, we can guarantee our API? Well, basically because you can’t. If you can run your test suite in a nuclear bunker, surrounded by a faraday cage with no outward or inward connectivity, then you’re onto a winner. The ability to be deterministic, to be certain that if your test fails its not because of some outward problem, but indeed due to a problem with your implementation, is vital for this specific type of testing. Other testing strategies such as end-to-end etc can accomodate this.

I’ve seen a few approaches to mocking data over the past decade. The common theme seems to be either one of:

Running a proxy that will returned canned responses to requests, configuring your network to use it as appropriate..

Littering all of your network code with #ifdef UI_AUTOMATION… and returning canned responses from an NSBundle.

In each individual test case, creating stubs and mocked responses for HTTP calls on the fly

All work, but it can be a little easier depending on your use case. SuperMock is inspired by both… a framework that you can drop into an existing code base, provide it with a simple .plist that maps network calls to canned responses in your NSBundle, functions as an NSURLConnection/NSURLSession proxy, but runs as part of your application test target, runs no server, requires no network and only leverages built in components of Foundation.

Example Scenario:

You have a menu in your application, which is dynamically driven from a web service, the contents of this menu can change at any time, but you’d like to assert that given some data, it populates and draws correctly on the screen.

Given the aforementioned problems… bring on the MOCK!

Example of the required Mocks.plist

Example of the required Mocks.json

By defining your original/real URL in

Mocks.plist

of SuperMock and running 1 line (ok maybe 2) of code in your AppDelegate, you are able to guarantee the value of your menu items in your application. Making your UI Test case very simple to write and very reliable to run.

How to implement SuperMock in your App.

How to implement SuperMock in your App.

Now when your HTTP client fires off a request for

http://mike.kz/api/menu.json

it will instead get returned

file://....menu_MOCK.json

from the NSBundle you provided earlier. In your UI Tests (whatever framework you use), you can now assert based upon these MOCK values. Whats advantageous is that there is no more work to be done and no extra code in your test cases to stub out responses.
This is a short whirlwind tour of my latest little pet project, but expect to see feature like dynamic override of mocks (for use when you want the same URL to return different responses upon each request) and some more real world scenarios.

I’ll be using this framework a lot myself in my personal projects over the coming months, so I may tweak / change / improve / try not to break it, in the process. Right now its functional but not complete and needs a new README.md ?

 

https://github.com/michaelarmstrong/SuperMock / @ArmstrongAtWork

 

SuperRecord an ActiveRecord implementation in Swift

All the media buzz around swift seems to be having some tangible effect. I won’t go into the opinionated slaw of Swift VS Objective-C VS Swift VS XYZ here :). Many of you know I freelance in the iOS space around London and beyond for SuperArmstrong and one of my recent clients asked me to work on a greenfield project to replace a very old wrapped web app they had. When we got down to the nitty gritties, one of their few requirements was that it should be written in Swift. My jaw did drop a little… considering this was about 20 days after Swift had first been publicly announced. After some conversation, we came to the mutual conclusion that they were brave.

Like many of the apps I work on, this project relied heavily on CoreData, as a convenience I decided i’d try out a library that I have a lot of respect for (even though its had its challenging moments) “MagicalRecord”, having only done organic CoreData for the past few years. As you probably know, Objective-C and Swift can sit alongside in a project and work in unison… however, not all the interoperability is 100% sound. I soon started to endure strange bugs and thanks to the incompleteness of Swift lldb support at the time (especially when mixing with Objective-C) these bugs soon became quite difficult to track down.

The most annoying was this:

let entityDescription = NSEntityDescription.entityForName("Pokemon", inManagedObjectContext: context)

Although harmless… this would actually fail when trying to insert an entity of that description into your managed object context. The culprit here? the NSString to String bridging (or vice versa).

To get around this bug (which I won’t go into too much detail) I began using:

let entityName = "Pokemon" as NSString
let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context)

Performing a forced downcast to NSString. So great, now it works… However, many of the MagicalRecord finders and helpers I was using, would not have these forced downcasts as they came from the Objective-C world. I first forked MagicalRecord, after delving into the source-code, making many changes for better Swift support, fixing some threading irregularities I then realised I was putting a lot of work into making something work that had more functionality than I required at the time. So I embarked on making a Swift ActiveRecord style “companion” to CoreData.

The reason I say “companion” and not “wrapper” is that I didn’t want to abstract away CoreData too much or remove the power from the hands of the developer. I wanted to make the developer’s life easier, whilst maintaining their flexibility.

I’d much rather do something like this:

let pokemon = Pokemon.createNewEntity() as Pokemon

and avoid the above lines + more.

Thereby SuperRecord was born. The original goals for SuperRecord were simple.

  1. Give me the ActiveRecord style finders I crave, optimise them, keep my application level code tidy, but still performant.
  2. Rather than me typing out the same code in each project to handle batch updates on my UITableView and UICollectionView classes, have a special “one size fits all” class that will act as your NSFetchedResultsControllerDelegate, providing “safe” batch updated to your reusable views.
  3. Additionally, I didn’t wanna have to spend too much time creating NSFetchedResultsControllers all the time either, so I added some helpers for this too.
  4. Be written in Swift, keeping the public API’s simple and stable, but changing the implementation as Swift changed and moved with updates.

In late October 2014 whilst still very much a work in progress, I released the first public version and it was featured in the great iOS Dev Weekly newsletter. I decided to release it early as I saw a lot of discussion around CoreData and Swift and thought there’d be a lot of people interested in this OSS effort, so we could build up a good toolset as a community. I’m still the only maintainer… (not by choice) but its early days :).

Below is some extract from the README.md but I suggest you head over to the project on github for more information and feel free to checkout the demo project also on github which shows how to use the safe batched updates along with some other common tasks.

 

Core Files

  • NSManagedObjectExtension.swift This extension is responsible for most of the “finder” functionality and has operations such as deleteAll()findOrCreateWithAttribute()createEntity() and allows you to specify your own NSManagedObjectContext or use the default one (running on the main thread).
  • NSFetchedResultsControllerExtension.swift In constant development, this Extension allows the easy creation of FetchedResultsControllers for use with UICollectionView and UITableView that utilise the SuperFetchedResultsControllerDelegate for safe batch updates.
  • SuperFetchedResultsControllerDelegate.swift heavily inspired by past-projects i’ve worked on along with other popular open source projects. This handles safe batch updatesto UICollectionView and UITableView across iOS 7 and iOS 8. It can be used on its own with your NSFetchedResultsController or alternatively, its automatically used by the NSFetchedResultsControllerExtension methods included in SuperRecord.
  • SuperCoreDataStack.swift a boilerplate experimental main thread CoreData stack. Can be used either as a sqlite store or in memory store. Simply by calling SuperCoreDataStack.defaultStack() for SQLite or SuperCoreDataStack.inMemoryStack() for an in memory store. Of course you have access to your context .context / .saveContext()

Usage

Create a new Entity

Assuming you have an NSManagedObject of type “Pokemon” you could do the following

let pokemon = Pokemon.createNewEntity() as Pokemon

Please add @objc(className) above the class name of all your NSManagedObject subclasses (as shown in the demo project) for now. Better support will be coming in the future.

Creating an NSFetchedResultsController

This feature is currently in progress with basic support so far, in future versions, sorting and sectionNameKeyPath’s will be supported. Until then you can create your own NSFetchedResultsController, however, if you have no need for the above missing functionality then simply use

lazy var fetchedResultsController: NSFetchedResultsController = self.superFetchedResultsController()

func superFetchedResultsController() -> NSFetchedResultsController {
return NSFetchedResultsController.superFetchedResultsController("Pokemon", tableView: tableView)
}

With Pokemon being the entity name of your NSManagedObject.

Delete Entities

I’m planning on adding much more powerful functionality around Delete soon, such as deleteAllWithPredicate() or deleteEntity(), right now all that is available is

Pokemon.deleteAll()

Method Listing

This isn’t an exhaustive list of all methods and classes, however it includes some of the most useful ones.

  • NSManagedObjectExtension
  • findAllWithPredicate(predicate: NSPredicate!, context: NSManagedObjectContext) -> NSArray
  • findAllWithPredicate(predicate: NSPredicate!) -> NSArray
  • deleteAll(context: NSManagedObjectContext) -> Void
  • deleteAll() -> Void
  • findAll(context: NSManagedObjectContext) -> NSArray
  • findAll() -> NSArray
  • findFirstOrCreateWithPredicate(predicate: NSPredicate!) -> NSManagedObject
  • findFirstOrCreateWithPredicate(predicate: NSPredicate!, context: NSManagedObjectContext) -> NSManagedObject
  • createNewEntity() -> NSManagedObject
  • findFirstOrCreateWithAttribute(attribute: NSString!, value: NSString!, context: NSManagedObjectContext) -> NSManagedObject
  • findFirstOrCreateWithAttribute(attribute: NSString!, value: NSString!) -> NSManagedObject
  • NSFetchedResultsControllerExtension
  • superFetchedResultsController(entityName: NSString!, collectionView: UICollectionView) -> NSFetchedResultsController
  • superFetchedResultsController(entityName: NSString!, tableView: UITableView) -> NSFetchedResultsController

NSFetchedResultsControllers created using this method will automatically handle safe batch updates.

Developer Notes

This whole project is a work in progress, a learning exercise and has been released “early” so that it can be built and collaborated on with feedback from the community. I’m using it in a project I work on everyday, so hopefully it’ll improve and gain more functionality, thread-safety and error handling over time.

The next key things to be worked on are Optionality (as this has changed in every Swift BETA), the CoreDataStack, adding more finders with more functionality and improving the NSFetchedResultsControllerExtension.

 

 

Brisk a simple lightweight Networking Framework written in Swift


This is gonna be a short and sweet blog post… I’ve been working on a little pet project to practise and learn some Swift, so I thought, what do I use the most in projects these days… its networking. I’ve published on github.com my first attempt Brisk, its no where near complete and only has basic functionality right now, but if it becomes interesting i’ll pick up the effort and add more, until then, its a great educational exercise, you can check it out here and be sure to contribute back 🙂 it should work on both OS X and iOS and is MIT Licensed.

 

How to setup Ruby on Rails on Ubuntu Linux

There are a lot of guides that do exactly the same as what i’m about to write about… the reason for this quick blog post is mostly a brain dump for myself.. but also because I always struggle to find up to date info for all of this in one place… and there are always gaps… So here goes! by the end of this short tutorial, you should have not only a working rails and ruby installation, running as a user, but also a ruby on rails hello world! whaaaaaat. … 

 

Ubuntu 13.04 on a Late 2012 Mac Mini

EDIT: Tonight i’ll be picking up one of my Mac Mini’s from the Datacenter to get Ubuntu 13.04 up and running! expect a full guide with drivers here shortly 🙂

So Ubuntu 13.04 LTS recently was released, It comes with the new 3.8.0-19 upstream of the Linux Kernel so I thought I’d check it out!

Although our patched 12.04 and 12.10 Ubuntu’s use version 3.124c of the tg3 NeXtreme drivers from Broadcom which have Mac Mini support… The version in Ubuntu 13.04 (3.128c) seems to have had this removed!

A simple run of modinfo tg3 | grep 1686 reveals sadly that support for detection of the Mac Mini Ethernet hardware seems to have been removed during 3.124 and 3.128 of the Broadcom tg3 drivers.

I’m likely to install 13.04 on a Mac Mini sometime soon so will update this post with a proper howto and any good news I encounter but I don’t think its good news…

lsmod | grep Ethernet returns
01:00.0 Ethernet controller: Broadcom Corporation Device 1686 (rev 01)

whilst modinfo tg3 | grep 1686 on our modified 12.04/12.10 machines using the NeXtreme driver from this blog returns:

alias:          pci:v000014E4d00001686sv*sd*bc*sc*i*

however on 13.04 returns nothing.

 

Instantly gain insight on someone else’s iOS App Architecture with MADebugTools

Just a quick post to say i’ve posted my first piece of code in over 5 years to GitHub. Its a clever little Objective-C iOS Category on UIViewController that seemlessly overlays a UILabel on every single view controller managed view with the class, nib or storyboard name that is used. Great for debugging old or inherited projects with minefield architectures. It uses some cool libobjc runtime techniques to accomplish this, but implementing the category is a case of dropping it into your project and Build+Go!

Category in Action

Grab the source code here as usual, follow me @italoarmstrong on twitter 🙂

 

 

Overclocking & Optimising the Raspberry PI

My Raspberry PI

Out the box the Raspberry PI comes with a ARM1176JZFS Core (armv6 with hard float aka armhf arch) running at 700 Mhz as part of the Broadcom SoC. Additionally the memory frequency is also limited. In recent firmwares however… tinkerers have had the ability to “overclock” the Raspberry PI to squeeze some extra juice out of it. Mine’s currently running at 1Ghz at a solid 48C temperature when under load. So the first question that springs to mind is… why doesn’t everyone overclock their Raspberry PI? Well… there have been (well founded) reports of SD card corruption, heat/power issues and instability. The idea of this post is to show the user how to safety squeeze every last bit, cycle and IOP out of their PI safely’ish and without being an astrophysicist. Read on for the know-how. … 

 

Installing Linux on a Late 2012 Mac Mini

So in the last post I discussed why the Mac Mini is the perfect machine for Linux and for Datacenters in general! One frustration some readers may be finding is that the networking chipset used by Ivy Bridge platform in Late 2012 Mac Mini’s doesn’t have native support in the Linux Kernel (as of now anyway). So its required to install a kernel module from the manufacturer/vendor (broadcom).

On their website they provide the “tg3” drivers for Linux kernels, however these are only good if you are running a Linux kernel < 3.5.x. If you take Ubuntu for example, 12.04 uses the 3.2.x stream, whereas 12.10 uses the 3.5.x stream and isn’t immediately compatible with the drivers on the broadcom page. This is due to the deprecation in 3.x and removal in 3.5.x of the asm/system.h header.

Read on for the fix, more and downloads. … 

 

How to Unlock almost any iPhone without any jailbreak or accessory

So… some of you may have already seen this, if you didn’t then, here it is 🙂 its pretty cool, it works… but has one caveat… Its a TEMPORARY unlock… i.e. it will unlock your phone sure, but once your TMSI (Temporary Mobile Subscriber Identity) is refreshed, you will have to repeat the process again… in the UK and US i think this happens when you switch the phone on/off or travel over a large geographic area… however it could potentially happen whenever…

Instructions on how to unlock are after the break 🙂

  1. Grab your iPhone
  2. Insert a supported Sim Card… so, if your phone is locked to Tmobile, put a Tmobile sim in there … 
 

Samsung F4 EcoGreen F4EG Firmware Bug Patch

Many people already know that the Samsung green drives have a bug in the firmware that may cause data loss, Samsung have created a patch that you need to create a bootable floppy disk along and drag in their file, if like me you don’t have a floppy disk drive & don’t want to mess around with USB booting and creation of a drive or just cannot boot from USB then you’ll need another solution, i’ve put together a quick bootable CDROM ISO that contains freedos and the patch, simply boot and type F4EG and hit enter, the patch will automatically detect your drives and update them. I hope this helps people out as it did me. As quoted from the original site:

“If identify commmand is issued from host during NCQ write command in the condition of PC ,
write condition is unstable.

So It can make the loss of written data.”
(Model : F4EG HD204UI, HD204UI/Z4, HD204UI/UZ4, HD155UI, HD155UI/Z4, HD155UI/UZ4)

Samsung Article regarding firmware and affected drives

CaptainGeek Bootable ISO: DOWNLOAD