admin管理员组文章数量:1122826
I use the Swift Testing
framework in my iOS
project. Imagine I have a function I need to test:
func isEven(_ num: Int) -> Bool
I’m working with parameterized tests, where multiple test cases are evaluated using the same test function. I’d like Xcode to show the exact line of the failing test case, similar to how Issue.record works.
Here’s my current setup:
@Test(arguments: testCases)
func test() {
let output = isEven(testCase.input)
#expect(output == testCase.expectedOutput) // I need to somehow pass file and line here
}
static var testCases: [TestCase<Int, Bool>] = [
(2, true),
(0, true),
(3, false),
(5, true) // Incorrect expected value for demonstration
]
struct TestCase<Input, Output> {
public let input: Input
public let expectedOutput: Output
public let file: StaticString
public let line: UInt
public init(input: Input, expectedOutput: Output, file: StaticString = #file, line: UInt = #line) {
self.input = input
self.expectedOutput = expectedOutput
self.file = file
self.line = line
}
}
What I’m Trying to Achieve
- Xcode to report the exact file and line where the test case failed (In case of parametrised tests).
Question
- Is it possible to pass file and line to #expect in the Swift Testing framework?
- If not, is there an alternative way to achieve the desired behavior? Any guidance would be appreciated!
I use the Swift Testing
framework in my iOS
project. Imagine I have a function I need to test:
func isEven(_ num: Int) -> Bool
I’m working with parameterized tests, where multiple test cases are evaluated using the same test function. I’d like Xcode to show the exact line of the failing test case, similar to how Issue.record works.
Here’s my current setup:
@Test(arguments: testCases)
func test() {
let output = isEven(testCase.input)
#expect(output == testCase.expectedOutput) // I need to somehow pass file and line here
}
static var testCases: [TestCase<Int, Bool>] = [
(2, true),
(0, true),
(3, false),
(5, true) // Incorrect expected value for demonstration
]
struct TestCase<Input, Output> {
public let input: Input
public let expectedOutput: Output
public let file: StaticString
public let line: UInt
public init(input: Input, expectedOutput: Output, file: StaticString = #file, line: UInt = #line) {
self.input = input
self.expectedOutput = expectedOutput
self.file = file
self.line = line
}
}
What I’m Trying to Achieve
- Xcode to report the exact file and line where the test case failed (In case of parametrised tests).
Question
- Is it possible to pass file and line to #expect in the Swift Testing framework?
- If not, is there an alternative way to achieve the desired behavior? Any guidance would be appreciated!
2 Answers
Reset to default 4#expect
takes a sourceLocation:
parameter, which defaults to the location of the #expect
macro. You can replace it with your own SourceLocation
.
Your idea of taking in the line number in the initialiser of TestCase
is in the right direction. Instead of the line number, take a SourceLocation
.
@Test(arguments: testCases)
func test(testCase: TestCase<Int, Bool>) {
let output = testCase.input.isMultiple(of: 2)
#expect(output == testCase.expectedOutput, sourceLocation: testCase.sourceLocation)
}
let testCases: [TestCase<Int, Bool>] = [
.init(input: 1, expectedOutput: true), // Xcode will highlight this line
.init(input: 2, expectedOutput: true),
.init(input: 3, expectedOutput: false),
]
public struct TestCase<Input: Sendable, Output: Sendable>: Sendable {
public let input: Input
public let expectedOutput: Output
public let sourceLocation: SourceLocation
public init(input: Input, expectedOutput: Output, sourceLocation: SourceLocation = #_sourceLocation) {
self.input = input
self.expectedOutput = expectedOutput
self.sourceLocation = sourceLocation
}
}
Note the use of the #_sourceLocation
macro to get the current source location. If you don't like seeing underscore APIs for some reason, you can always take the 4 components of a SourceLocation
as parameter instead:
public init(input: Input, expectedOutput: Output, fileID: String = #fileID, filePath: String = #filePath, line: Int = #line, column: Int = #column) {
self.input = input
self.expectedOutput = expectedOutput
self.sourceLocation = SourceLocation(fileID: fileID, filePath: filePath, line: line, column: column)
}
The #expect
can accept a SourceLocation
:
func foo(value: Int, _ sourceLocation: SourceLocation = #_sourceLocation) {
#expect(value == 42, sourceLocation: sourceLocation)
}
@Test
func bar() {
foo(value: 1) // Shows up here: Expectation failed: (value → 1) == 42
}
本文标签: iosCan I Pass file and line to expect in Swift TestingStack Overflow
版权声明:本文标题:ios - Can I Pass file and line to #expect in Swift Testing? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736309628a1934085.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
(5, true)
to be highlighted? – Sweeper Commented Nov 21, 2024 at 15:13