IBDesignable Ошибки при добавлении к тестированию

У меня есть простой подкласс UIButton, который реализует IBDesignable с помощью IBInspectable var:

@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

Если я удаляю IBDesignable и IBInspectable vars, ошибки уходят - к сожалению, так же делает live рендеринг в Interface Builder.

Как я могу протестировать класс IBDesignable без этих ошибок?

Ответ 1

Сначала я подумал, что это была своего рода ошибка в 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")
    }
}

Вам не нужно добавлять "Button.swift" в цель "Тесты".

ШАГ 3 (для Swift)

В своей раскадровке явным образом выбираю модуль MyGreatApp для любых пользовательских классов вместо того, чтобы Xcode использовал текущий модуль.

Interface Builder select main target module

Ответ 2

В вашем вопросе описаны именно те обстоятельства, которые я испытал. Ошибка также видна в инспекторе атрибутов под вашими собственными атрибутами.

Это обходной путь, который работал у меня:

Шаг 1 удалите все @IBDesignable и @IBInspectable из вашего исходного кода

Шаг 2 Вернитесь к построителю интерфейса. Ошибка все еще существует.

Шаг 3 Перезапустите XCode, перестройте свой проект. Ошибки должны быть устранены.

Шаг 4 добавьте все @IBDesignable и @IBInspectable снова в исходный код

После этих шагов я смог без проблем справиться с моим проектом.

Моя теория, почему это работает, заключается в том, что создатель интерфейса кэширует некоторые вещи, которые не удаляются (и перестраиваются позже), когда вы выполняете проект → Очистить.

Другой ответ (Импорт основного модуля в ваш тестовый модуль) является хорошей идеей и решил некоторые неприятные проблемы для меня в прошлом, но не для этого.

Ответ 3

Решение очень простое. Вам нужно удалить тестовую цель и создать ее с самого начала. Когда я перенес проект в Xcode 7, я получил предупреждение о том, что мой тестовый объект поврежден. Поэтому я решил снова настроить его. IT WORKED!.

Кроме того, вы не прикрепляете свои раскадровки и даже какой-либо класс к своей тестовой цели. Пожалуйста, не делайте этого так:

введите описание изображения здесь

Вместо этого сделайте это следующим образом:

введите описание изображения здесь

Итак, просто удалите любой файл из тестовой цели (включая классы с @IBDesignables), тогда, если вам нужен доступ к вашим классам в тестовой цели, просто используйте @testable import MyApp:

введите описание изображения здесь

Он работает, и все ошибки с IBDesignables исчезнут. Наслаждайтесь: -)

Ответ 4

Что вызывает это?

Эта ошибка появляется, когда происходят две вещи:

  • Вы включаете в тестовый объект любой файл, содержащий @IBDesignable или @IBInspectable.
  • Вы открываете свой файл .storyboard или .xib(содержащий ваши назначаемые/проверяемые виды).

Как я могу предотвратить это?

Или:

  • Не включайте в тестовый объект файлы, содержащие @IBDesignable или @IBInspectable. (Если вы просто тестируете несколько изолированных файлов моделей, они могут оставаться членами вашей тестовой цели.)
  • Удалите все ваши файлы приложений из тестовой цели (как показано в Bartłomiej answer) и вместо этого импортируйте свой модуль приложений в тестовый файл (например, @testable import MyApp - Подробнее см. Здесь. Это лучшая практика, позволяющая продолжить тестирование ваших прогнозируемых/проверяемых представлений, а также любого кода модели в вашем приложении.

Как я могу решить его, как только это произошло?

Ужасная вещь с этой ошибкой заключается в том, что она автоматически не уходит, как только проблема будет решена, возможно, потому что IB может кэшировать что-то в качестве Герд предлагает в своем ответе.

Что я обнаружил, так это то, что если вы фактически выполнили одну из двух превентивных мер, перечисленных выше, просто перезапустите Xcode (без изменения какого-либо кода), чтобы ошибка исчезла.

Ответ 5

Наконец я нашел решение. Juste добавляет "-framework XCTest" к вашей тестовой цели в разделе "Настройки сборки" /другие флаги компоновщика.

Ответ 6

Эта проблема также может быть вызвана включением любых категорий или расширений в класс представления в тестовой цели.