Added FBTestManager class
Summary:It handles mediator and is exposed via strategy to keep connection to test manager daemon alive. Keeping strategy alive, didn't make much sense Reviewed By: mmmulani Differential Revision: D3041458 fb-gh-sync-id: 268cdcc5d79f79d145628a5556a1d0710110398d shipit-source-id: 268cdcc5d79f79d145628a5556a1d0710110398d
This commit is contained in:
Родитель
4d0a616cd3
Коммит
2ddea9bdac
|
@ -162,6 +162,8 @@
|
|||
AAF2D3571C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.m in Sources */ = {isa = PBXBuildFile; fileRef = AAF2D3551C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.m */; };
|
||||
E7A30F0476B173B900000000 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DD70E2976B173B900000000 /* Cocoa.framework */; };
|
||||
E7A30F04A6018C7A00000000 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DD70E29A6018C7A00000000 /* CoreGraphics.framework */; };
|
||||
EE1277571C9329CC00DE52A1 /* FBTestManager.h in Headers */ = {isa = PBXBuildFile; fileRef = EE1277551C9329CC00DE52A1 /* FBTestManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
EE1277581C9329CC00DE52A1 /* FBTestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1277561C9329CC00DE52A1 /* FBTestManager.m */; };
|
||||
EE4F0D3A1C91B7DB00608E89 /* XCTestBootstrap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE4F0D301C91B7DA00608E89 /* XCTestBootstrap.framework */; };
|
||||
EE4F0D701C91B82700608E89 /* FBApplicationDataPackage.h in Headers */ = {isa = PBXBuildFile; fileRef = EE4F0D4A1C91B82700608E89 /* FBApplicationDataPackage.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
EE4F0D711C91B82700608E89 /* FBApplicationDataPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = EE4F0D4B1C91B82700608E89 /* FBApplicationDataPackage.m */; };
|
||||
|
@ -517,6 +519,8 @@
|
|||
AAEA3AA81C90BB73004F8409 /* FBLogSearchTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBLogSearchTests.m; sourceTree = "<group>"; };
|
||||
AAF2D3541C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSimulatorInteraction+Lifecycle.h"; sourceTree = "<group>"; };
|
||||
AAF2D3551C33EA3100434516 /* FBSimulatorInteraction+Lifecycle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FBSimulatorInteraction+Lifecycle.m"; sourceTree = "<group>"; };
|
||||
EE1277551C9329CC00DE52A1 /* FBTestManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBTestManager.h; sourceTree = "<group>"; };
|
||||
EE1277561C9329CC00DE52A1 /* FBTestManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBTestManager.m; sourceTree = "<group>"; };
|
||||
EE4F0D301C91B7DA00608E89 /* XCTestBootstrap.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XCTestBootstrap.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
EE4F0D391C91B7DB00608E89 /* XCTestBootstrapTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XCTestBootstrapTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
EE4F0D4A1C91B82700608E89 /* FBApplicationDataPackage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBApplicationDataPackage.h; sourceTree = "<group>"; };
|
||||
|
@ -1269,6 +1273,8 @@
|
|||
EE4F0D661C91B82700608E89 /* TestManagerMediators */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EE1277551C9329CC00DE52A1 /* FBTestManager.h */,
|
||||
EE1277561C9329CC00DE52A1 /* FBTestManager.m */,
|
||||
EE4F0D671C91B82700608E89 /* FBTestManagerAPIMediator.h */,
|
||||
EE4F0D681C91B82700608E89 /* FBTestManagerAPIMediator.m */,
|
||||
);
|
||||
|
@ -1559,6 +1565,7 @@
|
|||
EE4F0D8B1C91B82700608E89 /* FBRunLoopSpinner.h in Headers */,
|
||||
EE4F0D761C91B82700608E89 /* FBProductBundle+Private.h in Headers */,
|
||||
EE4F0D8D1C91B82700608E89 /* NSError+XCTestBootstrap.h in Headers */,
|
||||
EE1277571C9329CC00DE52A1 /* FBTestManager.h in Headers */,
|
||||
EE4F0D751C91B82700608E89 /* FBFileManager.h in Headers */,
|
||||
EE4F0D7B1C91B82700608E89 /* FBTestConfiguration.h in Headers */,
|
||||
EE4F0D861C91B82700608E89 /* FBXCTestPreparationStrategy.h in Headers */,
|
||||
|
@ -1931,6 +1938,7 @@
|
|||
EE4F0D711C91B82700608E89 /* FBApplicationDataPackage.m in Sources */,
|
||||
EE4F0D8E1C91B82700608E89 /* NSError+XCTestBootstrap.m in Sources */,
|
||||
EE4F0D801C91B82700608E89 /* NSFileManager+FBFileManager.m in Sources */,
|
||||
EE1277581C9329CC00DE52A1 /* FBTestManager.m in Sources */,
|
||||
EE4F0D731C91B82700608E89 /* FBCodeSignCommand.m in Sources */,
|
||||
EE4F0D831C91B82700608E89 /* FBDeviceTestPreparationStrategy.m in Sources */,
|
||||
EE4F0D7C1C91B82700608E89 /* FBTestConfiguration.m in Sources */,
|
||||
|
|
|
@ -49,6 +49,16 @@
|
|||
ReferencedContainer = "container:FBSimulatorControl.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EE4F0D381C91B7DB00608E89"
|
||||
BuildableName = "XCTestBootstrapTests.xctest"
|
||||
BlueprintName = "XCTestBootstrapTests"
|
||||
ReferencedContainer = "container:FBSimulatorControl.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class FBTestManager;
|
||||
@protocol FBXCTestPreparationStrategy;
|
||||
@protocol FBDeviceOperator;
|
||||
|
||||
|
@ -25,8 +26,8 @@
|
|||
@param attributes additional attributes used to start test runner
|
||||
@param environment additional environment used to start test runner
|
||||
@param error If there is an error, upon return contains an NSError object that describes the problem.
|
||||
@return YES if the operation succeeds, otherwise NO.
|
||||
@return testManager if the operation succeeds, otherwise nil.
|
||||
*/
|
||||
- (BOOL)startTestWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error;
|
||||
- (FBTestManager *)startTestManagerWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error;
|
||||
|
||||
@end
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
|
||||
#import "FBDeviceOperator.h"
|
||||
#import "FBProductBundle.h"
|
||||
#import "FBTestManagerAPIMediator.h"
|
||||
#import "FBTestManager.h"
|
||||
#import "FBTestRunnerConfiguration.h"
|
||||
#import "FBXCTestPreparationStrategy.h"
|
||||
#import "NSError+XCTestBootstrap.h"
|
||||
|
||||
@interface FBXCTestRunStrategy () <FBTestManagerDelegate>
|
||||
@interface FBXCTestRunStrategy ()
|
||||
@property (nonatomic, strong) id<FBDeviceOperator> deviceOperator;
|
||||
@property (nonatomic, strong) id<FBXCTestPreparationStrategy> prepareStrategy;
|
||||
@property (nonatomic, strong) FBTestManagerAPIMediator *mediator;
|
||||
@end
|
||||
|
||||
@implementation FBXCTestRunStrategy
|
||||
|
@ -27,14 +26,14 @@
|
|||
return strategy;
|
||||
}
|
||||
|
||||
- (BOOL)startTestWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error
|
||||
- (FBTestManager *)startTestManagerWithAttributes:(NSArray *)attributes environment:(NSDictionary *)environment error:(NSError **)error
|
||||
{
|
||||
NSAssert(self.deviceOperator, @"Device operator is needed to perform meaningful test");
|
||||
NSAssert(self.prepareStrategy, @"Test preparation strategy is needed to perform meaningful test");
|
||||
|
||||
FBTestRunnerConfiguration *configuration = [self.prepareStrategy prepareTestWithDeviceOperator:self.deviceOperator error:error];
|
||||
if (!configuration) {
|
||||
return NO;
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableArray *mAttributes = (configuration.launchArguments ?: @[]).mutableCopy;
|
||||
|
@ -51,7 +50,7 @@
|
|||
arguments:mAttributes.copy
|
||||
environment:mEnvironment.copy
|
||||
error:error]) {
|
||||
return NO;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Get XCTStubApps process Id
|
||||
|
@ -60,31 +59,19 @@
|
|||
if (error) {
|
||||
*error = [NSError XCTestBootstrapErrorWithDescription:@"Failed to determine launched process PID"];
|
||||
}
|
||||
return NO;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Attach WDA
|
||||
self.mediator =
|
||||
[FBTestManagerAPIMediator mediatorWithDevice:self.deviceOperator.dvtDevice
|
||||
testRunnerPID:testRunnerProcessID
|
||||
sessionIdentifier:configuration.sessionIdentifier];
|
||||
self.mediator.delegate = self;
|
||||
[self.mediator connectTestRunnerWithTestManagerDaemon];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - FBTestManagerDelegate
|
||||
|
||||
- (BOOL)testManagerMediator:(FBTestManagerAPIMediator *)mediator launchProcessWithPath:(NSString *)path bundleID:(NSString *)bundleID arguments:(NSArray *)arguments environmentVariables:(NSDictionary *)environment error:(NSError **)error
|
||||
{
|
||||
if (![self.deviceOperator installApplicationWithPath:path error:error]) {
|
||||
return NO;
|
||||
FBTestManager *testManager =
|
||||
[FBTestManager testManagerWithOperator:self.deviceOperator
|
||||
testRunnerPID:testRunnerProcessID
|
||||
sessionIdentifier:configuration.sessionIdentifier
|
||||
];
|
||||
if (![testManager connectWithError:error]) {
|
||||
return nil;
|
||||
}
|
||||
if (![self.deviceOperator launchApplicationWithBundleID:bundleID arguments:arguments environment:environment error:error]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
return testManager;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol FBDeviceOperator;
|
||||
|
||||
/**
|
||||
This class manages connection with testmanager daemon
|
||||
*/
|
||||
@interface FBTestManager : NSObject
|
||||
|
||||
/**
|
||||
Creates and returns a test manager with given paramenters
|
||||
|
||||
@param deviceOperator a device operator used to handle device
|
||||
@param testRunnerPID a process id of test runner (XCTest bundle)
|
||||
@param sessionIdentifier a session identifier of test that should be started
|
||||
@return Prepared FBTestManager
|
||||
*/
|
||||
+ (instancetype)testManagerWithOperator:(id<FBDeviceOperator>)deviceOperator testRunnerPID:(pid_t)testRunnerPID sessionIdentifier:(NSUUID *)sessionIdentifier;
|
||||
|
||||
/**
|
||||
Connects to test manager daemon
|
||||
|
||||
@param error If there is an error, upon return contains an NSError object that describes the problem.
|
||||
@return YES if operation was successful, NO otherwise
|
||||
*/
|
||||
- (BOOL)connectWithError:(NSError **)error;
|
||||
|
||||
@end
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "FBTestManager.h"
|
||||
|
||||
#import "FBDeviceOperator.h"
|
||||
#import "FBTestManagerAPIMediator.h"
|
||||
|
||||
@interface FBTestManager () <FBTestManagerMediatorDelegate>
|
||||
@property (nonatomic, strong) FBTestManagerAPIMediator *mediator;
|
||||
@property (nonatomic, strong) id<FBDeviceOperator> deviceOperator;
|
||||
@end
|
||||
|
||||
@implementation FBTestManager
|
||||
|
||||
+ (instancetype)testManagerWithOperator:(id<FBDeviceOperator>)deviceOperator testRunnerPID:(pid_t)testRunnerPID sessionIdentifier:(NSUUID *)sessionIdentifier
|
||||
{
|
||||
FBTestManager *testManager = [self.class new];
|
||||
testManager.mediator = [FBTestManagerAPIMediator mediatorWithDevice:deviceOperator.dvtDevice testRunnerPID:testRunnerPID sessionIdentifier:sessionIdentifier];
|
||||
testManager.mediator.delegate = testManager;
|
||||
testManager.deviceOperator = deviceOperator;
|
||||
return testManager;
|
||||
}
|
||||
|
||||
- (BOOL)connectWithError:(NSError *__autoreleasing *)error
|
||||
{
|
||||
[self.mediator connectTestRunnerWithTestManagerDaemon];
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - FBTestManagerMediatorDelegate
|
||||
|
||||
- (BOOL)testManagerMediator:(FBTestManagerAPIMediator *)mediator launchProcessWithPath:(NSString *)path bundleID:(NSString *)bundleID arguments:(NSArray *)arguments environmentVariables:(NSDictionary *)environment error:(NSError **)error
|
||||
{
|
||||
if (![self.deviceOperator installApplicationWithPath:path error:error]) {
|
||||
return NO;
|
||||
}
|
||||
if (![self.deviceOperator launchApplicationWithBundleID:bundleID arguments:arguments environment:environment error:error]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
@class DVTAbstractiOSDevice;
|
||||
|
||||
@protocol FBTestManagerDelegate;
|
||||
@protocol FBTestManagerMediatorDelegate;
|
||||
|
||||
/**
|
||||
This is massively simplified reimplementations of Apple's _IDETestManagerAPIMediator class,
|
||||
which is mediator (running on host) between test runner (app that executes XCTest bundle on device) and testmanagerd (running on device), that helps to launch tests.
|
||||
*/
|
||||
@interface FBTestManagerAPIMediator : NSObject
|
||||
@property (nonatomic, weak) id<FBTestManagerDelegate> delegate;
|
||||
@property (nonatomic, weak) id<FBTestManagerMediatorDelegate> delegate;
|
||||
|
||||
/**
|
||||
Creates and returns a mediator with given paramenters
|
||||
|
@ -31,7 +31,7 @@
|
|||
@end
|
||||
|
||||
|
||||
@protocol FBTestManagerDelegate <NSObject>
|
||||
@protocol FBTestManagerMediatorDelegate <NSObject>
|
||||
|
||||
/**
|
||||
Request to launch an application
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
|
@ -15,12 +17,12 @@
|
|||
#import <XCTestBootstrap/FBFileManager.h>
|
||||
#import <XCTestBootstrap/FBProductBundle.h>
|
||||
#import <XCTestBootstrap/FBRunLoopSpinner.h>
|
||||
#import <XCTestBootstrap/FBSimulatorTestPreparationStrategy.h>
|
||||
#import <XCTestBootstrap/FBTestBundle.h>
|
||||
#import <XCTestBootstrap/FBTestConfiguration.h>
|
||||
#import <XCTestBootstrap/FBTestRunnerConfiguration.h>
|
||||
#import <XCTestBootstrap/FBTestManager.h>
|
||||
#import <XCTestBootstrap/FBTestManagerAPIMediator.h>
|
||||
#import <XCTestBootstrap/FBSimulatorTestPreparationStrategy.h>
|
||||
#import <XCTestBootstrap/FBTestRunnerConfiguration.h>
|
||||
#import <XCTestBootstrap/FBXCTestRunStrategy.h>
|
||||
|
||||
#import <XCTestBootstrap/NSError+XCTestBootstrap.h>
|
||||
#import <XCTestBootstrap/NSFileManager+FBFileManager.h>
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
{
|
||||
id prepareTestMock = [OCMockObject niceMockForProtocol:@protocol(FBXCTestPreparationStrategy)];
|
||||
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:nil testPrepareStrategy:prepareTestMock];
|
||||
XCTAssertThrows([strategy startTestWithAttributes:nil environment:nil error:nil]);
|
||||
XCTAssertThrows([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
|
||||
}
|
||||
|
||||
- (void)testTestRunWithRequiredAttributes
|
||||
{
|
||||
id prepareTestMock = [OCMockObject niceMockForProtocol:@protocol(FBXCTestPreparationStrategy)];
|
||||
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:[OCMockObject mockForProtocol:@protocol(FBDeviceOperator)] testPrepareStrategy:prepareTestMock];
|
||||
XCTAssertNoThrow([strategy startTestWithAttributes:nil environment:nil error:nil]);
|
||||
XCTAssertNoThrow([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
|
||||
}
|
||||
|
||||
- (void)testCallToTestPreparationStep
|
||||
|
@ -33,7 +33,7 @@
|
|||
OCMockObject<FBXCTestPreparationStrategy> *prepareTestMock = [OCMockObject mockForProtocol:@protocol(FBXCTestPreparationStrategy)];
|
||||
[[prepareTestMock expect] prepareTestWithDeviceOperator:[OCMArg any] error:[OCMArg anyObjectRef]];
|
||||
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:[OCMockObject mockForProtocol:@protocol(FBDeviceOperator)] testPrepareStrategy:prepareTestMock];
|
||||
XCTAssertNoThrow([strategy startTestWithAttributes:nil environment:nil error:nil]);
|
||||
XCTAssertNoThrow([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
|
||||
[prepareTestMock verify];
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
|||
[[[prepareTestMock stub] andReturn:testConfigurationMock] prepareTestWithDeviceOperator:[OCMArg any] error:[OCMArg anyObjectRef]];
|
||||
|
||||
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:deviceOperatorMock testPrepareStrategy:prepareTestMock];
|
||||
XCTAssertTrue([strategy startTestWithAttributes:@[@4] environment:@{@"A" : @"B"} error:nil]);
|
||||
XCTAssertTrue([strategy startTestManagerWithAttributes:@[@4] environment:@{@"A" : @"B"} error:nil]);
|
||||
[deviceOperatorMock verify];
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
|||
OCMockObject<FBDeviceOperator> *deviceOperatorMock = [OCMockObject mockForProtocol:@protocol(FBDeviceOperator)];
|
||||
id prepareTestMock = [OCMockObject niceMockForProtocol:@protocol(FBXCTestPreparationStrategy)];
|
||||
FBXCTestRunStrategy *strategy = [FBXCTestRunStrategy strategyWithDeviceOperator:deviceOperatorMock testPrepareStrategy:prepareTestMock];
|
||||
XCTAssertFalse([strategy startTestWithAttributes:nil environment:nil error:nil]);
|
||||
XCTAssertFalse([strategy startTestManagerWithAttributes:nil environment:nil error:nil]);
|
||||
[deviceOperatorMock verify];
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче