问题
If I have some library with methods like:
public struct Foo {
@available(macOS 10.15, *)
func greatNewFeature() -> String {
return "new feature"
}
func legacyFeature() -> String {
return "legacy feature"
}
}
Then some code that uses it:
func methodToTest() -> String {
let foo = Foo()
guard #available(macOS 10.15, *) else {
return foo.legacyFeature()
}
return foo.greatNewFeature()
}
Is there a way I can write unit tests which give me complete coverage of methodToTest?
All ideas I have had so far, have not been helpful:
- you can't treat the availability check as injected functionality - the compiler specifically needs the
@availablekeyword in order to use thegreatNewFeaturemethod. - you can't add some hacky boolean which you could set in the tests like
#available(macOS 10.15, *) || isMacOS10_15for a similar reason to the previous point.
The only thing I think would work is to run the test suite multiple times - once for each supported OS version, then create a script to combine the code coverage stats. Can anyone think of a better approach?
回答1:
You can create a flag in your tests whether to skip the OS version check or not and && that with your #available check.
This way you simply need to call testFooFeature with the flag both turned on and off and you'll be able to test both code paths on macOS 10.15.
var forceOldOSVersion = true
func testFooFeature() -> String {
let foo = Foo()
if !forceOldOSVersion, #available(macOS 10.15, *) {
return foo.greatNewFeature()
} else {
return foo.legacyFeature()
}
}
testFooFeature() // "legacy feature"
来源:https://stackoverflow.com/questions/61084603/testing-codepaths-for-older-os-versions