diff --git a/TestApp/TestAppUITests/Scenario.h b/TestApp/TestAppUITests/Scenario.h index 2ecda67..237f07a 100644 --- a/TestApp/TestAppUITests/Scenario.h +++ b/TestApp/TestAppUITests/Scenario.h @@ -12,5 +12,6 @@ @property (nonatomic) NSString* scenarioName; @property (nonatomic) NSArray* steps; +@property (nonatomic) NSDictionary* environment; @end diff --git a/TestApp/TestAppUITests/ScenarioTestCase.h b/TestApp/TestAppUITests/ScenarioTestCase.h index 2f85cb3..47adc33 100644 --- a/TestApp/TestAppUITests/ScenarioTestCase.h +++ b/TestApp/TestAppUITests/ScenarioTestCase.h @@ -10,14 +10,15 @@ @interface ScenarioTestCase : XCTestCase -+ (void)addScenarioWithName:(NSString* _Nonnull)scenarioName steps:(NSArray* _Nonnull)steps testSuite:(XCTestSuite* _Nonnull)suite; ++ (void)addScenarioWithName:(NSString* _Nonnull)scenarioName steps:(NSArray* _Nonnull)steps environment:(NSDictionary* _Nonnull)environment testSuite:(XCTestSuite* _Nonnull)suite; + (NSArray* _Nonnull)scenarios; + (NSString* _Nonnull)storyfile; @property (nonatomic) NSString* _Nonnull scenarioName; @property (nonatomic) NSArray* _Nonnull steps; +@property (nonatomic) NSDictionary* _Nonnull environment; -- (instancetype _Nonnull)initWithInvocation:(NSInvocation* _Nonnull)invocation name:(NSString* _Nonnull)scenarioName steps:(NSArray* _Nonnull)steps; +- (instancetype _Nonnull)initWithInvocation:(NSInvocation* _Nonnull)invocation name:(NSString* _Nonnull)scenarioName steps:(NSArray* _Nonnull)steps environment:(NSDictionary* _Nonnull)environment; @end diff --git a/TestApp/TestAppUITests/ScenarioTestCase.m b/TestApp/TestAppUITests/ScenarioTestCase.m index d5a46b2..674306d 100644 --- a/TestApp/TestAppUITests/ScenarioTestCase.m +++ b/TestApp/TestAppUITests/ScenarioTestCase.m @@ -22,7 +22,7 @@ + (id)defaultTestSuite XCTestSuite* suite = [[XCTestSuite alloc] initWithName:NSStringFromClass(self)]; for (Scenario* scenario in [self scenarios]) { - [self addScenarioWithName:scenario.scenarioName steps:scenario.steps testSuite:suite]; + [self addScenarioWithName:scenario.scenarioName steps:scenario.steps environment:scenario.environment testSuite:suite]; } return suite; } @@ -32,7 +32,7 @@ + (NSArray*)scenarios return @[]; } -+ (void)addScenarioWithName:(NSString*)scenarioName steps:(NSArray*)steps testSuite:(XCTestSuite*)suite ++ (void)addScenarioWithName:(NSString*)scenarioName steps:(NSArray*)steps environment:(NSDictionary* _Nonnull)environment testSuite:(XCTestSuite*)suite { for (NSInvocation* invocation in [self testInvocations]) { @@ -42,7 +42,7 @@ + (void)addScenarioWithName:(NSString*)scenarioName steps:(NSArray*)steps testSu SEL selector = [self addInstanceMethodForScenario:scenarioName]; invocation.selector = selector; - XCTestCase* test = [[self alloc] initWithInvocation:invocation name:scenarioName steps:steps]; + XCTestCase* test = [[self alloc] initWithInvocation:invocation name:scenarioName steps:steps environment:environment]; [suite addTest:test]; } } @@ -53,12 +53,13 @@ + (NSString*)storyfile return @"OVERRIDE"; } -- (instancetype)initWithInvocation:(NSInvocation*)invocation name:(NSString*)scenarioName steps:(NSArray*)steps +- (instancetype)initWithInvocation:(NSInvocation*)invocation name:(NSString*)scenarioName steps:(NSArray*)steps environment:(NSDictionary*)environment { self = [super initWithInvocation:invocation]; if (self) { _scenarioName = scenarioName; _steps = steps; + _environment = environment; } return self; diff --git a/TestApp/TestAppUITests/SwiftBehaveTest.swift b/TestApp/TestAppUITests/SwiftBehaveTest.swift index 25b4af9..93c7f0a 100644 --- a/TestApp/TestAppUITests/SwiftBehaveTest.swift +++ b/TestApp/TestAppUITests/SwiftBehaveTest.swift @@ -21,6 +21,7 @@ class SwiftBehaveTest: ScenarioTestCase, MappingProvider { continueAfterFailure = true let app = XCUIApplication() app.launchArguments.append("SwiftBehaveTest") + app.launchEnvironment = environment // passing on environment variables (see super class) app.launch() // Wait for launch screen to disappear Thread.sleep(forTimeInterval: 0.5) @@ -51,6 +52,7 @@ class SwiftBehaveTest: ScenarioTestCase, MappingProvider { var currentParams = Array>() var currentTableKeys = Array() // array containing table headers var returnArray = [Any]() + var currentEnvironment = [String:String]() for currentTextLine in storyFileContent { @@ -59,6 +61,14 @@ class SwiftBehaveTest: ScenarioTestCase, MappingProvider { continue } + if currentTextLine.hasPrefix("@Environment(") { + // add an evironment variable + let expression = currentTextLine.dropFirst(13).dropLast(1) + let expressionComponents = expression.components(separatedBy: "=") + currentEnvironment[expressionComponents[0].trimmingCharacters(in: .whitespaces)] = expressionComponents[1].trimmingCharacters(in: .whitespaces) + continue + } + if currentTextLine.hasPrefix("Examples:") { // start parameter table tableInProgress = true @@ -93,13 +103,15 @@ class SwiftBehaveTest: ScenarioTestCase, MappingProvider { // are we currently building a scenario? if currentName.count > 0 { // then finish the current scenario... - let scenarios = finishScenarioOrOutline(name: currentName, steps: currentSteps, params: currentParams) + let scenarios = finishScenarioOrOutline(name: currentName, steps: currentSteps, params: currentParams, environment: currentEnvironment) if tableInProgress { currentTableKeys.removeAll() currentParams.removeAll() tableInProgress = false } currentSteps.removeAll() + currentEnvironment.removeAll() + returnArray.append(contentsOf: scenarios) } @@ -116,7 +128,7 @@ class SwiftBehaveTest: ScenarioTestCase, MappingProvider { // add the last (or single) scenario, if one was found if currentName.count > 0 { // then finish the current scenario(s)... - returnArray.append(contentsOf: finishScenarioOrOutline(name: currentName, steps: currentSteps, params: currentParams)) + returnArray.append(contentsOf: finishScenarioOrOutline(name: currentName, steps: currentSteps, params: currentParams, environment: currentEnvironment)) // no need of clean up, methods ends anyway } @@ -128,13 +140,14 @@ class SwiftBehaveTest: ScenarioTestCase, MappingProvider { /** * Finish a single scenario or a scenario outline (depending on the number of parameters given. */ - fileprivate static func finishScenarioOrOutline(name: String, steps: Array, params: Array>) -> [Any] { + fileprivate static func finishScenarioOrOutline(name: String, steps: Array, params: Array>, environment: Dictionary) -> [Any] { var scenarioArray = [Any]() if params.count == 0 { let scenario = Scenario() scenario.scenarioName = name scenario.steps = steps + scenario.environment = environment print("Adding scenario '\(scenario.scenarioName!)' with \(steps.count) steps.") @@ -145,6 +158,7 @@ class SwiftBehaveTest: ScenarioTestCase, MappingProvider { let scenario = Scenario() scenario.scenarioName = "\(name) \(exampleCount)" scenario.steps = replace(params: paramDict, in: steps) + scenario.environment = environment print("Adding scenario '\(scenario.scenarioName!)' with \(steps.count) steps.")