The addTeardownBlock(_:) runs right after the test method ends and before the instance’s tearDownWithError() method is called.
Below is an example of a TestCase class that does not test anything and only demonstrates the order in which the setUp() and tearDown() methods are called.
If you are interested in video lessons on how to write Unit tests and UI tests to test your Swift mobile app, check out this page: Unit Testing Swift Mobile App
When will the addTeardownBlock(_:) run?
The addTeardownBlock will run after the test method is executed and before the instance, tearDownWithError() method is called. Below is an order in which the setUp() and tearDown() methods of XCTestCase class are called.
- override class func setUp() – Class level setUp() method is called one time only per each Test Case class. This method will be called before any method in a test case class,
- override func setUpWithError() throws – An Instance setUpWithError() method is called before each test method runs,
- addTeardownBlock(_:) – Is called after the test method ends even if the test method fails,
- override func tearDownWithError() throws – An instance tearDownWithError() method is called after each test method runs,
- override class func tearDown() – Class level tearDown() method is called one time only per each Test Case class. This method will be called after all methods have been executed.
import XCTest class TearDownTestExample: XCTestCase { override class func setUp() { print("**** Class setUp() method is called") } override func setUpWithError() throws { print("**** Instance setUpWithError() method is called") } override class func tearDown() { print("**** Class tearDown() method is called") } override func tearDownWithError() throws { print("**** Instance tearDownWithError() method is called") } func testExample() throws { print("**** Test method is called") addTeardownBlock { // Called when testExample() ends. print("**** TeardownBlock is called when test method ends") } } }
If you run the above XCTestCase in your project, it will give you the following output.
**** Class setUp() method is called **** Instance setUpWithError() method is called **** Test method is called **** TeardownBlock is called when the test method ends **** Instance tearDownWithError() method is called **** Class tearDown() method is called
When to use the addTeardownBlock?
You will want to use the addTeardownBlock when a test method creates a resource that should be destroyed. You can destroy resources in the tearDownWithError() method but this method runs after each test method in the Test Case class. Whereas the addTeardownBlock runs one time only after a test method that has registered the addTeardownBlock.
A possible use-case for addTeardownBlock is to clear temporary records from a database. Assume you need to test that your system under test can successfully store user records into a database. After storying one record, and asserting that the record has been successfully stored, you want to remove the record from a database. In this case, you can use the addTeardownBlock() to remove a record from a database after the test method ends.
func testExample() throws { // Arrange let userRecord = User(firstName: "Sergey", lastName: "Kargopolov") // Act let storedRecord = sut.storeRecord(userRecord) addTeardownBlock { sut.deleteRecord(storedRecord) } // Assert XCTAssertNotNil(storedRecord) }
I hope this tutorial was of some value to you. There are other useful Unit Testing tutorials on this blog if you check the Unit Testing category. I hope you will find what you are looking for!
Happy unit testing! 🙋🏻♂️