web-dev-qa-db-ja.com

テストターゲットに追加するときのIBDesignableエラー

UIButtonIBDesignablevarを実装する単純なIBInspectableサブクラスがあります。

@IBDesignable class Button: UIButton {
    @IBInspectable var borderColor: UIColor = UIColor.whiteColor() {
        didSet { layer.borderColor = borderColor.CGColor }
    }
}

私はこれをフレームワーク内で使用しておらず、意図したとおりにInterface Builderで機能していますが、このサブクラスをTestsターゲットに追加すると、ライブレンダリングが停止し、次のエラーが発生します。

Main.storyboard: error: IB Designables: Failed to update auto layout status: dlopen(TestTests.xctest, 1): Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: TestTests.xctest
Reason: image not found

Main.storyboard: error: IB Designables: Failed to render instance of Button: dlopen(TestTests.xctest, 1): Library not loaded: @rpath/XCTest.framework/XCTest
Referenced from: TestTests.xctest
Reason: image not found

IBDesignableIBInspectable varsを削除すると、エラーはなくなります。残念ながら、InterfaceBuilderでのライブレンダリングもなくなります。

これらのエラーなしでIBDesignableクラスに対してテストするにはどうすればよいですか?

21
Adolfo

最初は、これはXcodeの一種のバグだと思いました。以下は私が見つけた回避策です:

ステップ1

クラスとプロパティをpublicとしてマークします。

@IBDesignable public class Button: UIButton {
    @IBInspectable public var borderColor: UIColor = UIColor.whiteColor() {
        didSet { layer.borderColor = borderColor.CGColor }
    }

    @IBInspectable public var borderWidth:CGFloat = 0.0 {
        didSet { layer.borderWidth = borderWidth }
    }
}

ステップ2

「テスト」モジュールからアプリケーションモジュールをインポートします。

たとえば、アプリケーションの名前がMyGreatAppであるとすると、MyGreatAppTests/MyGreatAppTests.Swift

import UIKit
import XCTest
import MyGreatApp

class MyGreatAppTests: XCTestCase {

    func testExample() {
        let btn = Button()
        btn.borderColor = UIColor.redColor()
        XCTAssertEqual(UIColor(CGColor:btn.layer.borderColor), UIColor.redColor(), "borderColor")
    }
}

「Tests」ターゲットに「Button.Swift」を追加する必要はありません。

ステップ(スイフト用)

ストーリーボードで、Xcodeに現在のモジュールを使用させるのではなく、カスタムクラスのモジュールMyGreatAppを明示的に選択します。

Interface Builder select main target module

17
rintaro

あなたの質問は、私が経験した状況を正確に説明しています。エラーは、独自の属性の下の属性インスペクターにも表示されます。

これは私のために働いた回避策です:

ステップ1ソースコードからすべての@IBDesignableと@IBInspectableを削除します

ステップ2 InterfaceBuilderに戻ります。エラーはまだあります。

ステップ XCodeを再起動し、プロジェクトを再構築します。エラーは消えるはずです。

ステップ4すべての@IBDesignableと@IBInspectableをソースコードに再度追加します

このステップの後、私は問題なくプロジェクトを進めることができました。

これが機能する理由は、[プロジェクト]-> [クリーン]を実行したときに、インターフェイスビルダーが削除されない(後で再構築される)ものをキャッシュするという私の理論です。

もう1つの答え(メインモジュールをテストモジュールにインポートする)は良い考えであり、過去に私にとっていくつかの厄介な問題を解決しましたが、これは解決しませんでした。

15
Gerd Castan

解決策は非常に簡単です。テストターゲットを削除し、最初からもう一度作成する必要があります。プロジェクトをXcode7に移動したときに、テストターゲットが破損しているという警告が表示されました。そこで、もう一度設定することにしました。 それはうまくいきました!

さらに、ストーリーボードやクラスさえもテストターゲットに添付しません。このようにしないでください:

enter image description here

代わりに、次のようにしてください。

enter image description here

したがって、テストターゲット(@IBDesignablesのクラスを含む)からファイルを削除するだけです。テストターゲット内のクラスにアクセスする必要がある場合は、@testable import MyAppを使用してください。

enter image description here

それは機能しており、IBDesignablesのすべてのエラーが消えます。楽しい:-)

これを引き起こしているのは何ですか?

このエラーは、次の2つの場合に発生します。

  1. @IBDesignableまたは@IBInspectableを含むファイルをテストターゲットに含めます。
  2. .storyboardまたは.xibファイル(設計可能/検査可能なビューを含む)を開きます。

これを防ぐにはどうすればよいですか?

どちらか:

  1. @IBDesignableまたは@IBInspectableを含むファイルをテストターゲットに含めないでください。 (いくつかの分離されたモデルファイルをテストしているだけの場合、それらはテストターゲットのメンバーのままでかまいません。)
  2. テストターゲットからすべてのアプリのファイルを削除し( Bartłomiejの回答 に示すように)、代わりにアプリのモジュールをテストファイルにインポートします(例:@testable import MyApp詳細はこちらをご覧ください 。)これはベストプラクティスであり、設計可能/検査可能なビューとモデルコードのテストを継続できます。アプリ内。

それがすでに起こったらどうすれば解決できますか?

このエラーの厄介な点は、問題が解決された後は自動的に消えないことです。これは、IBが何かをキャッシュしている可能性があるためです Gerdは彼の回答で示唆しています

私が見つけたのは、上記の2つの予防策のいずれかを実際に実行した後、Xcodeを(コードを変更せずに)再起動するだけでエラーがなくなることです。

2
George WS

私はついに解決策を見つけました。ビルド設定/その他のリンカーフラグの下で、テストターゲットに「-frameworkXCTest」を追加してください。

1
CZ54

この問題は、テストターゲットのビュークラスにカテゴリまたは拡張機能を含めることによっても発生する可能性があります。

0
Brian Croom