Let AI write your iOS UI tests
Stop writing boilerplate UI tests. AITestScout explores your iOS app autonomously and generates production-ready XCUITests automatically.
// One line to explore your app with AI
let result = try Scout.explore(app)
// Tests are automatically generated when failures are detected
print("Discovered \(result.screensDiscovered) screens")Step 1: Add this one test file:
import XCTest
import AITestScout
@available(iOS 26.0, *)
final class AIExplorationTests: XCTestCase {
func testExploreApp() throws {
let app = XCUIApplication()
app.launch()
// AI explores your app autonomously
let result = try Scout.explore(app)
// Tests are auto-generated if failures occur
if let testFile = result.generatedTestFile {
print("📁 Generated test: \(testFile.path)")
}
}
}Step 2: Run once:
xcodebuild test -scheme YourApp -only-testing:AIExplorationTestsStep 3: Get production-ready tests (auto-generated when failures are detected):
// Auto-generated by AITestScout
final class LoginFlowTests: XCTestCase {
func testSuccessfulLogin() throws {
let app = XCUIApplication()
app.launch()
let emailField = app.textFields["emailField"]
XCTAssertTrue(emailField.waitForExistence(timeout: 5))
emailField.tap()
emailField.typeText("[email protected]")
let passwordField = app.secureTextFields["passwordField"]
passwordField.tap()
passwordField.typeText("password123")
app.buttons["loginButton"].tap()
XCTAssertTrue(app.staticTexts["Dashboard"].waitForExistence(timeout: 10))
}
}That's it. Real tests. Zero manual work.
Add to your Package.swift:
dependencies: [
.package(url: "https://github.com/Xamrock/AITestScout", from: "0.6.0")
]Or in Xcode: File → Add Package Dependencies
Requirements:
- iOS 26+ (for AI exploration with Apple Intelligence)
If you prefer not to add the package directly, use the Xamrock CLI to generate the test file:
brew install xamrock/tap/xamrock
xamrock explore --app com.yourcompany.YourApp
cp scout-results/ScoutCLIExploration.swift YourAppUITests/Then run the test in Xcode (⌘U) and view results in scout-results/.
Exploration with Goal:
let result = try Scout.explore(
app,
steps: 30,
goal: "Test the checkout flow"
)
// Validate results
try result.assertDiscovered(minScreens: 3)
try result.assertTransitions(min: 5)Full Configuration:
let config = ExplorationConfig(
steps: 25,
goal: "Comprehensive app exploration",
outputDirectory: URL(fileURLWithPath: "./GeneratedTests"),
generateTests: true,
failOnCriticalIssues: false,
verboseOutput: true
)
let result = try Scout.explore(app, config: config)
print(result.summary)Access Exploration Results:
// Run exploration
let result = try Scout.explore(app, steps: 20)
// Access detailed metrics
print("Screens: \(result.screensDiscovered)")
print("Transitions: \(result.transitions)")
print("Duration: \(result.duration)s")
print("Success Rate: \(result.successRatePercent)%")
print("Total Actions: \(result.totalActions)")
// Check for generated test files
if let testFile = result.generatedTestFile {
print("Test file: \(testFile.path)")
}
if let reportFile = result.generatedReportFile {
print("Report: \(reportFile.path)")
}
// Access from static property
if let lastResult = Scout.lastResult {
print("Last exploration: \(lastResult.screensDiscovered) screens")
}Assertion Helpers:
let result = try Scout.explore(app, steps: 15)
// Built-in assertions for test validation
try result.assertDiscovered(minScreens: 3)
try result.assertTransitions(min: 5)
try result.assertSuccessRate(minPercent: 80)
try result.assertNoCriticalIssues()Integrate with Third-Party Frameworks:
Use delegates to run custom actions during exploration (accessibility scanning, analytics, performance monitoring, etc.):
// Example: Accessibility scanning delegate
class AccessibilityScoutDelegate: AICrawlerDelegate {
let scanner = AxeAccessibilityScanner()
func didDiscoverNewScreen(_ fingerprint: String, hierarchy: CompressedHierarchy) {
// Run accessibility scan on every new screen
let issues = scanner.scan(hierarchy)
if !issues.isEmpty {
print("⚠️ Found \(issues.count) accessibility issues")
}
}
}
// Example: Analytics & performance tracking delegate
class AnalyticsScoutDelegate: AICrawlerDelegate {
func didMakeDecision(_ decision: ExplorationDecision, hierarchy: CompressedHierarchy) {
Analytics.logAIDecision(decision)
}
func didRecordTransition(from: String, to: String, action: Action, duration: TimeInterval) {
if duration > 2.0 {
PerformanceMonitor.reportSlowTransition(duration: duration)
}
}
}
// Use delegates during exploration
let accessibilityDelegate = AccessibilityScoutDelegate()
let result = try Scout.explore(app, steps: 20, delegate: accessibilityDelegate)This allows AITestScout to integrate seamlessly with your existing test infrastructure without modification.
- Issues: GitHub Issues for bugs and features
- Discussions: Xamrock Community Discord
AITestScout is developed and maintained by Xamrock, a developer tools company focused on mobile testing automation.
- Xamrock Cloud: CI/CD testing infrastructure for mobile teams
- Xamrock Analytics: Advanced test metrics and insights
- Enterprise Support: Priority support and custom integrations
MIT