@@ -5,7 +5,7 @@ import SwiftHamcrest
55open class Feature : XCTestCase {
66 let id : String = UUID ( ) . uuidString
77 open var currentScenario : Scenario ? = nil
8-
8+
99 open func title( ) -> String {
1010 fatalError ( " Set feature title " )
1111 }
@@ -16,9 +16,23 @@ open class Feature: XCTestCase {
1616
1717 /// our lifecycle starts after xctest is ending
1818 public override func tearDown( ) async throws {
19- try await run ( )
19+ var errorFromRun : Error ?
20+ do {
21+ try await run ( )
22+ } catch {
23+ errorFromRun = error
24+ }
2025 self . currentScenario = nil
21- try await super. tearDown ( )
26+ var superTeardownError : Error ?
27+ do {
28+ try await super. tearDown ( )
29+ } catch {
30+ superTeardownError = error
31+ }
32+
33+ if let errorToThrow = errorFromRun ?? superTeardownError {
34+ throw errorToThrow
35+ }
2236 }
2337
2438 public override class func tearDown( ) {
@@ -34,30 +48,36 @@ open class Feature: XCTestCase {
3448 }
3549
3650 func run( ) async throws {
37- // check if we have the scenario
38- if ( currentScenario == nil ) {
39- throw XCTSkip ( """
40- To run the feature you have to setup the scenario for each test case.
41- Usage:
42- func testMyScenario() async throws {
43- scenario = Scenario( " description " )
44- .given // ...
51+ let currentTestMethodName = self . name
52+ if currentScenario == nil {
53+ let rawMethodName = currentTestMethodName. split ( separator: " " ) . last? . dropLast ( ) ?? " yourTestMethod "
54+
55+ let errorMessage = """
56+ ‼️ SCENARIO NOT DEFINED in test method: \( currentTestMethodName)
57+ Each 'func test...()' method within a 'Feature' class must assign a 'Scenario' to 'self.currentScenario'.
58+
59+ Example:
60+ func \( rawMethodName) () async throws {
61+ currentScenario = Scenario( " A brief scenario description " , file: #file, line: #line)
62+ .given( " some precondition " )
63+ .when( " some action " )
64+ .then( " some expected outcome " )
4565 }
46- """ )
66+ """
67+ throw ConfigurationError . missingScenario ( errorMessage)
4768 }
48-
49- if ( currentScenario!. disabled) {
50- throw XCTSkip ( " Scenario [ \( currentScenario!. title) ] is disabled " )
69+ if currentScenario!. disabled {
70+ throw XCTSkip ( " Scenario ' \( currentScenario!. name) ' in test method \( currentTestMethodName) is disabled. " )
5171 }
52-
5372 try await TestConfiguration . setUpInstance ( )
5473
55- if ( currentScenario! is ParameterizedScenario ) {
56- let parameterizedScenario = currentScenario! as! ParameterizedScenario
57- for scenario in parameterizedScenario . build ( ) {
58- try await TestConfiguration . shared ( ) . run ( self , scenario )
74+ if let parameterizedScenario = currentScenario as? ParameterizedScenario {
75+ for scenarioInstance in parameterizedScenario . build ( ) {
76+ scenarioInstance . feature = self
77+ try await TestConfiguration . shared ( ) . run ( self , scenarioInstance )
5978 }
6079 } else {
80+ currentScenario? . feature = self
6181 try await TestConfiguration . shared ( ) . run ( self , currentScenario!)
6282 }
6383 }
0 commit comments