2016-05-04 2 views
3

Я новичок в быстром автоматическом тестировании с использованием XCTest. В моей работе я столкнулся с правильной компоновкой некоторых частей кода внутри теста Просьба пояснить разницу между объявлением переменной в начале класса и определенной функцией. Какой способ является предпочтительным?Объявление переменной внутри класса в Swift

вар.1

class someClass: XCTestCase { 
    let app = XCUIApplication() 

    func someFunc { 
     print (app.debugdescription) 
    } 
} 

Var. 2

class someClass: XCTestCase { 

func someFunc { 
     let app = XCUIApplication() 
     print (app.debugdescription) 
    } 
} 

ответ

1

переменной декларации в качестве уровня класса или уровня функции такой же, как и в других языках программирования, так что было бы здорово, если вы понимаете, их основной принцип.

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

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

1

Var. 1 дает вам возможность сконфигурировать ваш XCUIApplication в setup() и использовать его в тестах. Например:

class someClass: XCTestCase { 
    var app: XCUIApplication! 

    func setUp { 
     app = XCUIApplication() 
     app.launchArguments.append("launchArgument") 
     setupSnapshot(app) 
     app.launch() 
    } 

    func test1 { 
     XCTAssertNotNil(app) 
    } 

    func test2 { 
     XCTAssertNotNil(app) 
    } 
} 

С Var. 2 вы можете настроить свое приложение по-разному в каждом тесте. Как это:

class someClass: XCTestCase { 

    func test1 {   
     let app = XCUIApplication() 
     app.launchArguments.append("withTestUser") 
     app.launch() 

     XCTAssertNotNil(app) 
    } 

    func test2 {   
     let app = XCUIApplication() 
     app.launchArguments.append("withNoData") 
     app.launch() 

     XCTAssertNotNil(app) 
    } 
} 
+0

Первого примера не компилируется, так как вы заявляете 'app' в качестве константы, а затем пытается изменить его значение в' setUp' –

+0

@MaximKosov Спасибо, обновлено – Daniel

2

Возможны обе стороны, но var 2 является предпочтительным. Для вар 1 решения рассмотрим следующий сценарий:

class State { 
    var val: Int = 0 
} 

class TestClass: XCTestCase { 
    let state = State() 

    func test1() { 
     state.val = 5 

     XCTAssertEqual(5, state.val) 
    } 

    func test2() { 
     XCTAssertEqual(0, state.val) 
    } 
} 

Таким образом, результат зависит от того, какой тест будет выполняться первым. Если test2 будет первым, то оба теста будут успешными. Другой способ, второй тест не удастся.

Для вар 2 раствора

class TestClass: XCTestCase { 
    func test1() { 
     let state = State()    

     state.val = 5 

     XCTAssertEqual(5, state.val) 
    } 

    func test2() { 
     let state = State() 

     XCTAssertEqual(0, state.val) 
    } 
} 

оба теста не преуспевает, независимо от того, что тест будет выполняться в первую очередь. Это делает предпочтительным решение в большинстве сценариев var 2.

Существует случай, когда вар 1 более удобно чем вар 2.Это когда SUT имеет много зависимостей, и вам нужно скопировать и вставить код создания для них в каждом тесте. Тогда вы можете объявить зависимости в качестве переменного класса, но необходимо использовать тест setUp (и, возможно, tearDown), чтобы убедиться, что их состояние обновляется перед каждым испытанием

class TestClass: XCTestCase { 
    var dep1: Dependency1! 
    var dep2: Dependency2! 

    var sut: SUT! 

    func setUp() { 
     dep1 = Dependency1() 
     dep2 = Dependency2() 

     sut = SUT(dep1, dep2) 
    } 
}