You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Asynchronous operations
- Expect, Wait, Fulfill, and Assert
- Define the Expectation. XCTestExpectation
- Mark the Expectations as Fulfill
- Pause the test method run until we have an answer
XCTestExpectation Pattern (see //1, //2, //3)
func testImageProcessing(){
// arrange
letimage=UIImage(named:"cats")!
letmanager=CatsProcessingManager()
// act
varcuteCats=0
// creating an expectation to get number of cats.
letexpectation=self.expectation(description:"Counting number of cats") //1
manager.findCuteCats(image: image){(numberOfCuteCats)in
cuteCats = numberOfCuteCats
// we've got an answer. our expectation is fulfilled!
expectation.fulfill() //2
}
// assert
// let's wait 5 seconds before asserting...
waitForExpectations(timeout:5.0, handler:nil) //3
XCTAssertEqual(cuteCats,3)}
Multiple fullfill, one expectation. expectedFulfillmentCount
- Dummy - Does nothing. Purpose: to fill the gap of instantiating objects
- Fake - always returns the same value
- Stub - control return value
- Spy - does not return anything. To record calls that can be asserted later
- Mock - assertion happens in Mock via `verify()` via `Bool`
Complete vs Partial Mocking - Partial is when mocking is done via subclassing. Partial should be avoided if possible
Avoid test doubles if possible
- Test doubles considered as a code smell.
Types of Coupling
- Subclass
- Shared Objects - diff objects mutating properties of shared obj
- Dependencies - recommend to inject dependencies, delegate pattern, protocol-based dep, closure
- Side Effects
Coupling Severity
- Tightly coupled - cannot be replaced
- Coupled - relies on particular type, able to change with obj of same type or subclass
- Loosely coupled - not dependent on specific class but rather protocol. When you can use mocks/stubs
- Decoupled - can communicate via closure or notification
Compare Arrays
- Items in the array, if not primitive, should be Comparable / Equatable
- do you need to test order? or not?
- does duplicate items matter in your test
Parameterized Unit Tests
Create Abstract Method for Testing. eg runTest
func runTest(
withData events :[Event],
expectedLayout :LayoutStructure,
file :StaticString= #file, line :UInt= #line
){
// act
letactualStructure=CalendarLayoutGenerator().generateLayout(events: events)
// assert
XCTAssertEqual(actualStructure, expectedLayout, file :
file, line : line)}func testGenerateLayout_abstractMethod1(){varevents=[Event]()
events.append(Event(...)) // different data set
...letexpectedLayout=LayoutStructure()runTest(withData: events, expectedLayout:LayoutStructure()) // <--
}func testGenerateLayout_abstractMethod2(){varevents=[Event]()
events.append(Event(...))...letexpectedLayout=LayoutStructure()runTest(withData: events, expectedLayout:LayoutStructure()) // <--
}
Loading test cases from a file
- effortless to add more tests cases
- easy to validate
- anybody can write
- excellent for cross-platform testing
- Bundle(for: type(of: self)).path(forResource: "tests", ofType: "json")
1) `names`, `expectedFullName` - input and expected output from test method
2) Creation of new test suite with several test cases
3) `addNewTest` - for every `invocation` creates new test case into test suite
4) actual test method
<reading> expect more </reading>
The text was updated successfully, but these errors were encountered:
By: Avi Tsadok 2020
Writing Tests
- Duplicate Assertion Code
- When your assertion code is too big
- When you assertion doesn't speak the right language
-
#file
and#line
- allows custom function to show fail feedback on correct test that failed- Expect, Wait, Fulfill, and Assert
- Define the Expectation.
XCTestExpectation
- Mark the Expectations as Fulfill
- Pause the test method run until we have an answer
//1
,//2
,//3
)expectedFulfillmentCount
isInverted
Test Doubles
- Test doubles considered as a code smell.
- Subclass
- Shared Objects - diff objects mutating properties of shared obj
- Dependencies - recommend to inject dependencies, delegate pattern, protocol-based dep, closure
- Side Effects
- Tightly coupled - cannot be replaced
- Coupled - relies on particular type, able to change with obj of same type or subclass
- Loosely coupled - not dependent on specific class but rather protocol. When you can use mocks/stubs
- Decoupled - can communicate via closure or notification
Comparing
Equatable
protocol. egXCTAssertEqual(person1, person2)
Comparable
protocol. egXCTAssertGreaterThan(person1, person2)
XCTAssertEqual(image1, image2)
- Items in the array, if not primitive, should be Comparable / Equatable
- do you need to test order? or not?
- does duplicate items matter in your test
Parameterized Unit Tests
runTest
- effortless to add more tests cases
- easy to validate
- anybody can write
- excellent for cross-platform testing
-
Bundle(for: type(of: self)).path(forResource: "tests", ofType: "json")
defaultTestSuite()
variable - return own own XCTestSuite<reading> expect more </reading>
The text was updated successfully, but these errors were encountered: