Writing in the front
The importance of unit testing is self-evident. In the process of iterative development of the Framework, good unit testing can detect problems early.
XCTests is the most common tool for unit testing of the iOS Framework, but it has some limitations, so I wrote a small tool to supplement it.
This article briefly covers the use of XCTests.
Create a project
To create a new SDKDemo project, Include Unit Tests
Generate the project figure with a Target for SDKDemoTests and the corresponding directory
Create NetworkRequest as a test object with the following code:
@interface NetworkRequest : NSObject
- (BOOL)configure;
@end
@implementation NetworkRequest
- (BOOL)configure {
return YES;
}
@end
Copy the code
Use XCTests for unit testing
In the new template, select Unit Tests Case Class and create NetworkRequestTests as shown in the figure below:
#import <XCTest/XCTest.h>
#import "NetworkRequest.h"
@interface NetworkRequestTests : XCTestCase
@property (nonatomic.strong) NetworkRequest *request;
@end
@implementation NetworkRequestTests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
self.request = [NetworkRequest new];
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
// Add the test method
- (void)testConfigure {
XCTAssertTrue([self.request configure]);
}
@end
Copy the code
For each method that starts with test, Xcode displays a dot to the left. Click on it to run the test method, and use the command+ U shortcut to execute all the tests.
Also XCTests provides a number of assertions, such as XCTAssertTrue used above.
The dot appears green when the assertion is true, red otherwise.
If there are blocks, how do I test them?
Add code to NetworkRequest:
@interface NetworkRequest : NSObject
- (void)loginWithCompletionHandler:(void(^) (BOOL success))handler;
@end
@implementation NetworkRequest
- (BOOL)configure {
return YES;
}
- (void)loginWithCompletionHandler:(void(^) (BOOL))handler {
NSLog(@"Begin login");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
handler(YES);
});
}
@end
Copy the code
For Block tests, use XCTestExpectation and call the fullfill method inside the Block. Otherwise, the test will not wait for the Block to execute and exit.
Test code:
@implementation NetworkRequestTests
- (void)testLogin {
Declare an XCTestExpectation object
XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"login expectation"];
[self.request loginWithCompletionHandler:^(BOOL success) {
XCTAssertTrue(success);
// Call fullfill to tell XCTestExpectation has appeared
[expectation fulfill];
}];
/ / wait for XCTestExpectation
[self waitForExpectationsWithTimeout:5 handler:nil];
}
@end
Copy the code
Code coverage
It is not enabled by default. You can edit the Test Scheme, as shown in the figure below
Run the test again and see the results as shown
How do I reference the Framework in a unit test?
A typical scenario during Framework development is when A references B and tests A, as described below
Because unit test targets are missing the Linked Frameworks and Libraries section in their General settings tab, you must instead drag the built frameworks to the Link Binaries With Libraries build phase.
In this case, you can’t test, which is why I wanted to supplement XCTests in the first place.
But then it turns out
In the Test target under the Build Settings tab, add @loader_path/Frameworks to the Runpath Search Paths if it isn’t already present.
There are solutions.
extension
XCTests is an official test method that is easy to use and ideal for unit testing.
One catch is that XCTests does not support real machine testing, so some features cannot be tested and performance cannot be tested on real machines.
For details on how to handle this situation, see the iOS Framework Unit Tests (2) — JDAppTests (Supplement to XCTests)
The resources
Apple Developer
Carthage