Swift test дают ошибку "Undefined символы для архитектуры x86_64"
Я запускаю swift test
из командной строки для запуска тестовых случаев. Это тестовый пример:
import XCTest
@testable import vnk_swift
class KeyMappingTests: XCTestCase {
static var allTests : [(String, (KeyMappingTests) -> () throws -> Void)] {
return [
// ("testExample", testExample),
]
}
func testExample() {
let keyMapping = KeyMapping()
XCTAssertNotNil(keyMapping , "PASS")
}
}
А вот и выходное сообщение.
![image]()
Если я уберу использование KeyMapping
, все будет работать нормально:
func testExample() {
// let keyMapping = KeyMapping()
XCTAssertNotNil(true , "PASS")
}
![image]()
Похоже, есть проблема, когда я пытаюсь использовать класс. Как мне это исправить?
(Я не использовал Xcode для этого проекта, так как начал с swift package init
, исходный код этого проекта находится здесь: https://github.com/trungdq88/vnk-swift)
Ответы
Ответ 1
Мне удалось успешно собрать и протестировать ваш пакет, выполнив следующие изменения:
- переименовал имя пакета в
VnkSwift
, по некоторым причинам инструмент сборки не любит тире в имени пакета и не работает, когда у вас есть подчеркивание в имени сгенерированного пакета (поэтому переименуйте пакет в vnk_swift
чтобы убедиться, что оператор импорта и пакет совпадение имен не сработало) - переименовал тестовую папку в
VnkSwiftTests
чтобы компоновщик знал, с чем связываться; кажется, что это обязательное условие для компоновщика, чтобы знать, чтобы связать с пакетом - наконец, переименовал
main.swift
во что-то другое (я использовал utils.swift
). Дело в том, что наличие main.swift
инструктирует инструмент компоновки генерировать исполняемый файл, и связывание с исполняемым файлом работает не очень хорошо. После переименования пришлось комментировать код if
, так как глобально работающий код может принадлежать только main.swift
.
Заключить:
- Избегайте не алфавитно-цифровых имен пакетов
- Имя пакета и имя тестового каталога должны быть синхронизированы
- Убедитесь, что у вас нет файла
main.swift
чтобы убедиться, что пакет может быть связан с
Почему нельзя проверить целевую ссылку модульного тестирования на исполняемые файлы?
Это потому, что и тестовый пакет, и исполняемый пакет имеют глобальный исполняемый код (он же основная функция), поэтому компоновщик не знает, какой из них выбрать. При тестировании из Xcode тестовый пакет запускается в контексте приложения - он не связывается с ним, как в ситуации прямо здесь.
Xcode также имеет эту проблему при создании инструмента командной строки - вы не можете выполнить модульное тестирование этой цели, если вы хотите выполнить модульное тестирование кода, то вам нужно создать библиотеку, которая будет связана как инструментом, так и целью модульного тестирования ( или включите файлы в обе цели)
Ответ 2
Кажется, это вызвано тем, что у меня в каталоге модулей есть main.swift
. Это приводит к сборке исполняемого файла, а не библиотеки, с которой могут быть связаны ваши тесты.
Я решил эту проблему, разделив мой код на два модуля. Библиотека, для которой у меня есть тестовые случаи, и приложение, которое содержит только main.swift
:
Package.swift
Sources\FooBarLib\
Sources\FooBarLib\Something.swift
Sources\FooBarLib\MoreStuff.swift
Sources\FooBarApp\main.swift
Tests\FooBarLibTests\TestSomething.swift
Затем в моем Package.swift
убедитесь, что FooBarApp
зависит от FooBarLib
:
import PackageDescription
let package = Package(
name: "FooBar",
targets: [
.target(name: "FooBarLib"),
.target(name: "FooBarApp", dependencies: ["FooBarLib"])
],
)
Затем в TestSomething.swift
вы импортируете модуль FooBarLib
:
@testable import FooBarLib
import XCTest
class TestSomething: XCTestCase {
func testFunc() {
}
}
Ответ 3
Добавить в ответ @Frank.
В Swift 4 проверьте, зависит ли ваш .testTarget
от FooBarLib
.
.testTarget(
name: "FooBarLibTests",
dependencies: ["FooBarLib"]),
Ответ 4
Я вижу, что в каталогах у вас есть vnk-swift
, но в операторах импорта и в искаженном имени у вас есть vnk_swift
. Может быть, это ошибка Xcode/компилятора при обработке дефисов. Попробуйте воспроизвести в каталоге и проектировать без дефиса в имени, например vnkswift
.
Надеюсь, поможет
Ответ 5
Построение ответа @Cristik на самом деле сводится к тому, что находится в вашей папке Sources
. Для меня у меня была папка в Sources
, которая должна была быть точно такой же, как и в Tests
, за исключением того, что то, что находится в Tests
, должно быть суффиксным с Tests
. Итак, если у вас есть Sources
→ Foo-Bar
, вы должны иметь Tests
→ Foo-BarTests
. НЕТ ИСКЛЮЧЕНИЙ.
Еще одно примечание: все тире будут преобразованы в подчеркивания, поэтому в верхней части тестовых файлов вам нужно будет добавить @testable import Foo_Bar
.
Ответ 6
В моем случае я включаю тест, чтобы перейти к показу тестового навигатора в XCode, щелкнуть правой кнопкой мыши и включить тест. И это сработало.