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.