Function
func assertCaughtUnexpectedE(String,String,String)
public func assertCaughtUnexpectedE(
message: String,
expectedExceptions: String,
caughtException: String
): Nothing
Description: Records information and throws an exception if a caught exception does not meet the expectation.
Parameters:
- message: String: message displayed when the caught exception does not meet the expectation
- expectedExceptions: String: expected exception to be caught
- caughtException: String: exception that is actually caught
func assertEqual<T>(String, String, T, T): Unit where T <: Equatable<T>
public func assertEqual<T>(leftStr: String, rightStr: String, expected: T, actual: T): Unit where T <: Equatable<T>
Description: Checks whether the expected
and actual
values are equal. Throws an exception if they are not.
Parameters:
- leftStr: String: string of the expected expression
- rightStr: String: string of the actual expression
- expected: T: expected value
- actual: T: actual value
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>
Description: Reads the data value of type T from a CSV file, where T must be serializable. The returned value is a parameter source for parameterized tests.
Parameters:
- fileName: String: Specifies the file path of the CSV file. It can be a relative path and has no restrictions on the file name extension.
- delimiter!: Rune: symbol used as the delimiter between elements in a row. The default value is comma (
,
). - quoteChar!: Rune: symbol used to enclose elements. The default value is double quotes (
"
). - escapeChar!: Rune: symbol that escapes the enclosed element. The default value is
"
(double quotes). - commentChar!: Option<Rune>: comment symbol for skipping a line. It must be at the leftmost position of a row. The default value is
None
(without comment symbol). - header!: Option<Array<String>>: Provides a way to override the first row.
- When the header is specified, the first row of the file is used as a data row, and the specified header is used.
- When the header is specified and the first row is skipped through
skipRows
, the first row is ignored and the specified header is used. - When the header is not specified (that is,
None
), the first row of the file is used as the header. This is the default value.
- skipRows!: Array<UInt64>: Specifies which rows to skip, with row numbers starting from 0. The default value is an empty array
[]
. - skipColumns!: Array<UInt64>: Specifies which columns to skip, with column numbers starting from 0. If data columns are skipped and a custom header is provided, the header matches with the actual remaining columns. The default value is empty
[]
. - skipEmptyLines!: Bool: Specifies whether to skip empty lines. The default value is
false
.
Returns:
- an object of type CsvStrategy<T>, where T is serializable, and the data is read from the CSV file.
func defaultConfiguration()
public func defaultConfiguration(): Configuration
Description: Generates default configuration information.
Returns:
- Configuration: configuration information
func entryMain(TestPackage)
public func entryMain(testPackage: TestPackage): Int64
Description: Specifies an entry function for the framework to execute test cases, for use by cjc --test
.
Parameters:
- testPackage: TestPackage: test package object
Returns:
- Int64: execution result
func expectCaughtUnexpectedE(String,String,String)
public func expectCaughtUnexpectedE(
message: String,
expectedExceptions: String,
caughtException: String
): Unit
Description: Records information without throwing any exception if a caught exception does not meet the expectation.
Parameters:
- message: String: message displayed when the caught exception does not meet the expectation
- expectedExceptions: String: expected exception to be caught
- caughtException: String: exception that is actually caught
func expectEqual<T>(String, String, T, T): Unit where T <: Equatable<T>
public func expectEqual<T>(leftStr: String, rightStr: String, expected: T, actual: T): Unit where T <: Equatable<T>
Description: Checks whether the expected
and actual
values are equal. Records the comparison result without throwing any exception.
Parameters:
- leftStr: String: string of the expected expression
- rightStr: String: string of the actual expression
- expected: T: expected value
- actual: T: actual value
func fail(String)
public func fail(message: String): Nothing
Description: Makes the case fail and throws an exception.
Parameters:
- message: String: failure information
func failExpect(String)
public func failExpect(message: String): Unit
Description: Makes the case fail and records information without throwing any exception.
Parameters:
- message: String: failure information
func json<T>(String) where T <: Serializable<T>
public func json<T>(fileName: String): JsonStrategy<T> where T <: Serializable<T>
Description: Reads the data value of type T from a JSON file, where T must be serializable. The returned value is a parameter source for parameterized tests.
Parameters:
- fileName: String: file path of the JSON file. It can be a relative path.
Returns:
- JsonStrategy<T>, where T is serializable, and the data is read from the JSON file.
Example:
@Test[user in json("users.json")]
func test_user_age(user: User): Unit {
@Expect(user.age, 100)
}
The following is an example json file:
[
{
"age": 100
},
{
"age": 100
}
]
Create a class that is used to test function parameters. This class implements the Serializable interface.
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.")
}
}
Any type that implements Serializable can be used as a parameter type, including the default type.
@Test[user in json("numbers.json")]
func test(value: Int64)
@Test[user in json("names.json")]
func test(name: String)
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>
Description: Reads the data value of type T from a TSV file, where T must be serializable. The returned value is a parameter source for parameterized tests.
Parameters:
- fileName: String: file path of the TSV file. It can be a relative path, and has no restrictions on the file name extension.
- quoteChar!: Rune: symbol used to enclose elements. The default value is double quotes (
"
). - escapeChar!: Rune: symbol used to escape enclosed elements. The default value is double quotes (
"
). - commentChar!: Option<Rune>: comment symbol used to skip a row. It must be at the very beginning of a row. The default value is
None
(no comment symbol). - header!: Option<Array<String>>: Provides a way to override the first row.
- When the header is specified, the first row of the file is used as a data row, and the specified header is used.
- When the header is specified and the first row is skipped through
skipRows
, the first row is ignored and the specified header is used. - When the header is not specified (that is,
None
), the first row (the actual data remaining) of the file is used as the header. This is the default value.
- skipRows!: Array<UInt64>: Specifies which rows to skip, with row numbers starting from 0. The default value is an empty array
[]
. - skipColumns!: Array<UInt64>: Specifies which columns to skip, with column numbers starting from 0. If data columns are skipped and a custom header is provided, the header matches with the actual remaining data columns. The default value is empty
[]
. - skipEmptyLines!: Bool: Specifies whether to skip empty lines. The default value is
false
.
Returns:
- CsvStrategy<T>, where T is serializable, and the data is read from the TSV file.
Example:
In unit testing, you can conduct parameterized tests by passing the CSV/TSV file path.
The data in each row of the CSV file is represented as a Serializable<T> object. The member names correspond to the column headers, and the member values are the values in the corresponding columns of the DataModelString type.
For example, consider a testdata.csv
file with the following content:
username,age
Alex Great,21
Donald Sweet,28
There are several ways to serialize this data:
-
Represent the data as HashMap<String, String>.
An example is as follows:
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") }
-
Represent the data as Serializable<T> data. Data of the String type can be deserialized into a DataModelStruct object.
An example is as follows:
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)
}