IOS --- use XCTest for unit testing

Source: Internet
Author: User
Tags image filter

IOS --- use XCTest for unit testing

Test-driven development (TDD) is a popular development concept. XCTest is an Apple-encapsulated Unit Test Library. The process of using XCTest for unit testing is relatively simple. This blog only briefly introduces the use of XCTest. However, the understanding of unit testing (when to use it and how to drive development more efficiently) is a process that needs to be accumulated and should be carefully understood in the TDD process.

SetUp and tearDown

A test case exists in the form of an Objective-C class. The implementation has the default setUp and tearDown methods, which are used to process the preparations before and after the execution of the test case.

- (void)setUp {    [super setUp];    // Put setup code here. This method is called before the invocation of each test method in the class.}- (void)tearDown {    // Put teardown code here. This method is called after the invocation of each test method in the class.    [super tearDown];}

Therefore, initialization of basic objects and other necessary steps are often performed in setUp.

Unit Test

All instance methods starting with test (with no parameters) are a complete unit test case.

There is a small icon on the left. Click it to execute the test case.

Performance Testing

Performance testing can be used directly-(Void) measureBlock :( void (^) (void) block;The transfer parameter is a block consisting of the tasks to be executed.
The following cases can be used to test the performance of the block parameters received by measureBlock.

Baseline can be used to set a reference benchmark for qualified performance.
Note: In a performance test case, only one measureBlock can be executed, that is, only the performance of one specified block step can be tested (this is also reasonable, where can I separate the performance test results ). Therefore, you cannot use measureBlock in a while, for, or other loop. Otherwise, an error occurs.
The usage of measureMetrics is similar to that of measureBlock.
Of course, you can also use startMeasuring and stopMeasuring methods for performance testing, but in most cases, using measureBlock is sufficient.

Macro definition of Performance Testing

For example, when you test the performance of an image filter separately, you can:

-(Void) testPerformanceFilter1 {[self measureBlock: ^ {NSInteger filterid = 100; UIImage * filteredImage = [FilterTool filterImage: self. image withFilterId: filterid]; XCTAssertNotNil (filteredImage, @ "filter should not be blank") ;}];}

So what if there are dozens of filters that require performance testing?
Because the method name of the unit test case cannot pass parameters and the measureBlock cannot be used in the loop, it seems that macro definition is a better solution for a large number of repeated performance test cases.

# Define TestFilterPerformance (filterid)-(void) testFilterPerformance _ # filterid {\ [self measureBlock: ^ {\ UIImage * filteredImage = [FilterTool filterImage: self. image withFilterId: filterid]; \ XCTAssertNotNil (filteredImage, @ "filter should not be blank"); \}]; \}

Then, all test cases can be defined as follows.

Asynchronous Test

XCTest provides XCTestExpectation for asynchronous testing. You can use its fulfill instance method at the specified time to start executing the asserted command. For example, the following is a test example of a complete network request. It can be used to test whether the server is normal and must be asserted in the corresponding block.

-(Void) testAsynchronousURLConnection {XCTestExpectation * expectation = [self expectationWithDescription: @ "GET Baidu"]; NSURL * url = [NSURL URLWithString: @ "http://www.baidu.com/"]; NSURLSession * session = [NSURLSession sharedSession]; operator * task = [session completion: url completionHandler: ^ (NSData * _ Nullable data, NSURLResponse * _ Nullable response, NSError * _ Nullable error) {// The XCTestExpectation condition has been met, and the following test can be executed. [Expectation fulfill]; XCTAssertNotNil (data, @ "returned data should not be nil"); XCTAssertNil (error, @ "error should be nil"); if (nil! = Response) {NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response; XCTAssertEqual (httpResponse. statusCode, 200, @ "The HTTPResponse status code should be 200"); XCTAssertEqual (httpResponse. URL. absoluteString, url. absoluteString, @ "HTTPResponse URL should be consistent with the requested URL");} else {XCTFail (@ "Returned content is not NSHTTPURLResponse type") ;}]; [task resume]; // After timeout, run [self waitForExpectationsWithTimeout: 10 handler: ^ (NSError * _ Nullable error) {[task cancel] ;}];}

That is, the Asynchronous Network request operation is normal, but the assertion command is only executed after [expectation fulfill];. This ensures that the corresponding assertion is executed after the result of the network request is returned. You can also set the timeout time and corresponding operations.
Otherwise, you need to use a timing mechanism to handle similar situations.

Access the private variables of the class to be tested

In case, how to access a private variable of the class to be tested? This class can be expanded accordingly.

#import 
  
   #import "FilterTool.h"@interface FilterTool (UnitTest)@property (strong, nonatomic) FilterController *filterController;- (void)didSelectFilterCellAtIndexPath:(NSIndexPath *)indexPath;@end@interface FilterToolTest : XCTestCase@end@implementation FilterToolTestXXXX@end
  

FilterController attribute of the FilterTool class and didSelectFilterCellAtIndexPath: The method is private. To test the method, you must add it to the extension.

Asserted command
XCTFail (format ...) Generate a failed test. If XCTAssertNil (a1, format...) is null, it is passed when a1 is null, otherwise it fails. XCTAssertNotNil (a1, format ...) If it is not null, a1 is passed when it is not null, and vice versa; XCTAssert (expression, format ...) when expression is evaluated as TRUE, it is passed; XCTAssertTrue (expression, format ...) when expression is evaluated as TRUE, it is passed; XCTAssertFalse (expression, format ...) when expression is evaluated as False, it is passed; XCTAssertEqualObjects (a1, a2, format ...) when the value of [a1 isEqual: a2] is TRUE, it is passed. If one of them is not empty, it is not passed. XCTAssertNotEqualObjects (a1, a2, format ...) when the value of [a1 isEqual: a2] is False, XCTAssertEqual (a1, a2, format ...) equal judgment (when a1 and a2 are C language scalar, Struct or consortium used, the actual test found that NSString can also); XCTAssertNotEqual (a1, a2, format ...) unequal judgment (used when a1 and a2 are c scalar, struct, or consortium); XCTAssertEqualWithAccuracy (a1, a2, accuracy, format ...) equality judgment. (double or float type) provides an error range, which is tested when the error range (+/-accuracy) is equal. XCTAssertNotEqualWithAccuracy (a1, a2, accuracy, format ...) unequal judgment, (double or float type) provides an error range, which is tested when the error range is not equal to; XCTAssertThrows (expression, format ...) exception test: used when expression is abnormal. Otherwise, it fails. (abnormal) XCTAssertT HrowsSpecific (expression, specificException, format ...) exception test: This method is used when expression specificException exception occurs. Otherwise, other exceptions or no exceptions fail. XCTAssertThrowsSpecificNamed (expression, specificException, exception_name, format ...) exception test: If expression encounters an exception or a name exception, the test is passed. If expression fails, XCTAssertNoThrow (expression, format ...) Exception test: test the expression when no exception occurs. XCTAssertNoThrowSpecific (expression, specificException, format ...) exception test: If expression does not have an exception or a specific exception name, the test is passed. Otherwise, the test fails. XCTAssertNoThrowSpecificNamed (expression, specificException, exception_name, format ...) exception test: If expression does not have an exception or a specific exception name, the test is passed. Otherwise, the test fails.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.