Reputation: 5340
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
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
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
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
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
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
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
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
Reputation: 4198
Another possible solution which I found in some article: prefix your skipped tests with something like "skipped_"
Benefits:
Upvotes: 34
Reputation: 11341
You can disable XCTests run by Xcode by right clicking on the test symbol in the editor tray on the left.
You'll get this menu, and you can select the "Disable " option.
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
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
Reputation: 620
There is no test case skipping. You can use if-else block:nested and run/print your desired output.
Upvotes: -2
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