ProgramGuru

Test behaviour and read diagnostics

Test behaviour and read diagnostics

A pass-rule program can compile and still use the wrong boundary. Tests compare actual behaviour with stated expectations, especially at edges. Compiler diagnostics concern source rules; failing tests concern behaviour that did not meet an expectation. Separating them makes debugging more systematic.

What you’ll learn

  • Check a pass rule below, at and above its threshold.
  • Distinguish behavioural tests from source diagnostics and input validation.

Test behaviour and read diagnostics in the example

  1. Stated rule

    A pass-rule program can compile and still use the wrong boundary.

    Stated rule
  2. Boundary expectations

    For a package, Swift Testing offers @Test and expectation macros on supported toolchains; XCTest is also available.

    Boundary expectations
  3. Compare behaviour

    The three checks cover below, exactly at and above the threshold.

    Compare behaviour
The three checks cover below, exactly at and above the threshold. If one comparison fails under this checked build, execution stops rather than printing the success message. The tests are tied to the stated rule, not simply copied from an implementation’s arbitrary output.

How test behaviour and read diagnostics works

For a package, Swift Testing offers @Test and expectation macros on supported toolchains; XCTest is also available. The small complete example below uses precondition for an executable check, not as a replacement for a test suite or input validation.

Work through test behaviour and read diagnostics

Save this complete program as main.swift and run it with the Swift toolchain. No separate input file is needed.

Swift · complete program

func passed(_ score: Int) -> Bool { score >= 75 }
let checks = [(74, false), (75, true), (80, true)]
for (score, expected) in checks {
  precondition(passed(score) == expected)
}
print("3 boundary checks passed")

Expected output

3 boundary checks passed

Follow the execution

The three checks cover below, exactly at and above the threshold. If one comparison fails under this checked build, execution stops rather than printing the success message. The tests are tied to the stated rule, not simply copied from an implementation’s arbitrary output.

Try this program in the Swift compiler. Paste the complete source above.

Practice: Test behaviour and read diagnostics

Your task: Which check catches changing >= 75 to > 75?

Swift · complete program

func passed(_ score: Int) -> Bool { score >= 75 }
let checks = [(74, false), (75, true), (80, true)]
for (score, expected) in checks {
  precondition(passed(score) == expected)
}
print("3 boundary checks passed")

Worked answer

The input 75 with expected true catches the mistake. That is why a boundary example can be more informative than many scores far from the threshold.

Check the rule at its boundary

Precondition is not an appropriate mechanism for validating untrusted form data, and optimization modes affect some runtime checking mechanisms. Use configured tests for regression protection, and errors or explicit results for ordinary invalid inputs. Read the first relevant diagnostic before changing unrelated code.

Check your decision

Which check catches changing >= 75 to > 75?
Choose one answer. You can try again.

Answer and explanation

The input 75 with expected true catches the mistake.

The input 75 with expected true catches the mistake. That is why a boundary example can be more informative than many scores far from the threshold.

Check the rule at its boundary

The input 75 with expected true catches the mistake. That is why a boundary example can be more informative than many scores far from the threshold. Precondition is not an appropriate mechanism for validating untrusted form data, and optimization modes affect some runtime checking mechanisms.

Further reading: official Swift language guide.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Async and await: suspension is not blocking →