Parameterized-test for Swift. (with XCTest)
SwiftParamTest supports two way of code-style dependent on Swift version.
I recommend this API when you use Swift 5.1 or later.
assert(to: max) {
args(1, 2, expect: 2)
args(2, 1, expect: 2)
args(4, 4, expect: 4)
}
// You can also use tuple (with label).
assert(to: max) {
args((x: 1, y: 2), expect: 2)
args((x: 2, y: 1), expect: 2)
args((x: 4, y: 4), expect: 4)
}
You can use array literal based API that like follwing when you use under Swift 5.1.
assert(to: max, expect: [
args(1, 2, expect: 2),
args(2, 1, expect: 2),
args(4, 4, expect: 4),
])
// You can also use tuple (with label).
assert(to: max, expect: [
args((x: 1, y: 2), expect: 2),
args((x: 2, y: 1), expect: 2),
args((x: 4, y: 4), expect: 4),
])
You can specify row by use the operator ==>
that like following:
// Function Builder API
assert(to: max) {
expect((1, 2) ==> 2)
expect((2, 1) ==> 2)
expect((4, 4) ==> 4)
}
// Legacy API
assert(to: max, expect: [
expect((1, 2) ==> 2),
expect((2, 1) ==> 2),
expect((4, 4) ==> 4),
])
Save or output markdown table when enabled by option (default is all disable).
override func setUp() {
ParameterizedTest.option = ParameterizedTest.Option(
traceTable: .markdown, // output console is enabled
saveTableToAttachement: .markdown // save to attachement is enabled
)
}
override func tearDown() {
ParameterizedTest.option = ParameterizedTest.defaultOption // restore to default
}
func testExample() {
assert(to: max) {
args(1, 2, expect: 2)
args(2, 1, expect: 2)
args(4, 4, expect: 4)
}
// =>
// | Args 0 | Args 1 | Expected |
// |--------|--------|----------|
// | 1 | 2 | 2 |
// | 2 | 1 | 2 |
// | 4 | 4 | 4 |
}
You can also specify column header name too.
func testMarkdownTable() {
assert(to: max, header: ["x", "y"]) { // specify `header`
args(1, 2, expect: 2)
args(2, 1, expect: 2)
args(4, 4, expect: 4)
}
// =>
// | x | y | Expected |
// |---|---|----------|
// | 1 | 2 | 2 |
// | 2 | 1 | 2 |
// | 4 | 4 | 4 |
}
You can also retrive markdown table from result too.
let tableString = assert(to: max, header: ["x", "y"]) {
args(1, 2, expect: 2)
args(2, 1, expect: 2)
args(4, 4, expect: 4)
}.table
print(tableString)
// =>
// | x | y | Expected |
// |---|---|----------|
// | 1 | 2 | 2 |
// | 2 | 1 | 2 |
// | 4 | 4 | 4 |
This is useful for copy and paste the test specification table to PR or others.
Copy .codesnippet
files to the following directory from .xcode directory:
~/Library/Developer/Xcode/UserData/CodeSnippets/
and restart Xcode.
Or run the following command from the root of the repository:
$ make snippets
import SwiftParamTest
import XCTest
class ExampleTests: XCTestCase {
override func setUp() {
ParameterizedTest.option = ParameterizedTest.Option(traceTable: .markdown,
saveTableToAttachement: .markdown)
}
override func tearDown() {
ParameterizedTest.option = ParameterizedTest.defaultOption
}
func testExample() {
// for `function`
assert(to: abs) {
args( 0, expect: 0)
args( 2, expect: 2)
args(-2, expect: 2)
}
// for `operator`
assert(to: +) {
args(1, 1, expect: 2)
args(1, 2, expect: 3)
args(2, 2, expect: 4)
}
// for `instance method` (when receiver is not fixed)
assert(to: String.hasPrefix) {
args("hello", "he", expect: true)
args("hello", "HE", expect: false)
}
// for `instance method` (when receiver is fixed)
assert(to: "hello".hasPrefix) {
args("he", expect: true)
args("HE", expect: false)
}
}
}
SwiftParamTest uses XCTAssertEqual()
and owns error messages by default.
But you can use custom assertion like follows.
// custom assertion
func customAssert<T: Equatable>(_ actual: T, _ expected: T, file: StaticString, line: UInt) {
let message = """
----
Expected: \(expected)
Actual: \(actual)
----
"""
XCTAssert(expected == actual, message, file: file, line: line)
}
// passed by `with` arguments
assert(to: fizzBuzz, with: customAssertion) {
args(1, expect: "Fizz")
// =>
//
// XCTAssertTrue failed -
// ----
// Expected: 1
// Actual: Fizz
// ----
//
}
- Only up to four arguments are supported.
This library use many type inference, therefore type inference are failed in sometime. This may be resolved by explicitly specifying the type information.
for example:
// Legacy API
assert(to: max, expect: [
args(1, 2, expect: 2),
args(2, 1, expect: 2),
args(4, 4, expect: 4),
] as [Row2<Int, Int, Int>]) // `N` in `RowN` is arguments count
// Function Builder API
typealias T = Int
assert(to: max) {
args(1 as T, 2 as T, expect: 2)
args(2 as T, 1 as T, expect: 2)
args(4 as T, 4 as T, expect: 4)
}
pod 'SwiftParamTest'
dependencies: [
.package(url: "https://github.com/YusukeHosonuma/SwiftParamTest.git", .upToNextMajor(from: "2.2.0")),
],
targets: [
.testTarget(
name: "YOUR_TEST_MODULE",
dependencies: [
"SwiftParamTest",
]),
],
Write following to Cartfile.private
.
github "YusukeHosonuma/SwiftParamTest"
Yusuke Hosonuma / [email protected]
SwiftParamTest is available under the MIT license. See the LICENSE file for more info.