iOS-Swiftの単体テストの実行時に「MyProject-Swift.h」ファイルが見つかりません


94

プロジェクトの単体テストをセットアップしようとしています。これは既存のObjective-Cアプリで、最近Swiftクラスを1つ追加しました。'MyProject-Swift.h'とSwift Bridgingファイル( 'MyProject'と 'MyProjectTest'の両方)をセットアップし、Objective-CとSwiftの両方のコードを使用して、アプリを問題なくビルドして実行できます。

しかし、今は新しい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 2014年

1
上記の「 'MyProject-Swift.h'ファイルが見つからないというエラーも表示されます」というコメントの更新は次のとおりです。したがって、両方のターゲット(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」を追加すると機能しました。:)そのコメントからSOの答えを出せば、私はあなたに賞金を授与することができ、それがどんな素晴らしい答えであるかを他の人に明らかにすることができます。
finneycanhelp 2015年

回答:


148

「MyProject-Swift.h」ファイルは、次のパスに生成されます。

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

結局、これをユニットテストターゲットのヘッダー検索パスに追加します。

また、@ hyouuuが既知の問題であることを指摘したように、うまくいけば、Appleが最後にいくつかの良い解決策を提供するでしょう。私がこの上のソリューションを使用する必要があると思うまで。

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


魅力のように働いた!
DonnaLea 2015年

驚くばかり!Appleがこれを回避策として言及しない理由を知らない。この問題を抱えている人がこれ以上いないことにも驚いています。既存のものをSwiftに変換する既存のObj-Cプロジェクトを持っている人はだれでもこの問題に遭遇します。
mluisbrown 2015

@fabbは当てはまりません。TARGET_NAMEは通常<Product Name> Tests、テストターゲットのようなものです。ただし、製品名にスペースが含まれている場合、このソリューションは機能しません。解決策については、以下の私の答えを参照しください。
Christopher Pickslay 2015年

2
ただのメモですが、検索パスを追加して、具体的には「再帰的」に設定する必要がありました。明白かもしれませんが、私がそれをするまで、それは数回機能しませんでした。私はそれがサブフォルダに入ると思います。
ミロ

1
私のプロジェクトで$(TARGET_TEMP_DIR)は、うまくいきませんでした。私が使ったのは$CONFIGURATION_TEMP_DIR/{myTargetName}.build/DerivedSources
Jordan Bondo

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 codegenクラスのユニットテストの問題を解決します。
Elise van Looij 2017年

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で記述されたテストは、@ import FrameworkName;を使用してフレームワークモジュールをインポートすることにより、Swiftで生成されたインターフェイスにアクセスできます。(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オブジェクトの新しいテストを書くことができました。

お役に立てれば!


あなたのソリューションはFoo内部でのAPIの使用を許可していませんBar.m
Yevhen Dubinin 2014

2
確かにそれはありません-など、何ということMyProject-Swift.h.m、ファイルはあなたを取得します。
dpassage 2014

4

トピックで見つけたすべてのことを試した後、「ModuleName-Swift.hファイルが見つかりません」というエラーがまだ表示されていても、実際に機能していたのはアプリを実行することでした。

それはなくなり、私のアプリは完全に問題なく動作しました。私は以前にそれを考慮すべきだったと思います... エラーは繰り返し発生しますが、アプリを実行した後は常に再び消えます。したがって、問題は実際には解決されていませんが、今のところ他のトピックに取り組んでいくことができます...


はい、「見つかりません」エラーを解消するためのソリューションです。
Vijay Kumar Kanta 2018

今でも、アプリを実行しているだけでビルドが失敗します。これを直せ、アップル!
ScottyB


0

奇妙なことに、これと同じエラーが表示されましたが、デバイス(シミュレータではない)をターゲットにしている場合のみです。テストを実行する前に、 "MyProjectNameTests-Swift.h"のインポートステートメントの横に赤い感嘆符が表示されます。

ただし、面白いのは、先に進んでテストを実行した場合(この明らかなビルドエラーにもかかわらず)、その後に発生するビルドフェーズ中に、XCodeが実際に「MyProjectNameTests-Swift.h」ファイルを生成し、テストを実行することです。うまくいきます!

したがって、少なくとも私の場合、他の解決策は必要ありませんでした。明らかに、他の解決策も機能していると思います。

これの前にDerivedDataディレクトリを削除したことにも注意してください。そのため、これも試す価値のある手順です。


-1

mySwiftClassTests(およびobjective-cで使用したい他の迅速なクラス)はマークする必要があります@objc

@objc class MySwiftClassTests: XCTestCase

-1

他の回答で言及されているファイルパスを追加して機能させることはできませんでしたが、問題のあるファイルはテストされていなかったことがわかりました。右のユーティリティサイドバーを使用して、テストターゲットから削除する必要がありました。


-2

そのターゲットに.swiftファイルを追加すると、その問題が修正されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.