Excuse me in advance if Xcode questions are off topic because they're not strictly related to the open source parts of the Swift ecosystem.
My goal
I have a macOS application with a performance problem. I want to be a good boy, and be data-driven in my attempt to remedy that, by using performance tests to benchmark my progress.
In order for the benchmark to be worth anything, both the calling code (the unit test bundle) and the target (the Mac app) should be compiled in release mode, with optimizations on, right?
Well running regular unit tests in debug mode is quite handy (symbols for debugging, faster compiles, etc.). So it looks like I should make a new unit test bundle just for performance tests, is that right (question 1)?
Enabling optimizations
Assuming my premise in question 1 is correct, I added a new unit test bundle target to my project. I employed Ben Rimmington's trick to use an assertion to ensure optimizations are on:
override func setUp() throws {
assert(false, "The performance tests aren't being run with optimizations on!")
}
I ran the XCTestCase with the diamond button in the left gutter, and sure enough, the assertion traps. I went into the Build Settings for the target, and set Swift Compiler - Code Generation
> Optimization Level
> Debug>
to Optimize for Speed [-O]
. Reran the tests, and that assertion no longer traps (it's being optimized out, woohoo!)
Now I added the same assertion to my app's module, in a public global method called verifyCompilerOptimizationsAreOn
. I ran this from my performance testcase, and it traps.
Question 2: How do I tell Xcode that the FooAppPerformanceTests
module should depend on a release build of FooApp
?
App launches during unit tests
Also, I've noticed that running unit tests causes the target mac app to launch and exit briefly.
- Why is that? I would have expected that only UI tests would need to run the app for real, and that unit tests would just run the relevant code directly, in isolation from a running app.
- I can disable that behavior by setting
Host Application
toNone
in the general section of the target's settings, but then I get linker errors telling my that the symbols under test are no longer found.
Question 3: Is there a way to turn that behavior off, while still being able to run the test targets? The flash of the app is pretty annoying, though admittedly it's a nuisance I can live with it if I must.