XCUITest

Добавьте зависимость TraceraXCUITest из tracera-swift в UI test target в Package.swift (транзитивно подтянется Tracera):

dependencies: [
  .package(url: "https://github.com/tracera-dev/tracera-swift", from: "0.1.0"),
],
targets: [
  .testTarget(
    name: "MyAppUITests",
    dependencies: [
      .product(name: "TraceraXCUITest", package: "tracera-swift"),
    ]
  ),
]

Требуется Swift ≥ 6, macOS ≥ 15 (или iOS ≥ 18) и Xcode ≥ 16 (см. Адаптеры автотестов).

Переменные окружения и режим прогона: Адаптеры автотестов.

Наследуйте TraceraXCTestCase и один раз вызовите install() в class func setUp() (медиа по умолчанию выкл. — см. Скриншоты):

import XCTest
import Tracera
import TraceraXCUITest

final class CheckoutUITests: TraceraXCTestCase {
  override class func setUp() {
    install()
  }
  // …
}

Если переопределяете instance setUp / tearDown (на каждый тест — не class func setUp), вызовите super.setUp() в конце setUp и super.tearDown() в начале tearDown, чтобы шаги попали в Предусловие / Тест / Постусловие.

Привязка testCaseId и autotestName

Привяжите через Tracera.testCase в начале каждого тестового метода:

func testCheckout() {
  Tracera.testCase(42)
  // Tracera.testCase(42, "e2e/checkout")
  // …
}

Если name не указан, то autotestName принимает значение имени теста в XCTest. Можно привязать в instance setUp, если несколько методов делят один case id.

Пропуск

Используйте skip("reason"), чтобы причина попала в результат как comment:

func testCheckout() throws {
  Tracera.testCase(42)
  try skip("needs a seeded account")
}

Шаги

Используйте Tracera.step("…") { } или await Tracera.step("…") { }. Шаги внутри instance setUp / tearDown попадают в Предусловие / Постусловие результата; шаги внутри теста попадают в Тест.

override func setUp() {
  Tracera.step("launch app") { }
  super.setUp()
}

func testCheckout() throws {
  Tracera.testCase(10)
  try Tracera.step("tap checkout") {
    try Tracera.step("nested leaf") { }
  }
}

override func tearDown() {
  super.tearDown()
  Tracera.step("terminate app") { }
}

Комментарии, ошибки и вложения

Лимиты и допустимые MIME-типы: Адаптеры автотестов.

Tracera.comment, Tracera.error и вложения добавляются к открытому шагу или к результату, если шаг не открыт. Tracera.attachmentFile принимает путь к файлу; Tracera.attachmentBytes — имя и байты (MIME-тип необязателен). Вложения загружаются при отправке результата.

Tracera.comment("result-level note")
Tracera.error("result-level error")
Tracera.attachmentFile("Fixtures/screenshot.png")
Tracera.step("open login") {
  Tracera.comment("step note")
  Tracera.attachmentBytes("body.json", data: Data(#"{"ok":true}"#.utf8), mimeType: "application/json")
}

Если вы создаёте Task и вызываете в нём API Tracera (шаги, комментарии, ошибки, вложения), сначала вызовите getContext() в тесте и запустите воркер через runWithContext — иначе эти вызовы в отчёт не попадут:

let ctx = getContext()
Task {
  await runWithContext(ctx) {
    Tracera.step("worker") { /* ... */ }
  }
}

Параметризация

Используйте литеральный Tracera.testCase(id, name) (или опустите name → имя теста XCTest).

Скриншоты и медиа

install() нужен для отчётности (см. выше). Через его параметры можно приложить медиа в конце каждого теста (по умолчанию .off): screenshots: — .onFailure / .onSuccess / .always (iOS/tvOS: XCUIScreen; macOS: ScreenCaptureKit при разрешении записи экрана); hierarchy: → window-hierarchy.txt; logs: → device-log.txt (unified log / OSLogStore).

override class func setUp() {
  install(screenshots: .onFailure, hierarchy: .onFailure, logs: .onFailure)
}

Чтобы приложить скриншот, иерархию или лог в нужный момент (например после тапа), вызовите вручную:

Tracera.step("after login") {
  screenshot()
  attachHierarchy()
  attachDeviceLog()
}