Now you can test Xcode apps and Swift packages in Zed
2025-10-17
This is a followup to Build, run and debug iOS and Mac apps in Zed instead of Xcode, so you'll want to start there unless you're only working on Swift packages.
Here's how to:
- Have runnable icons in your testing code, just like in Xcode
- Run tests in plain Swift packages
- Run tests in your iOS and Mac apps, targetting the platform and device of your choice
- Do this with both Swift Testing and XCTest
Used in the real world
This isn't just an article about what you could do in theory – I built my new app, DelayDrop, mainly in Zed. It's a pleasure to work in a genuinely good code editor, and switching into Xcode for things like previews really isn't an imposition.
DelayDrop is an iOS and Mac app for sending anything to your other Apple devices – even if they're locked, off or elsewhere – in two taps. It beats AirDrop because your other device can be anywhere in the world; and even if it is nearby, you're still winning because you don't have to get up and unlock it.
And if that sounds like a plug for DelayDrop, that's because it is!
Check you have runnable tests
Open up a project in Zed and navigate to a test file. You should see runnable triangles in the gutter next to your tests. (My changes to support test runnables are quite recent, so if you don't see them, check the Swift plugin version: it should be at least v0.4.4.)
These will work for Swift packages (but not Xcode projects yet), so if you have a package with tests, try it out.
Tip: If you're using Swift Testing, annotate your test structs/classes with @Suite, otherwise Zed won't see them as runnable.
If you're only interested in Swift packages, that's it – you can stop reading. The rest of the article is about Xcode projects.
Update xcede
If you've been using xcede for a while, make sure you've got the latest version.
If you're upgrading, note there are some breaking changes. build.sh will tell you about those when you run it.
Define tasks
The following assumes you're set up to build and run your app in Zed as described in the first article, including having a .xcrc file specifying your scheme etc.
Run zed: Open tasks and add the following:
,
,
How this works: The runnables you see in Zed are created by the Swift plugin. Each one has an associated tag, and also sets variables ($ZED_CUSTOM_*) for things we need to know – test class and test function. The plugin also defined tasks to execute these runnables using
swift test; here, we're replacing the plugin's tasks with versions that use xcede instead.
Note that you haven't lost the ability to run Swift package tests – if you've opened a package rather than an Xcode project, xcede will see that and run the appropriate swift test command.
A little more setup
- First, make sure your tests run in Xcode.
- In
.xcrc, addtesttarget, setting it to the name of the target (not scheme) containing your tests. - If you run your tests using their own scheme rather than your main app scheme, also set
testscheme(otherwise xcede will just use whatever you have forscheme).
That's it – now try out one of those triangles.
As ever, the output can be ugly, and xcbeautify or similar will make it nicer. See the previous article for details.
Run all tests
Running xcede test without any arguments will run all the tests in your target. It's easy enough to create a task for that.
What about packages within Xcode projects?
If you've moved your app's code into packages (I do this), in Xcode you'd include the packages' tests in
a scheme or schemes. Whether it's your main app scheme or a different one is up to you. Just make sure you've set
testtarget to the package's test target, and set testscheme if you need to.
If you want to run your package tests using swift not xcodebuild, just open the package directory as its own Zed project.
The end
If you have any feedback, join the discussion on Zed's github, or add an issue to the xcede repo.
@lxmn@mastodon.social.