Runs and debugs cross-platform tests for Skip projects, covering XCTest, Swift Testing, and multiple test runners for iOS and Android parity testing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/skip-testing-deployment:skip-testingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Skip supports parity testing — running the same tests on both iOS (Swift) and Android (Kotlin/JUnit) from a single test suite — through several different commands depending on the mode and how thorough you need to be.
Skip supports parity testing — running the same tests on both iOS (Swift) and Android (Kotlin/JUnit) from a single test suite — through several different commands depending on the mode and how thorough you need to be.
Skip Lite: Swift test files are transpiled to Kotlin/JUnit and run via Gradle. A test harness (XCSkipTests.swift) is auto-generated if not present and runs the Kotlin side via Robolectric by default.
Skip Fuse: Swift test files are compiled natively for Android via the Swift Android SDK and executed on device/emulator with skip android test. The auto-generated XCSkipTests harness does not apply to Fuse; use skip android test directly.
| Runner | Command | Where the Android side runs | Android APIs | Resource bundles | Speed |
|---|---|---|---|---|---|
| Lite Robolectric | swift test | JVM on the host via Gradle + XCSkipTests harness | Simulated by Robolectric | Yes | Fastest |
| Lite Instrumented | ANDROID_SERIAL=… swift test | Android emulator / device via Gradle | Full | Yes | Slowest |
| Fuse CLI | skip android test | Android emulator / device via adb shell | None — bare Linux exec, no JVM/JNI | Yes (sidecar .resources) | Fast |
| Fuse APK | skip android test --apk | Android emulator / device, packaged as an APK | Full (real app process with JNI) | No — Bundle.module doesn't work | Moderate |
Two important caveats:
--apk; use @Test / @Suite annotations from the Swift Testing module for tests you want to run in APK mode.Bundle.module.url(forResource:withExtension:), they will fail under --apk. Use CLI mode (which keeps a sidecar .resources directory next to the test binary) or restructure the tests to read fixtures from the file system / a network mock.import XCTest
final class MyTests: XCTestCase {
func testLogic() throws {
XCTAssertEqual(1 + 1, 2)
XCTAssertTrue(someCondition)
XCTAssertNotNil(optionalValue)
}
func testAsync() async throws {
let result = try await fetchData()
XCTAssertFalse(result.isEmpty)
}
}
import Testing
@Suite struct MathTests {
@Test func addition() { #expect(1 + 1 == 2) }
@Test func inequality() { #expect(3 != 5) }
@Test func comparisons() {
#expect(10 > 5)
#expect(3 < 8)
#expect(5 >= 5)
}
@Test func unwrap() throws {
let v: Int? = 42
let _ = try #require(v)
}
}
// Freestanding @Test functions are also supported
@Test func standalone() { #expect(true) }
Supported: @Test, @Suite, #expect (==, !=, >, <, >=, <=, bool), #require.
Not supported: Parameterised tests, traits, tags.
swift test # Lite: Swift host + transpiled JUnit (Robolectric)
swift test --filter MyModuleTests.MyTests # one Swift test class
swift test --filter MyModuleTests/testLogic # one Swift test method
swift test --filter XCSkipTests # only the Kotlin-transpiled side
ANDROID_SERIAL=emulator-5554 swift test # Lite, instrumented on emulator
skip android test # Fuse, CLI mode
skip android test --apk # Fuse, APK mode
skip android test --android-serial emulator-5554 # scope Fuse test to one device
skip android test --testing-library swift-testing # only @Test / @Suite
skip android test --event-stream-output-path tests.jsonl # JSON event stream
skip test parity-report commandskip test is a higher-level command that builds and runs both the Swift and the transpiled Kotlin tests, then produces a side-by-side parity report so you can see which tests pass on which platform at a glance.
skip test # parity report for the current project
skip test --android-serial emulator-5554 # parity report with instrumented Android side
skip test --xunit results.xml # write XUnit output for CI
skip test --junit junit-reports/ # write a JUnit report directory
skip test -c release # release-configuration parity
The output is a two-column table with the test name on the left and pass/fail per platform on the right. Use this when you suspect a transpilation regression: a test that passes on Swift but fails on Kotlin (or vice versa) is exactly the parity failure mode skip test is designed to surface.
swift test is fine for everyday iteration. skip test is the right pre-commit / CI gate when you want to be sure both sides agree.
Note: #if os(Android) is false under Robolectric. Use #if os(Android) || ROBOLECTRIC if you need code to run in both real Android and Robolectric.
func testIOSOnly() throws {
#if SKIP
throw XCTSkip("Not supported on Android")
#endif
// iOS-only test
}
Create XCSkipTests.swift to override the auto-generated harness:
#if os(macOS)
import SkipTest
@available(macOS 13, *)
final class XCSkipTests: XCTestCase, XCGradleHarness {
public func testSkipModule() async throws {
try await runGradleTests()
}
}
#endif
This can cause different failure counts per platform.
Kotlin compilation errors appear in testSkipModule() output with .kt file paths and line numbers. Cross-reference with Swift source.
When a Kotlin compile error references a transpilation pattern (integer overflow, Double-vs-Int comparison, Array.remove(atOffsets:) outside SwiftUI, Foundation.sqrt qualification, etc.), the underlying rule is in skip-lite-transpilation — fix the Swift source per that skill and re-run swift test --filter XCSkipTests to confirm.
swift test / skip test cover business logic and parity tests. They do not drive the running app — they don't tap buttons, type into URL bars, or take screenshots of the rendered UI. For that, use the inner loop in the skip-ui-automation skill:
skip app launch to install and run the app on the iOS Simulator and Android emulator together..maestro/ to script gestures and assertions against the live UI..accessibilityIdentifier(...) on every interactive view so flows survive translation and refactor.Logic tests catch transpilation bugs and regressions; Maestro flows catch rendering, navigation, and layout regressions. Run both.
Creates, edits, and verifies skills using a test-driven development approach with pressure scenarios and subagents.
npx claudepluginhub skiptools/skills --plugin skip-testing-deployment