@@ -5,7 +5,7 @@ import SwiftHamcrest
5
5
open class Feature : XCTestCase {
6
6
let id : String = UUID ( ) . uuidString
7
7
open var currentScenario : Scenario ? = nil
8
-
8
+
9
9
open func title( ) -> String {
10
10
fatalError ( " Set feature title " )
11
11
}
@@ -16,9 +16,23 @@ open class Feature: XCTestCase {
16
16
17
17
/// our lifecycle starts after xctest is ending
18
18
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
+ }
20
25
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
+ }
22
36
}
23
37
24
38
public override class func tearDown( ) {
@@ -34,30 +48,36 @@ open class Feature: XCTestCase {
34
48
}
35
49
36
50
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 " )
45
65
}
46
- """ )
66
+ """
67
+ throw ConfigurationError . missingScenario ( errorMessage)
47
68
}
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. " )
51
71
}
52
-
53
72
try await TestConfiguration . setUpInstance ( )
54
73
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 )
59
78
}
60
79
} else {
80
+ currentScenario? . feature = self
61
81
try await TestConfiguration . shared ( ) . run ( self , currentScenario!)
62
82
}
63
83
}
0 commit comments