Pull to refresh

Swift Power Assert

Reading time4 min
Views744
Original author: Kishikawa Katsumi

Power asserts (также известные как диаграммированные утверждения) дополняют ваши ошибки утверждений информацией о значениях, полученных во время оценки условия, и представляют ее в легко усваиваемой форме. Power asserts являются популярной функцией Spock (а позже и всего языка Groovy независимо от Spock), ScalaTest и Expecty.

Power asserts предоставляют описательные сообщения об утверждениях для ваших тестов, подобные следующим примерам:

#expect(max(a, b) == c)
        |   |  |  |  |
        7   4  7  |  12
                  false

#expect(xs.contains(4))
        |  |        |
        |  false    4
        [1, 2, 3]

#expect("hello".hasPrefix("h") && "goodbye".hasSuffix("y"))
        |       |         |    |  |         |         |
        "hello" true      "h"  |  "goodbye" false     "y"
                              false

Почему Power Assert?

При написании тестов нам нужно использовать различные функции утверждений. С помощью Power Assert вы используете только функцию #expect(). Нет необходимости запоминать множество Assertion API. Просто создайте выражение, которое возвращает булево значение, и Power Assert автоматически отобразит исчерпывающую информацию об ошибке.

Начало работы

Swift Power Assert реализован с помощью макросов, экспериментальной функции Swift. Поэтому вы должны использовать предварительную версию набора инструментов Swift, чтобы использовать эту библиотеку.

  1. Скачайте и установите набор инструментов из снапшота разработки на swift.org после 6 апреля 2023 года.

  2. Установите идентификатор набора инструментов в переменную окружения TOOLCHAINS, чтобы использовать его предварительную версию. Например:

export TOOLCHAINS=org.swift.59202303301a

Примечание: Чтобы узнать идентификатор набора инструментов, проверьте файл Info.plist в наборе инструментов. Наборы инструментов обычно устанавливаются в `/Library/Developer/Toolchains/'. Щелкните правой кнопкой мыши на значке набора инструментов и выберите "Показать содержимое пакета", чтобы найти файл Info.plist. Значение ключа Bundle Identifier в файле Info.plist является идентификатором набора инструментов. Дополнительную информацию можно найти в отличной статье Саруна: https://sarunw.com/posts/how-to-use-pre-release-swift-version-with-command-line-tools/

Проверка работы

Чтобы увидеть PowerAssert в действии, перейдите в каталог Examples и запустите swift test.

$ cd Example
$ swift test

Видите следующие результаты?

...
Test Suite 'All tests' started at 2023-04-05 07:17:58.800
Test Suite 'swift-power-assert-examplePackageTests.xctest' started at 2023-04-05 07:17:58.801
Test Suite 'PowerAssertTests' started at 2023-04-05 07:17:58.801
Test Case '-[ExampleTests.PowerAssertTests testExample]' started.
/swift-power-assert/Example/"ExampleTests/ExampleTests.swift":8: error: -[ExampleTests.PowerAssertTests testExample] : failed -
#expect(a * b == 91)
        |   | |  |
        10  9 |  91
              false
/swift-power-assert/Example/"ExampleTests/ExampleTests.swift":11: error: -[ExampleTests.PowerAssertTests testExample] : failed -
#expect(xs.contains(4))
        |  |        |
        |  false    4
        [1, 2, 3]
…

Меняйте код в Example/Tests/ExampleTests.swift, чтобы попробовать различные паттерны, которые вам нравятся.

Применение

Чтобы применить Swift Power Assert в вашей библиотеке или приложении, сначала добавьте SwiftPowerAssert в менеджер пакетов Swift.

// swift-tools-version:5.8
import PackageDescription

let package = Package(
  name: "MyLibrary",
  dependencies: [
    ...,
    .package(
        url: "https://github.com/kishikawakatsumi/swift-power-assert.git",
        branch: "main"
    ),
  ],
  targets: [
    ...,
    .testTarget(
      name: "MyLibraryTests",
      dependencies: [
        ...,
        .product(name: "PowerAssert", package: "swift-power-assert"),
      ]
    ),
  ]
)

Далее вы можете использовать Power Assert в ваших тестах с помощью макроса #expect().

// MyLibraryTests.swift
import XCTest
import PowerAssert
@testable import MyLibrary

final class MyLibraryTests: XCTestCase {
  func testExample() {
    let a = 7
    let b = 4
    let c = 12

    #expect(max(a, b) == c)
  }
}

Запрос о помощи в тестировании

Swift Power Assert находится на ранних стадиях разработки. Если вы можете помочь нам с тестированием, мы будем очень признательны! Пожалуйста, попробуйте различные паттерны кода с использованием этой библиотеки и пишите о любых проблемах, с которыми вы столкнулись. Мы приветствуем ваши отзывы и предложения по улучшению. Большое спасибо!

Часто задаваемые вопросы

В: Я хочу отображать результат даже в случае успешного прохождения теста (т.е. если выражение в функции #expect() вычисляется в true).

О: По умолчанию функция #expect() не отображает результат, если выражение вычисляется в true, потому что тест был успешным. Чтобы всегда выводить результат, установите аргумент verbose в значение true.

Например:

#expect(x == y, verbose: true)

В: Я хочу знать, как компилятор на самом деле раскрыл макрос.

О: Вы можете использовать опцию -dump-macro-expansions для вывода раскрытия макроса.

Например:

$ cd Example

$ swift test -Xswiftc -Xfrontend -Xswiftc -dump-macro-expansions

Если вы запустите вышеуказанное с опцией -dump-macro-expansions, вы получите следующий вывод.

...
@__swiftmacro_12ExampleTests011PowerAssertB0C04testA0yyF6expectfMf_.swift as ()
------------------------------

        PowerAssert.Assertion("#expect(a * b == 91)", message: "", file: #""ExampleTests/ExampleTests.swift""#, line: 8, verbose: false) {
  $0.capture($0.capture($0.capture(a .self, column: 8) * $0.capture(b .self, column: 12), column: 10) == $0.capture(91, column: 17), column: 14)
}
.render()
------------------------------
...

Tags:
Hubs:
Total votes 1: ↑0 and ↓1-1
Comments0

Articles