Simple use of unit tests
Unit tests of methods that reference the AFN framework
A programmer who does not write unit tests is not qualified. In order to become a qualified programmer, it is necessary to learn how to write unit tests. Here is an example of XCTest, the testing framework integrated with Xcode.
Basic usage of XCTest
The default test class inherits from XCTestCase, but you can also customize the test class by adding some common helper methods. All test methods must start with test and have no parameters, otherwise they will not be identified as test methods.
@interface__tests :XCTestCase@end @implementation__tests // Called before the start of each test case to initialize the relevant data – (void)setUp {[supersetUp]; 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.[supertearDown]; // 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.[selfmeasureBlock:^{// Put the code you want to measure the time of here.}]; }/// my custom test method for the Person class – (void)testPerson{}@end
assertions
Assertions for XCTest are available in the XCTestAssertions. H file, but again, a brief summary is provided here
// XCTAssert(expression,format…) XCTAssertTrue(expression,format…) XCTAssertFalse(expression,format…) XCTAssertEqual(expression1, expression2,format…) XCTAssertNotEqual(expression1, expression2,format…) XCTAssertEqualWithAccuracy(expression1, expression2, accuracy,format…) XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy,format…) XCTAssertNil(expression,format…) XCTAssertNotNil(expression,format…)
For example
- (void)testExample {// Set the variable and set the expected value NSUIntegera =10; NSUIntegerb =15; NSUIntegerexpected =24; NSUIntegeractual = [selfadd:a b:b]; XCTAssertEqual(expected, actual,@”add method error! “) ); }-(NSUInteger)add:(NSUInteger)a b:(NSUInteger)b{returna+b; }
You can also see that a test case is written in a more formal way: 1: defines variables and expectations, 2: executes methods to get actual values, and 3: asserts
Of course, there are special cases where using these assertions directly makes the code look bloated, so you can wrap them up a bit:
#define ml_ssertTrue(expr)XCTAssertTrue(expr) “)#define ml_assertFalse(expr)XCTAssertFalse(expr), @””)#define ml_assertNil(a1)XCTAssertNil((a1), @””)#define ml_assertNotNil(a1)XCTAssertNotNil((a1), @””)#define ml_assertEqual(a1, a2)XCTAssertEqual((a1),(a2), @””)#define ml_assertEqualObjects(a1, a2)XCTAssertEqualObjects((a1),(a2), @””)#define ml_assertNotEqual(a1, a2)XCTAssertNotEqual((a1),(a2), @””)#define ml_assertNotEqualObjects(a1, a2)XCTAssertNotEqualObjects((a1),(a2), @””)#define ml_assertAccuracy(a1, a2, acc)XCTAssertEqualWithAccuracy((a1),(a2),(acc))
Simple and practical preparation
795875-a207ce29f12fa7f2.png.jpeg
If you created a project before, you can create it by yourself:
795875-9e3ebd787a699757.png.jpeg
So if I go into this class,
SetUp is executed before each test method call,
TearDown is executed after each test method call.
TestExample is the test method, no different from our new one.
However, the test method must be in testXXX format and cannot have parameters, otherwise it will not be identified as a test method. Test methods are executed in lexicographical order.
Unit tests by pressing Command + U, which is all tests.
795875-362afa43ea505bb6.png.jpeg
Simple use of unit tests
Create a Person class with a test1 method in it
2, by the way, check the test unit button on the right, in order to test the data of the.m file
795875-192f3a273594f9e7.png.jpeg
If the project is small, you can test it directly in the tests method that the project just created. If the project is large, you can create a separate tests method, such as PersonTets:
795875-89721ddcf3d48789.png.jpeg
Create a test method: testPerson:
795875-cbeeb6ba7a19c6ef.png.jpeg
Test methods must be in testXXX format and must have no parameters, otherwise they will not be identified as test methods
If there is no diamond in front, you can Build it
5, click the small diamond icon, green appears to indicate success:
795875-fdefc42918aaccb4.png.jpeg
XCTAssert(<#expression,… #>), or some other assertion method to test the result;
Unit tests of methods that reference the AFN framework
1, Test methods with network requests, for example:
795875-12be468144d6e31a.png.jpeg
2. Click on the small diamond to find the AFN frame as before [Person test2] :
795875-d4d646284ee3dd06.png.jpeg
3. Some configuration needs to be done
Target(App) -build setting-header Search Paths
795875-27159a355bc9a14f.png.jpeg
3.2. Paste it into Target(UnitTests) -build setting-header-search Paths.
Copy Target(App) -build setting-user-defined – PODS_ROOT to Target(App).
3.4. Create a PODS_ROOT file at Target(unittests-build setting-user-defined).
795875-601bbddba0354ed1.png.jpeg
4. OK!
Three,
Expectations are actually asynchronous tests. When testing an asynchronous method, because the results are not immediately available, we can set an expectation that has a time limit and fulfill the expectation.
For example,
- (void)testAsynExample {// 1Exp = [selfexpectationWithDescription: @ “here can be the cause of the error description operation…”] ; NSOperationQueuequeue = [[NSOperationQueuealloc]init]; [queue addOperationWithBlock:^{queue addOperationWithBlock:^{queue addOperationWithBlock:^{queue addOperationWithBlock:^{queue addOperationWithBlock:^{queue addOperationWithBlock:^{queue addOperationWithBlock:^{queue addOperationWithBlock:^{ XCTAssertEqual(@”a”,@”a”);//2. If the assert is no problem, declare test fulfill [exp fulfill];}]; //3. Set the number of seconds after the delay, If there is no meet the test condition is error [selfwaitForExpectationsWithTimeout: 3 handler: ^ (NSError * _Nullable error) {if (error) {NSLog (@ “Timeout error: %@”, error); } }]; }
This test must have passed because setting the delay to 3 seconds and the asynchronous operation to 2 seconds would have produced a correct result and declared the condition satisfied [EXP fulfill], but when we changed the delay to 1 second, the test case would not have succeeded. The reason for the error is expectationWithDescription: @ “here can be the cause of the error description operation…
In addition to using expectationWithDescription asynchronous tests
Outside, you can also use expectationForPredicate and expectationForNotification
.
Master expectationWithDescription
Can, the latter two only understand
The following example uses expectationForPredicate test methods. The code comes from AFNetworking to test the background Mageforstate method
- (void)testThatBackgroundImageChanges { XCTAssertNil([self.buttonbackgroundImageForState:UIControlStateNormal]); NSPredicatepredicate = [NSPredicatepredicateWithBlock:^BOOL(UIButton_Nonnull button,NSDictionary * _Nullable bindings) {return[button backgroundImageForState:UIControlStateNormal] ! =nil; }]; [selfexpectationForPredicate:predicate evaluatedWithObject:self.buttonhandler:nil]; [selfwaitForExpectationsWithTimeout:20handler:nil]; }
Using predicate calculation, button gets the backgroundImage correctly. If it gets the backgroundImage correctly within 20 seconds, it passes the test, otherwise it fails.
ExpectationForNotification method, the method to monitor a notice, if correctly received notification within the given time is the test pass.
- (void) testAsynExample1 {[selfexpectationForNotification: @ “listening to inform the name of the XXX”) object: nilhandler: nil]; [[NSNotificationCenterdefaultCenter] postNotificationName: @ “listening to inform the name of the XXX” object: nil]; / / set how many seconds delay, if not meet the test condition is error [selfwaitForExpectationsWithTimeout: 3 handler: nil]; }
This example can also use expectationWithDescription implementation, it’s just a lot more code, But this can help you better understand the difference between methods and expectationWithDescription expectationForNotification. Similarly, expectationForPredicate method can also use expectationWithDescription implementation.
FunctestAsynExample1 () {letexpectation = expectationWithDescription letsub (” listening to inform the name of the XXX “) = NSNotificationCenter defaultCenter (.) addObserverForName (” listening to inform the name of the XXX “, object: nil, queue:nil) { (not) ->Voidinexpectation.fulfill() } NSNotificationCenter defaultCenter (.) postNotificationName (” listening to inform the name of the XXX “, object: nil) waitForExpectationsWithTimeout (1, handler:nil)NSNotificationCenter.defaultCenter().removeObserver(sub)}
Iv. Expectation combat:
– (void) testRequest {# create expectations XCTestExpectation expectation = [selfexpectationWithDescription: @ “does not meet expectations”]. AFHTTPSessionManager sessionManager = [AFHTTPSessionManager manager]; sessionManager.responseSerializer= [AFHTTPResponseSerializer serializer]; [our sessionManager GET: @ “www.weather.com.cn/adat/sk/101… “parameters:nilsuccess:^(NSURLSessionDataTask _Nonnull task,id_Nullable responseObject) {NSLog(@”responseObject:%@”, [NSJSONSerializationJSONObjectWithData:responseObject options:1error:nil]); # not nil pass, XCTAssertNotNil(responseObject,@” return error “); } failure:^(NSURLSessionDataTask _Nullable task,NSError* _Nonnull error) {# for nil, XCTAssertNil(error,@” request error “);}]; Set # 5 seconds Timeout [selfwaitForExpectationsWithTimeout: 3.0 handler: ^ (NSError * error) {if (error) {NSLog (@ “Timeout error: %@”, error); } }]; }