函数
func csv<T>(String, Rune, Rune, Rune, Option<Rune>, Option<Array<String>>, Array<UInt64>, Array<UInt64>, Bool) where T <: Serializable<T>
public func csv<T>(
fileName: String,
delimiter!: Rune = ',',
quoteChar!: Rune = '"',
escapeChar!: Rune = '"',
commentChar!: Option<Rune> = None,
header!: Option<Array<String>> = None,
skipRows!: Array<UInt64> = [],
skipColumns!: Array<UInt64> = [],
skipEmptyLines!: Bool = false
): CsvStrategy<T> where T <: Serializable<T>
功能:该函数可从 csv 文件中读取类型 T 的数据值,其中 T 必须可被序列化。该函数的返回值是参数化测试的一种参数源。
参数:
- fileName: String - CSV 格式的文件地址,可为相对地址,不限制后缀名。
- delimiter!: Rune - 一行中作为元素分隔符的符号。默认值为
,
(逗号)。 - quoteChar!: Rune - 括住元素的符号。默认值为
"
(双引号)。 - escapeChar :转义括住元素的符号。默认值为
"
(双引号)。 - escapeChar!: Rune - 注释符号,跳过一行。必须在一行的最左侧。默认值是
None
(不存在注释符号)。 - header!: Option<Array<String>> - 提供一种方式覆盖第一行。
- 当 header 被指定时,文件的第一行将被作为数据行,指定的 header 将被使用。
- 当 header 被指定,同时第一行通过指定
skipRows
被跳过时,第一行将被忽略,指定的 header 将被使用。 - 当 header 未被指定时,即值为
None
时,文件的第一行将被作为表头。此为默认值。
- skipRows!: Array<UInt64> - 指定需被跳过的数据行号,行号从 0 开始。默认值为空数组
[]
。 - skipColumns!: Array<UInt64> - 指定需被跳过的数据列号,列号从 0 开始。当有数据列被跳过,并且用户指定了自定义的 header 时,该 header 将按照跳过后的实际数据列对应。默认值为空数据
[]
。 - skipEmptyLines!: Bool - 指定是否需要跳过空行。默认值为
false
。
返回值:
- CsvStrategy<T> 对象,T 可被序列化,数据值从 CSV 文件中读取。
func json<T>(String) where T <: Serializable<T>
public func json<T>(fileName: String): JsonStrategy<T> where T <: Serializable<T>
功能:该函数可从 JSON 文件中读取类型 T 的数据值,其中 T 必须可被序列化。该函数的返回值是参数化测试的一种参数源。
参数:
- fileName: String - JSON 格式的文件地址,可为相对地址。
返回值:
- JsonStrategy<T> - T 可被序列化,数据值从 JSON 文件中读取。
示例:
@Test[user in json("users.json")]
func test_user_age(user: User): Unit {
@Expect(user.age, 100)
}
json 文件示例:
[
{
"age": 100
},
{
"age": 100
}
]
创建一种被用作测试函数参数的类,该类实现接口 Serializable 。
class User <: Serializable<User> {
User(let age: Int64) {}
public func serialize(): DataModel {
DataModelStruct()
.add(Field("age", DataModelInt(age)))
}
public static func deserialize(dm: DataModel): User {
if (let Some(dms) <- dm as DataModelStruct) {
if (let Some(age) <- dms.get("age") as DataModelInt) {
return User(age.getValue())
}
}
throw Exception("Can't deserialize user.")
}
}
任何实现 Serializable 的类型都可以用作参数类型,包括默认值:
@Test[user in json("numbers.json")]
func test(value: Int64)
@Test[user in json("names.json")]
func test(name: String)
func random<T>() where T <: Arbitrary<T>
public func random<T>(): RandomDataStrategy<T> where T <: Arbitrary<T>
功能:该函数生成 T 类型的随机数据,其中 T 必须实现接口 Arbitrary<T> 。该函数的返回值是参数化测试的一种参数源。
返回值:
- Arbitrary<T> - 使用随机数据生成的 RandomDataStrategy 接口的实例。
func tsv<T>(String, Rune, Rune, Option<Rune>, Option<Array<String>>, Array<UInt64>, Array<UInt64>, Bool) where T <: Serializable<T>
public func tsv<T>(
fileName: String,
quoteChar!: Rune = '"',
escapeChar!: Rune = '"',
commentChar!: Option<Rune> = None,
header!: Option<Array<String>> = None,
skipRows!: Array<UInt64> = [],
skipColumns!: Array<UInt64> = [],
skipEmptyLines!: Bool = false
): CsvStrategy<T> where T <: Serializable<T>
功能:该函数可从 tsv 文件中读取类型 T 的数据值,其中 T 必须可被序列化。该函数的返回值是参数化测试的一种参数源。
参数:
- fileName: String - TSV 格式的文件地址,可为相对地址,不限制后缀名。
- quoteChar!: Rune - 括住元素的符号。默认值为
"
(双引号)。 - escapeChar!: Rune - 转义括住元素的符号。默认值为
"
(双引号)。 - commentChar!: Option<Rune> - 注释符号,跳过一行。必须在一行的最左侧。默认值是
None
(不存在注释符号)。 - header!: Option<Array<String>> - 提供一种方式覆盖第一行。
- 当 header 被指定时,文件的第一行将被作为数据行,指定的 header 将被使用。
- 当 header 被指定,同时第一行通过指定
skipRows
被跳过时,第一行将被忽略,指定的 header 将被使用。 - 当 header 未被指定时,即值为
None
时,文件的第一行(跳过后的实际数据)将被作为表头。此为默认值。
- skipRows!: Array<UInt64> - 指定需被跳过的数据行号,行号从 0 开始。默认值为空数组
[]
。 - skipColumns!: Array<UInt64> - 指定需被跳过的数据列号,列号从 0 开始。当有数据列被跳过,并且用户指定了自定义的 header 时,该 header 将按照跳过后的实际数据列对应。默认值为空数据
[]
。 - skipEmptyLines!: Bool - 指定是否需要跳过空行。默认值为
false
。
返回值:
- CsvStrategy<T> - T 可被序列化,数据值从 TSV 文件中读取。
示例:
在单元测试中,可以通过传入 csv/tsv 文件地址进行参数化测试。
CSV 文件每一行的数据应当被表示成一个 Serializable<T> 对象,它的成员名是文件每一列头的值,成员值是 DataModelString 类型的对应列号上的值。
举例来说,有一个 testdata.csv
文件,具有如下内容:
username,age
Alex Great,21
Donald Sweet,28
有几种方式可以序列化上述数据:
具体示例为:
import std.collection.HashMap
import std.unittest.*
import std.unittest.testmacro.*
@Test[user in csv("testdata.csv")]
func testUser(user: HashMap<String, String>) {
@Assert(user["username"] == "Alex Great" || user["username"] == "Donald Sweet")
@Assert(user["age"] == "21" || user["age"] == "28")
}
- 将数据表示为 Serializable<T> 类型数据,其 String 类型的数据可被反序列化为 DataModelStruct 格式对象。
具体示例为:
import serialization.serialization.*
import std.convert.*
import std.unittest.*
import std.unittest.testmacro.*
public class User <: Serializable<User> {
public User(let name: String, let age: UInt32) {}
public func serialize(): DataModel {
let dms = DataModelStruct()
dms.add(Field("username", DataModelString(name)))
dms.add(Field("age", DataModelString(age.toString())))
return dms
}
static public func deserialize(dm: DataModel): User {
var data: DataModelStruct = match (dm) {
case dms: DataModelStruct => dms
case _ => throw DataModelException("this data is not DataModelStruct")
}
let name = String.deserialize(data.get("username"))
let age = String.deserialize(data.get("age"))
return User(name, UInt32.parse(age))
}
}
@Test[user in csv("testdata.csv")]
func testUser(user: User) {
@Assert(user.name == "Alex Great" || user.name == "Donald Sweet")
@Assert(user.age == 21 || user.age == 28)
}