Требуется ли вызов tearDown?
Что-то меня считают давно. Допустим, мы написали тестовый класс:
final class BearerTokenManagerTests: XCTestCase {
private var bearerTokenManager: BearerTokenManager!
private var bearerTokenProvider: BearerTokenProvider!
private var stubKeyValueStore: KeyValueStoreDummyStub!
private var scheduler: TestScheduler!
private var disposeBag: DisposeBag!
override func setUp() {
super.setUp()
stubKeyValueStore = KeyValueStoreDummyStub()
bearerTokenProvider = BearerTokenProvider(keyValueStore: stubKeyValueStore)
bearerTokenManager = BearerTokenManager(bearerTokenProvider: bearerTokenProvider)
scheduler = TestScheduler(initialClock: 0)
disposeBag = DisposeBag()
}
override func tearDown() {
stubKeyValueStore = nil
bearerTokenProvider = nil
bearerTokenManager = nil
scheduler = nil
disposeBag = nil
super.tearDown()
}
func test_bearerToken_observeChanges() {
let bearerToken = scheduler.createObserver(BearerTokenManagerType.BearerToken.self)
bearerTokenManager.bearerToken
.bind(to: bearerToken)
.disposed(by: disposeBag)
scheduler.start()
// every update should be saved in key value store
bearerTokenManager.update(bearerToken: "123")
XCTAssertEqual(stubKeyValueStore.string(forKey: "BearerToken"), "123")
bearerTokenManager.update(bearerToken: "456")
XCTAssertEqual(stubKeyValueStore.string(forKey: "BearerToken"), "456")
bearerTokenManager.update(bearerToken: "789")
XCTAssertEqual(stubKeyValueStore.string(forKey: "BearerToken"), "789")
// every udpate should be emited
XCTAssertEqual(bearerToken.events, [
.next(0, nil), // by default (on start) token equal to nil
.next(0, "123"),
.next(0, "456"),
.next(0, "789"),
])
}
}
Является tearDown
вызов для очистки необходим?
Почему я подумал, что в этом нет необходимости:
- Перед каждым следующим тестом
setUp
сбрасывает все. - Когда тесты в
BearerTokenManagerTests
заканчивается, тогда все должно быть освобождено
Почему я не уверен
- Предполагая, что "Когда тесты в
BearerTokenManagerTests
заканчивается, тогда все должно быть освобождено "может быть неправильно - Я беспокоился о
RxScheduler
побочные эффекты - Кое-что я еще не знаю
Может кто-нибудь поделится своим опытом? Вы убираете вещи вtearDown
? Сбрасывает свойства вsetUp
довольно?
0 ответов
Быстрый ответ
Согласно этой статье: https://qualitycoding.org/xctestcase-teardown/
XCTest создает новый
XCTestCase
экземпляр для каждого отдельного вызова теста, но неdeinit
любой из них после завершения.
Демо
Я создал демонстрационное приложение в Xcode 11.7, и его поведение осталось прежним.
Тестируемая система
import UIKit
var counter = 0
class ViewController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
counter += 1;
print("Created ViewController, currently living: \(counter)")
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
deinit {
counter -= 1;
print("Destroyed ViewController, currently living: \(counter)")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
TestCase с
tearDown()
class ViewControllerTests: XCTestCase {
var vc: ViewController!
override func setUp() {
super.setUp()
vc = ViewController()
}
override func tearDown() {
vc = nil
super.tearDown()
}
func test_a() {
XCTAssert(true == true)
}
func test_b() {
XCTAssert(true == true)
}
func test_c() {
XCTAssert(true == true)
}
}
Вывод:
Test Suite 'ViewControllerTests' started at 2020-09-13 14:44:15.889
Test Case '-[DemoTests.ViewControllerTests test_a]' started.
Created ViewController, currently living: 1
Destroyed ViewController, currently living: 0
Test Case '-[DemoTests.ViewControllerTests test_a]' passed (0.001 seconds).
Test Case '-[DemoTests.ViewControllerTests test_b]' started.
Created ViewController, currently living: 1
Destroyed ViewController, currently living: 0
Test Case '-[DemoTests.ViewControllerTests test_b]' passed (0.000 seconds).
Test Case '-[DemoTests.ViewControllerTests test_c]' started.
Created ViewController, currently living: 1
Destroyed ViewController, currently living: 0
Test Case '-[DemoTests.ViewControllerTests test_c]' passed (0.000 seconds).
Test Suite 'ViewControllerTests' passed at 2020-09-13 14:44:15.891.
Executed 3 tests, with 0 failures (0 unexpected) in 0.002 (0.003) seconds
Test Suite 'sdadasTests.xctest' passed at 2020-09-13 14:44:15.892.
Executed 3 tests, with 0 failures (0 unexpected) in 0.002 (0.003) seconds
Test Suite 'Selected tests' passed at 2020-09-13 14:44:15.892.
Executed 3 tests, with 0 failures (0 unexpected) in 0.002 (0.004) seconds
TestCase без
tearDown()
class ViewController2Tests: XCTestCase {
var vc: ViewController!
override func setUp() {
vc = ViewController()
}
func test_a() {
XCTAssert(true == true)
}
func test_b() {
XCTAssert(true == true)
}
func test_c() {
XCTAssert(true == true)
}
}
Вывод:
Test Suite 'ViewController2Tests' started at 2020-09-13 14:47:43.067
Test Case '-[sdadasTests.ViewController2Tests test_a]' started.
Created ViewController, currently living: 1
Test Case '-[DemoTests.ViewController2Tests test_a]' passed (0.001 seconds).
Test Case '-[DemoTests.ViewController2Tests test_b]' started.
Created ViewController, currently living: 2
Test Case '-[DemoTests.ViewController2Tests test_b]' passed (0.000 seconds).
Test Case '-[DemoTests.ViewController2Tests test_c]' started.
Created ViewController, currently living: 3
Test Case '-[DemoTests.ViewController2Tests test_c]' passed (0.000 seconds).
Test Suite 'ViewController2Tests' passed at 2020-09-13 14:47:43.070.
Executed 3 tests, with 0 failures (0 unexpected) in 0.002 (0.003) seconds
Test Suite 'sdadasTests.xctest' passed at 2020-09-13 14:47:43.070.
Executed 3 tests, with 0 failures (0 unexpected) in 0.002 (0.003) seconds
Test Suite 'Selected tests' passed at 2020-09-13 14:47:43.071.
Executed 3 tests, with 0 failures (0 unexpected) in 0.002 (0.004) seconds
Длинный ответ
Как вы можете видеть в примере без
tearDown()
инициализировать внутри
setUp()
не назначает новый объект тому же свойству. Каждый тест создает отдельный экземпляр и не
deinit
это после завершения. Только конец всего
XCTestCase
экземпляры будут освобождены.
В небольшом проекте это, наверное, не имеет большого значения.
Но если у вас много тестов в одном
XCTestCase
и вы создаете много данных в
setUp()
(например, заглушки, занимающие много памяти), вам следует подумать об использовании
tearDown()
потому что каждый тест будет хранить свою копию данных из
setUp()
пока не все
XCTestCase
будет завершена, и вы можете столкнуться с проблемами ограничения памяти.