// // GMPhotoTest.m // GMPhobos // // Created by Thierry on 16/1/28. // Copyright © 2016年 licong. All rights reserved. // #import #import #import "GMPhobosController.h" #import #import NSString *const MockAppName = @"gengmei_test"; NSString *const MockChannelId = @"AppStore"; NSString *const MockEventId = @"eventId"; NSString *const MockUserId = @"1"; NSString *const MockCityId = @"beijing"; @interface GMPhotoTest : XCTestCase @end ///[NSThread sleepForTimeInterval:0.2]; 因为是异步处理数据,所以需要延迟获取,进行单元测试 @implementation GMPhotoTest - (void)setUp { [super setUp]; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:PhobosGray]; [Phobos clientWithAppName:MockAppName channelId:MockChannelId]; Phobos.sharedClient.serverAPI = @"http://log.test.igengmei.com/log/collect"; Phobos.sharedClient.logEnabled = NO; // 调试打Log模式,看情况开启 Phobos.sharedClient.signingType = PhobosSigningTypeDebug; Phobos.sharedClient.userId = @""; Phobos.sharedClient.getTopController = ^UIViewController * _Nonnull{ return [UIViewController new]; }; } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; [Phobos removeAllPhobosData]; } /** * @brief 测试有用户ID的时候,埋点事件是否正确 * * @since <#version number#> */ - (void)testClientWithUserId{ [self setUp]; [Phobos removeAllPhobosData]; [Phobos.sharedClient setUserId:MockUserId]; [Phobos.sharedClient setCurrentCityId:MockCityId]; [Phobos track:MockEventId]; [NSThread sleepForTimeInterval:0.2]; NSArray *array = [Phobos fetchToBeSendPhobosData]; XCTAssertTrue(array.count == 1, @"array is empty"); NSDictionary *dict = [array.firstObject.data mj_JSONObject]; [self verfiyDict:dict]; XCTAssertTrue([[dict objectForKey:@"user_id"] isEqualToString:MockUserId] , @"Invalid user_id value"); } /** * @brief 测试发送不带参数事件成功 (由之前的实例方法变成类方法) * * @since <#version number#> */ - (void)testTrackEventWithoutAttr{ [Phobos track:MockEventId]; [NSThread sleepForTimeInterval:0.2]; NSArray *array = [Phobos fetchToBeSendPhobosData]; XCTAssertTrue(array.count == 1, @"array is empty"); NSDictionary *dict = [array.firstObject.data mj_JSONObject]; [self verfiyDict:dict]; } /** * @brief 测试发送带参数事件成功 * * @since <#version number#> */ - (void)testTrackEventWithAttr{ NSDictionary *attr = @{@"attr":@"track_attr"}; [Phobos track:MockEventId attributes:attr]; NSArray *array = [Phobos fetchToBeSendPhobosData]; XCTAssertTrue(array.count == 1, @"array is empty"); NSDictionary *dict = [array.firstObject.data mj_JSONObject]; [self verfiyDict:dict]; //验证Param的值是否正确 NSString *value = [[dict valueForKey:@"params"] valueForKey:@"attr"]; XCTAssertTrue([value isEqualToString:@"track_attr"], @"Invalid event attributes"); } /** * @brief 测试立即发送带参数事件成功 * * @since <#version number#> */ - (void)testTrackEventWithAttrAndSendNow{ [Phobos removeAllPhobosData]; // Given NSDictionary *attr = @{@"attr":@"track_attr"}; // When [Phobos track:MockEventId attributes:attr sendNow:YES]; // Then XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 0, @"array should be empty"); } /** * @brief 测试立即发送带参数事件成功,应该把普通埋点也带上 * * @since 1.1.4 */ - (void)testTrackEventWithAttrAndSendNowDonotClearNormal { // Given [Phobos removeAllPhobosData]; NSDictionary *attr = @{@"attr":@"track_attr"}; NSDictionary *sendNowAttr = @{@"attr":@"track_attr_send_now"}; // When [Phobos track:MockEventId attributes:attr sendNow:NO]; // When [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 0, @"array should be empty"); } /** * @brief 测试二次立即发送带参数事件成功,不应该重复发送上一条 * * @since 1.1.4 */ - (void)testTrackEventWithDoubleAttrAndSendNow { [Phobos removeAllPhobosData]; NSDictionary *attr = @{@"attr":@"track_attr"}; [Phobos track:MockEventId attributes:attr sendNow:YES]; // 因为实时埋点是异步删除,所以这个位置暂时延时取数据,待优化 TODO XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 0, @"array shouldn't be empty"); [Phobos track:MockEventId attributes:attr sendNow:YES]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 0, @"array shouldn't be empty"); [Phobos track:MockEventId attributes:attr sendNow:YES]; } /** * @brief 测试不立即发送带参数事件成功后,数据会被清除 * * @since 1.1.4 */ - (void)testTrackEventWithDoubleAttrAndNoSendNow { [Phobos removeAllPhobosData]; NSDictionary *attr = @{@"attr":@"track_attr"}; // [Phobos track:MockEventId attributes:attr]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 1, @"array shouldn't be empty"); // PhobosCacheKey超过50条数据会自动上报,模拟此情况 for (int i = 0; i < 50; i++) { [Phobos track:MockEventId attributes:attr]; } XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 1, @"array shouldn't be empty"); [Phobos track:MockEventId attributes:attr]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 2, @"array shouldn't be empty"); } /** * @brief 测试不实时和实时穿插 1 * * @since 1.1.4 */ - (void)testTrackEventWithSendNowAndNoSendNowOne { [Phobos removeAllPhobosData]; NSDictionary *attr = @{@"attr":@"track_attr"}; NSDictionary *sendNowAttr = @{@"attr":@"track_attr_send_now"}; for (int i = 0; i < 30; i++) { [Phobos track:MockEventId attributes:attr]; } [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 30, @"array shouldn't be empty"); // PhobosCacheKey超过50条数据会自动上报,模拟此情况 [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 0, @"array shouldn't be empty"); [Phobos track:MockEventId attributes:sendNowAttr sendNow:NO]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 1, @"array shouldn't be empty"); [Phobos track:MockEventId attributes:sendNowAttr sendNow:YES]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 0, @"array shouldn't be empty"); [Phobos track:MockEventId attributes:attr]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 1, @"array shouldn't be empty"); } /** * @brief 测试不实时和实时穿插 3 * * @since 1.1.4 */ - (void)testTrackEventWithSendNowAndNoSendNowThree { [Phobos removeAllPhobosData]; NSDictionary *attr = @{@"attr":@"track_attr"}; // [Phobos track:MockEventId attributes:attr]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 1, @"array shouldn't be empty"); // PhobosCacheKey超过50条数据会自动上报,模拟此情况 for (int i = 0; i < 50; i++) { [Phobos track:MockEventId attributes:attr]; } XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 1, @"array shouldn't be empty"); [Phobos track:MockEventId attributes:attr]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 2, @"array shouldn't be empty"); } - (void)verfiyDict:(NSDictionary *)dict{ NSArray *keys = [dict allKeys]; XCTAssertTrue([keys containsObject:@"type"], @"Missing type"); XCTAssertTrue([keys containsObject:@"app"], @"Missing app"); XCTAssertTrue([keys containsObject:@"version"], @"Missing version"); XCTAssertTrue([keys containsObject:@"device"], @"Missing device"); XCTAssertTrue([keys containsObject:@"user_id"], @"Missing user_id"); XCTAssertTrue([keys containsObject:@"create_at"], @"Missing create_at"); XCTAssertTrue([keys containsObject:@"params"], @"Missing params"); XCTAssertTrue([keys containsObject:@"absolute_time"], @"Missing absolute_time"); XCTAssertTrue([keys containsObject:@"create_at_millis"], @"Missing create_at_millis"); XCTAssertTrue([keys containsObject:@"nano_time"], @"Missing nano_time"); XCTAssertTrue([[dict[@"params"] allKeys] containsObject:@"referrer_link"],@"Missing referrer_link"); XCTAssertTrue((dict[@"params"][@"referrer_link"] != nil || ![dict[@"params"][@"referrer_link"] isEqual:@{}] || dict[@"params"][@"referrer_link"] != NULL), @"referrer_link至少使用默认的[]"); } - (void)testCatchNullInAttributes { Phobos.sharedClient.captureNullExpection = ^(NSString *eventId, NSDictionary *att) { NSCAssert([att[@"bussness_id"] integerValue] == 1244, @"testCatchNullInAttributes 没有捕获到有用信息"); }; NSDictionary *attributes = @{@"key": [NSNull null], @"bussness_id": @1244}; [Phobos track:@"testCatchNullInAttributes" attributes:attributes]; } // 某种情况下没有先走 onPageStart,只走了OnPageEnd,此时数据应该完整,某个key对应的value可以是空 - (void)testOnPageStart { GMPhobosController *controller = [GMPhobosController new]; controller.pageName = @"pageNameTest"; controller.businessId = @"businessIdTest"; controller.referrerId = @"rreferrerIdTest"; [controller viewWillAppear:true]; XCTAssertTrue(controller.inTime.integerValue > 0, "inTime 应该有值"); } // 某种情况下没有先走 onPageStart,只走了OnPageEnd,此时数据应该完整,某个key对应的value可以是空 - (void)testOnPageEnd { GMPhobosController *controller = [GMPhobosController new]; controller.isPush = @"1"; controller.pageName = @"pageNameTest"; controller.businessId = @"businessIdTest"; controller.referrerId = @"rreferrerIdTest"; [controller viewWillAppear:true]; [controller viewWillDisappear:true]; [self paramUnNilCheck]; NSArray *array = [Phobos fetchToBeSendPhobosData]; XCTAssertTrue(array.count != 0, @"PhobosCacheKey 下面应该有数据"); NSDictionary *dic = [array.firstObject.data mj_JSONObject][@"params"]; XCTAssertTrue([dic[@"referrer_id"] isEqualToString:@"rreferrerIdTest"], @"referrerId至少使用默认的空字符串"); } - (void)paramUnNilCheck { NSArray *array = [Phobos fetchToBeSendPhobosData]; XCTAssertTrue(array.count != 0, @"PhobosCacheKey 下面应该有数据"); NSDictionary *dic = [array.firstObject.data mj_JSONObject][@"params"]; XCTAssertTrue(dic[@"page_name"] != nil, @"page_name至少使用默认的空字符串"); XCTAssertTrue([dic[@"referer"] integerValue] >= 0, @"referer至少使用默认的空字符串"); XCTAssertTrue(dic[@"business_id"] != nil, @"business_id至少使用默认的空字符串"); XCTAssertTrue(dic[@"in_time_millis"] != nil, @"in_time_millis至少使用默认的空字符串"); XCTAssertTrue(dic[@"out_time_millis"] != nil, @"out_time_millis至少使用默认的空字符串"); XCTAssertTrue((dic[@"referrer_link"] != nil || ![dic[@"referrer_link"] isEqual:@{}] || dic[@"referrer_link"] != NULL), @"referrer_link至少使用默认的[]"); } #pragma mark - 属性test - (void)testNeedLogPV { UIViewController *controller = [UIViewController new]; XCTAssertTrue(controller.needLogPV, @"needLogPV应该默认为YES"); controller.needLogPV = NO; XCTAssertFalse(controller.needLogPV, @"needLogPV赋值为NO时应该NO"); } // 该单元测试暂时不用,因为过滤代码暂时不用,所以不需要跑通 /* - (void)testCheckPVPhobos { [Phobos removeAllPhobosData]; NSString *inDate = [PhobosUtil currentTime]; [NSThread sleepForTimeInterval:1];//模拟浏览页面,让out和in时间相差1s NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; [dict setObject:[PhobosUtil currentTime] forKey:@"out"]; [dict setObject:inDate forKey:@"in"]; [dict setObject:@"test" forKey:@"page_name"]; [dict setObject:@"" forKey:@"business_id"]; [dict setObject:@"" forKey:@"referrer"]; [dict setObject:@(0) forKey:@"fake"]; [dict setObject:@"" forKey:@"referrer_id"]; [dict setObject:@"" forKey:@"extra_param"]; [dict setObject:@"" forKey:@"referrer_tab_name"]; [dict setObject:@(0) forKey:@"is_push"]; [Phobos track:@"page_view" attributes:dict]; NSArray *array = [Phobos fetchToBeSendPhobosData]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue(array.count == 1, @"PhobosCacheKey 下面应该有数据"); [Phobos track:@"page_view" attributes:dict]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 2, @"PhobosCacheKey 上条数据不应该发送"); [NSThread sleepForTimeInterval:2];//模拟浏览页面,让第二次浏览和上一次时间相差2s [dict setObject:[PhobosUtil currentTime] forKey:@"in"]; [NSThread sleepForTimeInterval:1];//模拟浏览页面,让out和in时间相差1s [dict setObject:[PhobosUtil currentTime] forKey:@"out"]; [Phobos track:@"page_view" attributes:dict]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount]== 2, @"PhobosCacheKey 上条数据应该发送"); [Phobos track:@"page_view" attributes:dict]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 2, @"PhobosCacheKey 上条数据不应该发送"); [Phobos track:@"test" attributes:dict]; [NSThread sleepForTimeInterval:0.2]; XCTAssertTrue([Phobos fetchToBeSendPhobosDataCount] == 3, @"PhobosCacheKey 上条数据应该发送"); } */ #pragma mark - 其它方法test - (void)testVisibleController { } @end