|
| 1 | +# DocTest |
| 2 | + |
| 3 | +**DocTest** is an experimental tool |
| 4 | +for testing Swift example code in documentation. |
| 5 | + |
| 6 | +**This is still a work-in-progress, and not yet ready for production** |
| 7 | + |
| 8 | +> DocTest is inspired by |
| 9 | +> [Python's `doctest`](https://docs.python.org/3/library/doctest.html). |
| 10 | +
|
| 11 | +* * * |
| 12 | + |
| 13 | +The hardest part of software documentation is writing it in the first place. |
| 14 | +But once you clear that initial hurdle, |
| 15 | +the challenge becomes keeping documentation correct and up-to-date. |
| 16 | + |
| 17 | +There's no built-in feedback mechanism for documentation like there is for code. |
| 18 | +If you write invalid code, |
| 19 | +your compiler will tell you. |
| 20 | +If you write valid but incorrect code, |
| 21 | +your test suite will tell you. |
| 22 | +But if you write documentation with invalid or incorrect example code, |
| 23 | +nothing breaks (at least not immediately). |
| 24 | + |
| 25 | +DocTest offers a way to annotate Swift code examples in documentation |
| 26 | +with expectations about its behavior that can be tested automatically, |
| 27 | +just like unit tests. |
| 28 | + |
| 29 | +## Usage |
| 30 | + |
| 31 | +``` |
| 32 | +OVERVIEW: A utility for syntax testing documentation in Swift code. |
| 33 | +
|
| 34 | +USAGE: swift-doc-test <input> [--swift-launch-path <swift-launch-path>] [--package] [--assumed-filename <assumed-filename>] |
| 35 | +
|
| 36 | +ARGUMENTS: |
| 37 | + <input> Swift code or a path to a Swift file |
| 38 | +
|
| 39 | +OPTIONS: |
| 40 | + --swift-launch-path <swift-launch-path> |
| 41 | + The path to the swift executable. (default: |
| 42 | + /usr/bin/swift) |
| 43 | + -p, --package Whether to run the REPL through Swift Package Manager |
| 44 | + (`swift run --repl`). |
| 45 | + --assumed-filename <assumed-filename> |
| 46 | + The assumed filename to use for reporting when |
| 47 | + parsing from standard input. (default: Untitled.swift) |
| 48 | + -h, --help Show help information. |
| 49 | +
|
| 50 | +``` |
| 51 | + |
| 52 | +## How It Works |
| 53 | + |
| 54 | +DocTest launches and interacts with |
| 55 | +the Swift <abbr title="Read-Eval-Print-Loop">REPL</abbr>, |
| 56 | +passing each code statement through standard input |
| 57 | +and reading its result through standard output and/or standard error. |
| 58 | + |
| 59 | +Consider the following function declaration |
| 60 | +within a Swift package: |
| 61 | + |
| 62 | +~~~swift |
| 63 | +/** |
| 64 | + Returns the sum of two integers. |
| 65 | +
|
| 66 | + ```swift |
| 67 | + add(1 1) // 3.0 |
| 68 | + ``` |
| 69 | +*/ |
| 70 | +func add(_ a: Int, _ b: Int) -> Int { ... } |
| 71 | +~~~ |
| 72 | + |
| 73 | +There are three problems with the example code |
| 74 | +provided in the documentation for `add(_:_:)`: |
| 75 | + |
| 76 | +1. It doesn't compile |
| 77 | + (missing comma separator between arguments) |
| 78 | +2. It suggests an incorrect result |
| 79 | + (one plus one equals two, not three) |
| 80 | +3. It suggests an incorrect type of result |
| 81 | + (the sum of two integers is an integer, |
| 82 | + which isn't expressible by a floating-point literal) |
| 83 | + |
| 84 | +We can use DocTest to identify these problems automatically |
| 85 | +by adding `"doctest"` to the start of the fenced code block. |
| 86 | +This tells the documentation test runner to evaluate the code sample. |
| 87 | + |
| 88 | +~~~swift |
| 89 | +/** |
| 90 | + Returns the sum of two integers. |
| 91 | +
|
| 92 | + ```swift doctest |
| 93 | + add(1 1) // Double = 3.0 |
| 94 | + ``` |
| 95 | +*/ |
| 96 | +func add(_ a: Int, _ b: Int) -> Int { ... } |
| 97 | +~~~ |
| 98 | + |
| 99 | +Run the `swift-doctest` command |
| 100 | +from the root directory of the Swift package, |
| 101 | +specifying the `--package` flag |
| 102 | +(to invoke the Swift REPL via the Swift Package Manager) |
| 103 | +and passing the path to the file containing the `add(_:_:)` function. |
| 104 | +This will scan for all of code blocks annotated with |
| 105 | +<code>```swift doctest</code> |
| 106 | +run them through the Swift REPL, |
| 107 | +and test the output with any annotated expectations. |
| 108 | + |
| 109 | +```terminal |
| 110 | +$ swift doctest --package path/to/file.swift |
| 111 | +TAP version 13 |
| 112 | +1..1 |
| 113 | +not ok 1 - `add(1 1)` did not produce `Double 3.0` |
| 114 | + --- |
| 115 | + column: 1 |
| 116 | + file: path/to/file.swift.md |
| 117 | + line: 1 |
| 118 | + ... |
| 119 | + |
| 120 | +``` |
| 121 | + |
| 122 | +> Test results are reported in [TAP format](https://testanything.org). |
| 123 | +
|
| 124 | +## License |
| 125 | + |
| 126 | +MIT |
| 127 | + |
| 128 | +## Contact |
| 129 | + |
| 130 | +Mattt ([@mattt](https://twitter.com/mattt)) |
0 commit comments