-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
290 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"author": "Microsoft", | ||
"license": "MIT", | ||
"files": [ | ||
"src/Main.qs", | ||
"src/Operations.qs", | ||
"src/Functions.qs", | ||
"src/Tests.qs" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
/// # Summary | ||
/// Runs a series of named test functions with expected results. | ||
/// | ||
/// # Description | ||
/// Given an array of test names, test functions, and expected results (of the same type), returns `true` | ||
/// if all tests passed, and `false` if any one test failed. | ||
/// Prints the expected and received result for any failed tests. | ||
/// | ||
/// # Input | ||
/// ## test_cases | ||
/// An array of three-arity tuples of the form `(test_name, callable_to_test, expected_result)`. | ||
/// `callable_to_test` will be called and its result will be compared to `expected_result`. | ||
/// | ||
/// # Example | ||
/// ```qsharp | ||
/// function Main() : Unit { | ||
/// TestCases([ | ||
/// ("Should return 42", TestCaseOne, 42), | ||
/// ("Should add one", () -> AddOne(5), 6) | ||
/// ]); | ||
/// } | ||
/// | ||
/// function TestCaseOne() : Int { | ||
/// 42 | ||
/// } | ||
/// | ||
/// function AddOne(x: Int) : Int { | ||
/// x + 1 | ||
/// } | ||
/// ``` | ||
function TestCases<'Result : Eq + Show > (test_cases : (String, () -> 'Result, 'Result)[]) : Bool { | ||
let failed_test_buf = TestCasesSilent(test_cases); | ||
|
||
if Length(failed_test_buf) == 0 { | ||
Message($"{Length(test_cases)} test(s) passed."); | ||
true | ||
} else { | ||
Message($"{Length(failed_test_buf)} tests failed."); | ||
for item in failed_test_buf { | ||
Message($"{item}") | ||
} | ||
false | ||
} | ||
} | ||
|
||
/// # Summary | ||
/// Similar to `Qtest.Functions.TestCases`, but returns test failure info in an array of strings instead of directly messaging to | ||
/// output. Useful if you want to handle your own messaging when writing tests, for CI or similar. | ||
|
||
/// See `Qtest.Functions.TestCases` for more details. | ||
/// | ||
/// # Description | ||
/// Given an array of test names, test functions, and expected results (of the same type), returns an array | ||
/// of strings representing all failed test cases (if any). Strings are of the form "test_name: expected {}, got {}" | ||
/// | ||
/// # Input | ||
/// ## test_cases | ||
/// An array of three-arity tuples of the form `(test_name, callable_to_test, expected_result)`. | ||
/// `callable_to_test` will be called and its result will be compared to `expected_result`. | ||
/// | ||
/// # Example | ||
/// ```qsharp | ||
/// function Main() : Unit { | ||
/// let failure_messages = TestCasesSilent([ | ||
/// ("Should return 42", TestCaseOne, 42), | ||
/// ("Should add one", () -> AddOne(5), 6) | ||
/// ]); | ||
/// Std.Diagnostics.Fact(Length(failure_messages) == 0, "No tests should fail.") | ||
/// } | ||
/// | ||
/// function TestCaseOne() : Int { | ||
/// 42 | ||
/// } | ||
/// | ||
/// function AddOne(x: Int) : Int { | ||
/// x + 1 | ||
/// } | ||
/// ``` | ||
function TestCasesSilent<'Result : Eq + Show > (test_cases : (String, () -> 'Result, 'Result)[]) : String[] { | ||
let num_tests = Length(test_cases); | ||
mutable failed_test_buf = []; | ||
|
||
for (name, case, result) in test_cases { | ||
let (did_pass, message) = TestCase(case, result)!; | ||
if not did_pass { | ||
set failed_test_buf = failed_test_buf + [$"{name}: {message}"]; | ||
} | ||
} | ||
|
||
failed_test_buf | ||
} | ||
|
||
struct TestCaseResult { | ||
did_pass : Bool, | ||
message : String, | ||
} | ||
|
||
function TestCase<'Result : Eq + Show > (test_case : () -> 'Result, expected : 'Result) : TestCaseResult { | ||
let result = test_case(); | ||
if result == expected { | ||
new TestCaseResult { did_pass = true, message = "" } | ||
} else { | ||
new TestCaseResult { did_pass = false, message = $"expected: {expected}, got: {result}" } | ||
} | ||
} | ||
|
||
|
||
|
||
export TestCases; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
export Functions, Operations; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
/// # Summary | ||
/// Runs a series of named test operations with expected results. | ||
/// | ||
/// # Description | ||
/// Given an array of test names, test operations, and expected results (of the same type), returns `true` | ||
/// if all tests passed, and `false` if any one test failed. | ||
/// Prints the expected and received result for any failed tests. | ||
/// | ||
/// # Input | ||
/// ## test_cases | ||
/// An array of five-arity tuples of the form `(test_name, num_qubits, qubit_prep_callable, callable_to_test, expected_result)`. | ||
/// `num_qubits` will be allocated in a qubit array and passed to `qubit_prep_callable` to prepare the state before executing | ||
/// `callable_to_test`. Afterwards, `callable_to_test` will be called and its result will be compared to `expected_result`. | ||
/// | ||
/// # Example | ||
/// ```qsharp | ||
/// function Main() : Unit { | ||
/// TestCases([ | ||
/// ("Should return 42", TestCaseOne, 42), | ||
/// ("Should add one", () => AddOne(5), 6) | ||
/// ]); | ||
/// } | ||
/// | ||
/// function TestCaseOne() : Int { | ||
/// 42 | ||
/// } | ||
/// | ||
/// function AddOne(x: Int) : Int { | ||
/// x + 1 | ||
/// } | ||
/// ``` | ||
operation TestCases<'Result : Eq + Show > (test_cases : (String, Int, (Qubit[]) => (), (Qubit[]) => 'Result, 'Result)[]) : Bool { | ||
let failed_test_buf = TestCasesSilent(test_cases); | ||
|
||
if Length(failed_test_buf) == 0 { | ||
Message($"{Length(test_cases)} test(s) passed."); | ||
true | ||
} else { | ||
Message($"{Length(failed_test_buf)} tests failed."); | ||
for item in failed_test_buf { | ||
Message($"{item}") | ||
} | ||
false | ||
} | ||
} | ||
|
||
/// # Summary | ||
/// Similar to `Qtest.Operations.TestCases`, but returns test failure info in an array of strings instead of directly messaging to | ||
/// output. Useful if you want to handle your own messaging when writing tests, for CI or similar. | ||
|
||
/// See `Qtest.Operations.TestCases` for more details. | ||
/// | ||
/// # Description | ||
/// Given an array of test names, test functions, and expected results (of the same type), returns an array | ||
/// of strings representing all failed test cases (if any). Strings are of the form "test_name: expected {}, got {}" | ||
/// | ||
/// # Input | ||
/// ## test_cases | ||
/// An array of five-arity tuples of the form `(test_name, num_qubits, qubit_prep_callable, callable_to_test, expected_result)`. | ||
/// `num_qubits` will be allocated in a qubit array and passed to `qubit_prep_callable` to prepare the state before executing | ||
/// `callable_to_test`. Afterwards, `callable_to_test` will be called and its result will be compared to `expected_result`. | ||
/// | ||
/// # Example | ||
/// ```qsharp | ||
/// function Main() : Unit { | ||
/// let failure_messages = TestCasesSilent([ | ||
/// ("Should return 42", TestCaseOne, 42), | ||
/// ("Should add one", () => AddOne(5), 6) | ||
/// ]); | ||
/// Std.Diagnostics.Fact(Length(failure_messages) == 0, "No tests should fail.") | ||
/// } | ||
/// | ||
/// function TestCaseOne() : Int { | ||
/// 42 | ||
/// } | ||
/// | ||
/// function AddOne(x: Int) : Int { | ||
/// x + 1 | ||
/// } | ||
/// ``` | ||
operation TestCasesSilent<'Result : Eq + Show > (test_cases : (String, Int, (Qubit[]) => (), (Qubit[]) => 'Result, 'Result)[]) : String[] { | ||
let num_tests = Length(test_cases); | ||
mutable failed_test_buf = []; | ||
|
||
for (name, num_qubits, prepare_state, case, result) in test_cases { | ||
use qubits = Qubit[num_qubits]; | ||
prepare_state(qubits); | ||
let (did_pass, message) = TestCase(qubits, case, result)!; | ||
if not did_pass { | ||
set failed_test_buf = failed_test_buf + [$"{name}: {message}"]; | ||
} | ||
ResetAll(qubits); | ||
} | ||
|
||
failed_test_buf | ||
} | ||
struct TestCaseResult { | ||
did_pass : Bool, | ||
message : String, | ||
} | ||
|
||
operation TestCase<'Result : Eq + Show > (qubits: Qubit[], test_case : (Qubit[]) => 'Result, expected : 'Result) : TestCaseResult { | ||
let result = test_case(qubits); | ||
if result == expected { | ||
new TestCaseResult { did_pass = true, message = "" } | ||
} else { | ||
new TestCaseResult { did_pass = false, message = $"expected: {expected}, got: {result}" } | ||
} | ||
} | ||
|
||
|
||
|
||
export TestCases; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
function Main() : Unit { | ||
Std.Diagnostics.Fact( | ||
Functions.TestCases([ | ||
("Should return 42", TestCaseOne, 42), | ||
("Should add one", () -> AddOne(5), 6) | ||
]), | ||
"Test harness failed to return true for all passing tests." | ||
); | ||
Std.Diagnostics.Fact( | ||
Length(Functions.TestCasesSilent([ | ||
("Should return 42", TestCaseOne, 43), | ||
("Should add one", () -> AddOne(5), 42) | ||
])) == 2, | ||
"Test harness failed to return messages for failing tests." | ||
); | ||
} | ||
|
||
function TestCaseOne() : Int { | ||
42 | ||
} | ||
|
||
function AddOne(x : Int) : Int { | ||
x + 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters