iOS - Файл 'MyProject-Swift.h' не знайдено під час запуску модульних тестів для Swift


94

Я намагаюся налаштувати Unit Testing для свого проекту. Це нещодавно додаток Objective-C, до якого я нещодавно додав один клас Swift. У мене встановлено файли «MyProject-Swift.h» та Swift Bridging (як «MyProject», так і «MyProjectTest»), і я можу створити та запустити додаток на відмінно, використовуючи і Objective-C, і Swift-код.

Однак зараз я хочу запустити кілька тестів Unit для нового класу Swift. Я налаштував свій тестовий файл, і він виглядає так:

MySwiftClassTests.swift:

import UIKit
import XCTest
import MyProject

class MySwiftClassTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        XCTAssert(true, "Pass")
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measureBlock() {
            // Put the code you want to measure the time of here.
        }
    }

}

Я отримую цю помилку під час запуску програми як тест:

'MyProject-Swift.h' file not found

Я не впевнений, чому це відбувається лише при спробі запуску тестів. Будь-які пропозиції?


1
Додати оновлення щодо цього? Я стикаюся з тією ж проблемою ...
hyouuu

1
@Coveloper - Як ви можете встановити цілі для файлу -Swift.h? Це не справжній файл, який сидить у проекті, а натомість компілюється Xcode при складанні.
JimmyJammed

1
Ось оновлення до мого "Я також отримую файл" MyProject-Swift.h "не знайдено помилки .." коментар вище: Я знайшов вирішення, встановивши назву модуля продукту цілі MyProjectTests в MyProject на відміну від MyProjectTests. Отже, тепер обидві цілі (MyProject і MyProjectTests) мають однакову назву модуля продукту. Це дивно, але це працює і має низький ризик, оскільки це мета тесту. Слід зазначити, що назва мого проекту насправді схожа на My-Project, отже My_Project є фактичною назвою модуля.)
finneycanhelp

6
Файл "MyProject-Swift.h" генерується за адресою "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources". У кінцевому підсумку додаю це до Шляхів пошуку заголовків для моєї цільової одиниці тестування.
gagarwal

1
@gagarwal Додавання "$ (TARGET_TEMP_DIR) /../$ (PROJECT_NAME) .build / DerivedSources" до шляхів пошуку заголовка для моєї цілі Unit Test працювало. :) Зробіть ТОКУ відповідь із цього коментаря, і я можу нагородити вас нагородою плюс пояснити іншим, яка це чудова відповідь.
finneycanhelp

Відповіді:


148

Файл "MyProject-Swift.h" генерується за таким шляхом:

"$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources"

У підсумку я додаю це до шляхів пошуку заголовків для моєї цілі Unit Test.

Також, як @hyouuu зазначав про те, що відома проблема, сподіваємось, Apple запропонує хороше рішення в їх кінці. Поки я не вважаю, що нам потрібно використовувати це вище рішення.

https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html


Працював як шарм!
DonnaLea

Дивовижно! Не знаю, чому Apple не згадує це як спосіб вирішення. Також вражений тим, що людей, які мають цю проблему, не більше. Будь-хто з існуючим проектом Obj-C, який поступово перетворює речі на Swift, вирішить цю проблему.
mluisbrown

@fabb не відповідає дійсності - TARGET_NAME взагалі щось подібне <Product Name> Testsдо вашої цілі тестування. Однак це рішення не працює, якщо в назві вашого продукту є пробіли. Дивіться мою відповідь нижче для рішення.
Крістофер Пікслі

2
Лише зауваження, мені довелося додати Шлях пошуку і конкретно встановити його як "рекурсивний". Це може бути очевидним, але це не спрацювало кілька разів, поки я цього не зробив; Я припускаю, що це переходить у підпапки.
Миро

1
Для мого проекту $(TARGET_TEMP_DIR)не вдалося. Я завершив використання$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Джордан Бондо

32

Дякую @gagarwal за те, що це з’ясував. У нашому випадку в назві товару є пробіл, який згорнуто $PROJECT_NAME, тому мені довелося його жорстко кодувати. Крім того, використовуючи $CONFIGURATION_TEMP_DIRзамість $TARGET_TEMP_DIR, ви можете видалити батьківський каталог ( ../) з шляху. Таким чином, рішення полягає в тому, щоб додати до тестових цілей заголовка наступне:

"$(CONFIGURATION_TEMP_DIR)/Product Name With Spaces.build/DerivedSources"

Або якщо ваш продукт не містить пробілів:

"$(CONFIGURATION_TEMP_DIR)/$(PROJECT_NAME).build/DerivedSources"

Також вирішує проблему модульного тестування класів кодегенів Core Data.
Elise van Looij

14

Побачив у примітці до випуску Xcode 6.1, що це відома проблема ... знак ... Знайдіть "-swift.h" у примітці до випуску https://developer.apple.com/library/content/documentation/Xcode /Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html

Тести, написані в Objective-C, не можуть імпортувати заголовок згенерованих Swift інтерфейсів ($ (PRODUCT_MODULE_NAME) -Swift.h) для цілей програми, а тому не можуть використовуватися для тестування коду, який вимагає цього заголовка.

Тести на код Swift слід писати на Swift. Тести, написані на Objective-C для рамкових цілей, можуть отримати доступ до інтерфейсів, створених Swift, імпортуючи рамковий модуль за допомогою @import FrameworkName ;. (16931027)

Будь ласка, див. Вирішення @ gagarwal, нижче якого РОБОТИ!


8

У мене було подібне питання до вашого, я думаю; тут була моя установка.

У мене був визначений об’єкт у Swift:

// file Foo.swift
@objc public class Foo {
    // ...
}

Потім цей клас використовувався в ініціалізаторі об’єкта Objective-C:

// file Bar.h
#import "MyProject-Swift.h"

@interface Bar: NSObject

- (instancetype)initWithFoo:(Foo *)foo;

@end

Це зробило тести моїх одиниць Barне компільованими, оскільки MyProject-Swift.hзаголовок не справжній, і ціль тесту одиниці не може його побачити. Зауваження до випуску, яке поділився @hyouuu, є суттєвим, але я не тестую клас Swift, я тестую клас Objective-C!

Мені вдалося виправити це, змінивши файл заголовка, Barщоб замість цього використовувати посилання прямого класу:

// file Bar.h
@class Foo;

@interface Bar: NSObject

- (instancetype)initWithFoo:(Foo *)foo;

@end

Потім я включив MyProject-Swift.h вBar.m , і все працювало - мої тести Objective-C об'єктів написані на Objective-C , складений належним чином і продовжував бігти, і я міг би написати нові тести для об'єктів Swift в Swift.

Сподіваюся, це допомагає!


Ваше рішення не дозволяє використовувати FooAPI API всередині Bar.m.
Євген Дубінін

2
Звичайно, так - саме те, що включає MyProject-Swift.hу .mфайл, отримує вас.
dpassage

4

Після того, як я спробував усе, що міг знайти в цій темі, те, що мені вдалося, насправді запускало додаток, хоча воно все ще відображало помилку "ModuleName-Swift.h file not found".

Це пішло, і моя програма працює прекрасно. Думаю, мені слід було це враховувати раніше ... Помилка постійно повертається , але після запуску програми вона просто знову зникає. Тож питання насправді не вирішено для мене, але я можу продовжувати роботу над іншими темами зараз ...


Так, це рішення, щоб помилка "не знайдена" пішла.
Vijay Kumar Kanta

Навіть зараз Build не вдається, коли працює лише додаток. Виправте це, Apple!
ScottyB


0

Як не дивно, я бачив цю саму помилку, але лише при націлюванні на пристрій (а не на тренажер). Перед запуском тесту я бачив червоний знак оклику поруч із оператором імпорту для "MyProjectNameTests-Swift.h".

Однак смішним є те, що якщо я просто продовжую запускати тест у будь-якому випадку (незважаючи на цю очевидну помилку збірки), то під час фази збірки, що трапляється після цього, XCode насправді генерує файл "MyProjectNameTests-Swift.h" і тест працює просто чудово!

Тож, принаймні, в моєму випадку, не було потреби в інших рішеннях тут, очевидно, хоча я вважаю, що вони теж працюють.

Я також повинен зазначити, що я видалив свій каталог DerivedData до цього, тому, можливо, це і крок, який варто також спробувати.


-1

mySwiftClassTests(та будь-які інші швидкі класи, які ви хочете використовувати в target-c), потрібно позначити @objc:

@objc class MySwiftClassTests: XCTestCase

-1

Я не зміг змусити його працювати, додавши той шлях до файлу, згаданий в інших відповідях, але я зрозумів, що файл, на який він скаржився, навіть не тестувався. Мені просто довелося видалити його з тестової цілі за допомогою бічної панелі Right Utilities.


-2

Додавання .swift-файлу до цільової проблеми виправлення на ньому.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.