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:

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:

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:

  1. 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")
    }
    
  2. 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)
    }