2015-11-10 2 views
3

Справочная информация. Я хочу проверить частные методы с помощью XCTest, поэтому я ищу элегантное решение для предоставления частных методов для моих классов XCTestCase.Использование встроенных макросов препроцессора в Swift

Отказ от ответственности. Некоторые люди считают, что в корне неверно тестировать внутренности ваших классов. На практике я не согласен, потому что, когда тесты ломаются, тестирование рядовых может облегчить отслеживание проблемы.

Быстрые частные функции являются приватными для файла, а частные - частными, поэтому нет возможности публиковать частные функции для других файлов. Используя макросы препроцессора, частные функции могут быть открыты через публичные функции только для одной конфигурации сборки. Например, у меня есть настройка флага компиляции TEST для моей тестовой конфигурации, используемой в моей тестовой схеме.

До сих пор, это лучшее решение, которое я есть, но это требует раздражает шаблонного для каждой частной функции, которая нуждается в тестировании:

В ClassThatNeedsTesting.swift:

class ClassThatNeedsTesting { 
    #if TEST 
    func publicAccessToPrivateFunctionThatNeedsTesting() -> Bool { 
     return self.privateFunctionThatNeedsTesting() 
    } 
    #endif 

    private func privateFunctionThatNeedsTesting() -> Bool { 
     return true; 
    } 
} 

В TestClass.swift:

class TestClass: XCTestCase { 
    func testExample() { 
     XCTAssert(ClassThatNeedsTesting().publicAccessToPrivateFunctionThatNeedsTesting()); 
    } 
} 

Но есть ли способ упростить это с помощью встроенных макросов препроцессора? Это то, что я хочу, но он не компилируется, следовательно, почему я спрашиваю:

В ClassThatNeedsTesting.swift:

class ClassThatNeedsTesting { 
    #if TEST private #endif func privateFunctionThatNeedsTesting() -> Bool { 
     return true; 
    } 
} 

В TestClass.swift:

class TestClass: XCTestCase { 
    func testExample() { 
     XCTAssert(ClassThatNeedsTesting().privateFunctionThatNeedsTesting()); 
    } 
} 

Если есть нет способа сделать это, возможно, есть более простое решение?

ответ

3

Используйте @testable, новый Swift в 2.0:

@testable import MyModule 

class TestClass: XCTestCase { 
    func testExample() { 
     XCTAssert(ClassThatNeedsTesting().privateFunctionThatNeedsTesting()); 
    } 
} 

От Xcode 7 Release Notes

тестируемости. Благодаря тестируемости вы теперь можете писать тесты Swift 2.0 и приложений без необходимости публиковать все свои внутренние процедуры. Используйте @testable import {ModuleName} в своем тестовом исходном коде, чтобы сделать все общедоступные и внутренние процедуры доступными для целей XCTest, но не для других целей и приложений.

Следует ли тестировать частные методы или нет, является горячей темой. См. Обсуждение here, here и here

+2

Это не работает. Документация Apple, на которую вы ссылаетесь, указывает, что «Использовать' @ testable' import {ModuleName} в исходном коде теста, чтобы все общедоступные и внутренние процедуры использовались для целей XCTest ». '@ testable' работает только для общедоступных и внутренних процедур, а не для частных процедур. – kev

+0

Просто добавив соглашение с kev, поскольку у меня была такая же проблема. В моих тестах я получил следующую ошибку при вызове частного метода: использование неразрешенного идентификатора «PrivateMethodNameHere». Обратите внимание, что если бы это был Obj-C, вы могли бы вызвать частный метод, и это обсуждается здесь: http://stackoverflow.com/questions/12353795/objective-c-unit-testing-core-functionality-in-private-methods – xdeleon

+0

Как бы вы используете @testable в объективе-c?И, можете ли вы импортировать свое приложение в качестве модуля в объективе-c? Пожалуйста, простите невежество - хорошей информации трудно найти по этой теме! – shmim