scrrr
scrrr

Reputation: 5340

iOS Testing: Is there a way to skip tests?

I don't want to execute certain tests if the feature is currently disabled. Is there a way to "skip" a test (and to get appropriate feedback on console)?

Something like this:

func testSomething() {
  if !isEnabled(feature: Feature) {
    skip("Test skipped, feature \(feature.name) is currently disabled.")
  }

  // actual test code with assertions here, but not run if skip above called.
}

Upvotes: 45

Views: 31196

Answers (12)

Deep Singh Baweja
Deep Singh Baweja

Reputation: 418

Official iOS documentation https://developer.apple.com/documentation/xctest/methods_for_skipping_tests

Use XCTSkipIf() or XCTSkipUnless() when you have a Boolean condition that you can use to evaluate when to skip tests.

Throw an XCTSkip error when you have other circumstances that result in skipped tests. For example:

func testSomethingNew() throws {
    guard #available(macOS <#VersionNumber#>, *) else {
        throw XCTSkip("Required API is not available for this test.")
    }
    // perform test using <#VersionNumber#> APIs...
}

Upvotes: 3

Mussa Charles
Mussa Charles

Reputation: 4452

While there are answers which covered almost similar logic, if you don't want to have an extra file to manage conditions then you can mark your test function with throws then use XCTSkip with a nice description to explain why it is skipped. Note a clear message is important as it will make it easy for you to just read it on Report Navigator and understand why it is skipped without having to open a related XCTestCase.

Example:

 func test_whenInilizedWithAllPropertiesGraphQLQueryVariableDict_areSetCorrectly() throws {
        // Skip intentionally so that we can remember to handle this.
        throw XCTSkip("This method should be implemented to test equality of NSMutableDictoinary with heterogenious items.")
    }

Upvotes: 0

Ilias Karim
Ilias Karim

Reputation: 5407

Beginning with Xcode 11.4 you'll be able to using XCTSkipUnless(_:_:file:line:).

The release notes read,

XCTest now supports dynamically skipping tests based on runtime conditions, such as only executing some tests when running on certain device types or when a remote server is accessible. When a test is skipped, Xcode displays it differently in the Test Navigator and Test Report, and highlights the line of code where the skip occurred along with an optional user description. Information about skipped tests is also included in the .xcresult for programmatic access.

To skip a test, call one of the new XCTSkip* functions from within a test method or setUp(). For example:

func test_canAuthenticate() throws {
    try XCTSkipIf(AuthManager.canAccessServer == false, "Can't access server")

    // Perform test… 
}

The XCTSkipUnless(::file:line:) API is similar to XCTSkipIf(::file:line:) but skips if the provided expression is false instead of true, and the XCTSkip API can be used to skip unconditionally. (13696693)

Upvotes: 18

Ben
Ben

Reputation: 1434

If you use Xcode 11 and TestPlan, you can tweak your configuration to skip or allow specific tests. Xcode TestPlan is a JSON format after all.

By default, all tests are enabled, you can skip a list of tests or test file.

"testTargets" : [
    {
        "skippedTests" : [
            "SkippedFileTests", // skip the whole file
            "FileTests\/testSkipped()" // skip one test in a file
        ]
    ...

On the opposite, you can also skip all tests by default and enable only few.

"testTargets" : [
    {
        "selectedTests" : [
            "AllowedFileTests", // enable the whole file
            "FileTests\/testAllowed()" // enable only a test in a file
        ]
    ...

I'm not sure if you can combine both configurations though. It flips the logic based on Automatically includes new tests.

Upvotes: 2

Abhijith
Abhijith

Reputation: 3404

From Xcode 11.4+, you can use XCTSkipIf() or XCTSkipUnless().

try XCTSkipIf(skip condition, "message")


try XCTSkipUnless(non-skip condition, "message")

https://developer.apple.com/documentation/xctest/methods_for_skipping_tests#overview

Upvotes: 5

Grigory Entin
Grigory Entin

Reputation: 1857

It's not that universal, but you can override invokeTest in XCTestCase and avoid calling super where necessary. I'm not sure about the appropriate feedback in console though.

For instance the following fragment makes the test run only on iOS Simulator with iPhone 7 Plus/iPad Pro 9.7"/iOS 11.4:

class XXXTests : XCTestCase {

    let supportedModelsAndRuntimeVersions: [(String, String)] = [
        ("iPhone9,2", "11.4"),
        ("iPad6,4", "11.4")
    ]

    override func invokeTest() {
        let environment = ProcessInfo().environment
        guard let model = environment["SIMULATOR_MODEL_IDENTIFIER"], let version = environment["SIMULATOR_RUNTIME_VERSION"] else {
            return
        }
        guard supportedModelsAndRuntimeVersions.contains(where: { $0 == (model, version) }) else {
            return
        }
        super.invokeTest()
    }

Upvotes: 4

Citronex
Citronex

Reputation: 1139

This is what test schemes are meant to do. You can have different schemes targeting different testing situations or needs. For example, you may want to create a scheme that runs all your tests (full regression scheme), or you may want to select a handful of them to do a quick smoke test on your app when small changes are made. This way, you can select different schemes according to how much testing you need to do. Just go to

Product >> Scheme

Upvotes: 2

Alexander Doloz
Alexander Doloz

Reputation: 4198

Another possible solution which I found in some article: prefix your skipped tests with something like "skipped_"

Benefits:

  • XCode will not treat them as tests
  • You can easily find them using search
  • You can make them tests again, replacing "skipped_" to ""

Upvotes: 34

Sandy Chapman
Sandy Chapman

Reputation: 11341

You can disable XCTests run by Xcode by right clicking on the test symbol in the editor tray on the left.

enter image description here

You'll get this menu, and you can select the "Disable " option.

enter image description here

Right clicking again will allow you to re-enable. Also, as stated in user @sethf's answer, you'll see entries for currently disabled tests in your .xcscheme file.

As a final note, I'd recommend against disabling a test and committing the disabling code in your xcscheme. Tests are meant to fail, not be silenced because they're inconvenient.

Upvotes: 65

sethf
sethf

Reputation: 81

I've found a way to do this by modifying my ui test .xcscheme file and adding a section called SkippedTests under TestableReference, then adding individual Test tags with an 'Identifier' attribute with the name of your class and test method. Something like:

<SkippedTests>
       <Test Identifier="ClassName/testMethodName" />
</SkippedTests>

Hope this helps

Upvotes: 8

Vicky
Vicky

Reputation: 620

There is no test case skipping. You can use if-else block:nested and run/print your desired output.

Upvotes: -2

Sulthan
Sulthan

Reputation: 130200

Unfortunately, there is no build-in test case skipping. The test case either passes or fails.

That means you will have to add that functionality by yourself - you can add a function to XCTestCase (e.g. XCTestCase.skip) via a category that will print the information into console. However, you will have to put a return after that to prevent the other asserts from running.

Upvotes: 1

Related Questions