Question

My unit test suite contains a few test cases that are only applicable for the latest iOS version. Expectedly, these tests fail when running the suite on an older iOS version.

Is there a standard way to indicate that these test cases should run on a specific iOS version only?

One option I thought about:

- (void) testSomethingThatOnlyWorksOniOS7
{
    const BOOL iOS7OrHigher = floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1;
    if (!iOS7OrHigher) return;

    // Actual test goes here
}

Alternatively, could I tell SenTestCase to skip certain tests dynamically?

Was it helpful?

Solution

Your approach seems fine to me.

Generally speaking, I do not think that there is something like a "standard way" to selectively execute unit tests based on iOS version.

On the one hand, your approach is the same that can be used to implement one feature selectively or in different ways according to iOS version. Possibly you already know about this discussion on CocoaWithLove: Tips and Tricks from conditional.... It's pretty old, but the approaches described here to hold still.

You do not specify the way your unit tests are executed, but the real cool way to handle this, IMO, would be to be able to specify which tests to execute outside of the implementation, so that you state which ones are for iOS7 only and do not pollute your test implementation.

This could done, e.g., through a version number associated to each test; before calling the unit test implementation you check the version number in the function calling, e.g., testSomethingThatOnlyWorksOniOS7.

EDIT:

Actually, things could be easier that what I thought in the first place. Now I am going a bit hacky...

You could modify the place in OCUnit where the actual test method call is done (no idea about this, sorry, but I do not think it should be hard to find out...) so that it checks on the selector name: you convert the selector name into a string (NSStringFromSelector) and if it matches some regular expression, you take some specific branch (which would simply be in your case, ignoring that test).

If you are worried by modifying OCUnit, which might not be sensible, what I said above could be done through method swizzling: only if the selector name does not match your expression, you call the original implementation, otherwise do nothing.

OTHER TIPS

The best way is to run respondsToSelector: on a method you know is only available on iOS 7. E.g.

[view respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]

or

[UIView instancesRespondToSelector:@selector(snapshotViewAfterScreenUpdates:)]

There is not a standard way of doing this, and generally speaking testing is not something the iOS community talks too much about. The way I would approach this is by putting specific iOS7 tests on a test target on its own and then basically decide to run that suite accordingly

I tried playing around with OCUnit as @sergio suggested but I couldn't get far away. So far I'm annotating version-specific tests with a macro. It looks like this:

#define SKIP_IF_VERSION(v) if (floor(NSFoundationVersionNumber) <= v) return;

- (void)testSomethingThatOnlyWorksOniOS7
{ SKIP_IF_VERSION(NSFoundationVersionNumber_iOS_6_1)
// Test goes here
}

What I don't like about this approach is that the test runs anyway (and doesn't do anything). I would prefer the test to be skipped entirely.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top