| OLD | NEW |
| (Empty) |
| 1 JSON Reporter Protocol | |
| 2 ====================== | |
| 3 | |
| 4 The test runner supports a JSON reporter which provides a machine-readable | |
| 5 representation of the test runner's progress. This reporter is intended for use | |
| 6 by IDEs and other tools to present a custom view of the test runner's operation | |
| 7 without needing to parse output intended for humans. | |
| 8 | |
| 9 Note that the test runner is highly asynchronous, and users of this protocol | |
| 10 shouldn't make assumptions about the ordering of events beyond what's explicitly | |
| 11 specified in this document. It's possible for events from multiple tests to be | |
| 12 intertwined, for a single test to emit an error after it completed successfully, | |
| 13 and so on. | |
| 14 | |
| 15 ## Usage | |
| 16 | |
| 17 Pass the `--reporter json` command-line flag to the test runner to activate the | |
| 18 JSON reporter. | |
| 19 | |
| 20 pub run test --reporter json <path-to-test-file> | |
| 21 | |
| 22 The JSON stream will be emitted via standard output. It will be a stream of JSON | |
| 23 objects, separated by newlines. | |
| 24 | |
| 25 See `json_reporter.schema.json` for a formal description of the protocol schema. | |
| 26 See `test/runner/json_reporter_test.dart` for some sample output. | |
| 27 | |
| 28 ## Compatibility | |
| 29 | |
| 30 The protocol emitted by the JSON reporter is considered part of the public API | |
| 31 of the `test` package, and is subject to its [semantic versioning][semver] | |
| 32 restrictions. In particular: | |
| 33 | |
| 34 [semver]: https://www.dartlang.org/tools/pub/versioning.html#semantic-versions | |
| 35 | |
| 36 * No new feature will be added to the protocol without increasing the test | |
| 37 package's minor version number. | |
| 38 | |
| 39 * No breaking change will be made to the protocol without increasing the test | |
| 40 package's major version number. | |
| 41 | |
| 42 The following changes are not considered breaking. This is not necessarily a | |
| 43 comprehensive list. | |
| 44 | |
| 45 * Adding a new attribute to an existing object. | |
| 46 | |
| 47 * Adding a new type of any object with a `type` parameter. | |
| 48 | |
| 49 * Adding new test state values. | |
| 50 | |
| 51 ## Reading this Document | |
| 52 | |
| 53 Each major type of JSON object used by the protocol is described by a class. | |
| 54 Classes have names which are referred to in this document, but are not used as | |
| 55 part of the protocol. Classes have typed attributes, which refer to the types | |
| 56 and names of attributes in the JSON objects. If an attribute's type is another | |
| 57 class, that refers to a nested object. The special type `List<...>` indicates a | |
| 58 JSON list of the given type. | |
| 59 | |
| 60 Classes can "extend" one another, meaning that the subclass has all the | |
| 61 attributes of the superclass. Concrete subclasses can be distinguished by the | |
| 62 specific value of their `type` attribute. Classes may be abstract, indicating | |
| 63 that only their subclasses will ever be used. | |
| 64 | |
| 65 ## Events | |
| 66 | |
| 67 ### Event | |
| 68 | |
| 69 ``` | |
| 70 abstract class Event { | |
| 71 // The type of the event. | |
| 72 // | |
| 73 // This is always one of the subclass types listed below. | |
| 74 String type; | |
| 75 | |
| 76 // The time (in milliseconds) that has elapsed since the test runner started. | |
| 77 int time; | |
| 78 } | |
| 79 ``` | |
| 80 | |
| 81 This is the root class of the protocol. All root-level objects emitted by the | |
| 82 JSON reporter will be subclasses of `Event`. | |
| 83 | |
| 84 ### StartEvent | |
| 85 | |
| 86 ``` | |
| 87 class StartEvent extends Event { | |
| 88 String type = "start"; | |
| 89 | |
| 90 // The version of the JSON reporter protocol being used. | |
| 91 // | |
| 92 // This is a semantic version, but it reflects only the version of the | |
| 93 // protocol—it's not identical to the version of the test runner itself. | |
| 94 String protocolVersion; | |
| 95 | |
| 96 // The version of the test runner being used. | |
| 97 String runnerVersion; | |
| 98 } | |
| 99 ``` | |
| 100 | |
| 101 A single start event is emitted before any other events. It indicates that the | |
| 102 test runner has started running. | |
| 103 | |
| 104 ### AllSuitesEvent | |
| 105 | |
| 106 ``` | |
| 107 class AllSuitesEvent { | |
| 108 String type = "allSuites"; | |
| 109 | |
| 110 /// The total number of suites that will be loaded. | |
| 111 int count; | |
| 112 } | |
| 113 ``` | |
| 114 | |
| 115 A single suite count event is emitted once the test runner knows the total | |
| 116 number of suites that will be loaded over the course of the test run. Because | |
| 117 this is determined asynchronously, its position relative to other events (except | |
| 118 `StartEvent`) is not guaranteed. | |
| 119 | |
| 120 ### SuiteEvent | |
| 121 | |
| 122 ``` | |
| 123 class SuiteEvent extends Event { | |
| 124 String type = "suite"; | |
| 125 | |
| 126 /// Metadata about the suite. | |
| 127 Suite suite; | |
| 128 } | |
| 129 ``` | |
| 130 | |
| 131 A suite event is emitted before any `GroupEvent`s for groups in a given test | |
| 132 suite. This is the only event that contains the full metadata about a suite; | |
| 133 future events will refer to the suite by its opaque ID. | |
| 134 | |
| 135 ### GroupEvent | |
| 136 | |
| 137 ``` | |
| 138 class GroupEvent extends Event { | |
| 139 String type = "group"; | |
| 140 | |
| 141 /// Metadata about the group. | |
| 142 Group group; | |
| 143 } | |
| 144 ``` | |
| 145 | |
| 146 A group event is emitted before any `TestStartEvent`s for tests in a given | |
| 147 group. This is the only event that contains the full metadata about a group; | |
| 148 future events will refer to the group by its opaque ID. | |
| 149 | |
| 150 This includes the implicit group at the root of each suite, which has a `null` | |
| 151 name. However, it does *not* include implicit groups for the virtual suites | |
| 152 generated to represent loading test files. | |
| 153 | |
| 154 The group should be considered skipped if `group.metadata.skip` is `true`. When | |
| 155 a group is skipped, a single `TestStartEvent` will be emitted for a test within | |
| 156 that group that will also be skipped. | |
| 157 | |
| 158 ### TestStartEvent | |
| 159 | |
| 160 ``` | |
| 161 class TestStartEvent extends Event { | |
| 162 String type = "testStart"; | |
| 163 | |
| 164 // Metadata about the test that started. | |
| 165 Test test; | |
| 166 } | |
| 167 ``` | |
| 168 | |
| 169 An event emitted when a test begins running. This is the only event that | |
| 170 contains the full metadata about a test; future events will refer to the test by | |
| 171 its opaque ID. | |
| 172 | |
| 173 The test should be considered skipped if `test.metadata.skip` is `true`. | |
| 174 | |
| 175 ### PrintEvent | |
| 176 | |
| 177 ``` | |
| 178 class PrintEvent extends Event { | |
| 179 String type = "print"; | |
| 180 | |
| 181 // The ID of the test that printed a message. | |
| 182 int testID; | |
| 183 | |
| 184 // The message that was printed. | |
| 185 String message; | |
| 186 } | |
| 187 ``` | |
| 188 | |
| 189 A `PrintEvent` indicates that a test called `print()` and wishes to display | |
| 190 output. | |
| 191 | |
| 192 ### ErrorEvent | |
| 193 | |
| 194 ``` | |
| 195 class ErrorEvent extends Event { | |
| 196 String type = "error"; | |
| 197 | |
| 198 // The ID of the test that experienced the error. | |
| 199 int testID; | |
| 200 | |
| 201 // The result of calling toString() on the error object. | |
| 202 String error; | |
| 203 | |
| 204 // The error's stack trace, in the stack_trace package format. | |
| 205 String stackTrace; | |
| 206 | |
| 207 // Whether the error was a TestFailure. | |
| 208 bool isFailure; | |
| 209 } | |
| 210 ``` | |
| 211 | |
| 212 A `ErrorEvent` indicates that a test encountered an uncaught error. Note | |
| 213 that this may happen even after the test has completed, in which case it should | |
| 214 be considered to have failed. | |
| 215 | |
| 216 If a test is asynchronous, it may encounter multiple errors, which will result | |
| 217 in multiple `ErrorEvent`s. | |
| 218 | |
| 219 ### TestDoneEvent | |
| 220 | |
| 221 ``` | |
| 222 class TestDoneEvent extends Event { | |
| 223 String type = "testDone"; | |
| 224 | |
| 225 // The ID of the test that completed. | |
| 226 int testID; | |
| 227 | |
| 228 // The result of the test. | |
| 229 String result; | |
| 230 | |
| 231 // Whether the test's result should be hidden. | |
| 232 bool hidden; | |
| 233 } | |
| 234 ``` | |
| 235 | |
| 236 An event emitted when a test completes. The `result` attribute indicates the | |
| 237 result of the test: | |
| 238 | |
| 239 * `"success"` if the test had no errors. | |
| 240 | |
| 241 * `"failure"` if the test had a `TestFailure` but no other errors. | |
| 242 | |
| 243 * `"error"` if the test had an error other than a `TestFailure`. | |
| 244 | |
| 245 If the test encountered an error, the `TestDoneEvent` will be emitted after the | |
| 246 corresponding `ErrorEvent`. | |
| 247 | |
| 248 The `hidden` attribute indicates that the test's result should be hidden and not | |
| 249 counted towards the total number of tests run for the suite. This is true for | |
| 250 virtual tests created for loading test suites, `setUpAll()`, and | |
| 251 `tearDownAll()`. Only successful tests will be hidden. | |
| 252 | |
| 253 Note that it's possible for a test to encounter an error after completing. In | |
| 254 that case, it should be considered to have failed, but no additional | |
| 255 `TestDoneEvent` will be emitted. If a previously-hidden test encounters an | |
| 256 error after completing, it should be made visible. | |
| 257 | |
| 258 ### DoneEvent | |
| 259 | |
| 260 ``` | |
| 261 class DoneEvent extends Event { | |
| 262 String type = "done"; | |
| 263 | |
| 264 // Whether all tests succeeded (or were skipped). | |
| 265 bool success; | |
| 266 } | |
| 267 ``` | |
| 268 | |
| 269 An event indicating the result of the entire test run. This will be the final | |
| 270 event emitted by the reporter. | |
| 271 | |
| 272 ## Other Classes | |
| 273 | |
| 274 ### Test | |
| 275 | |
| 276 ``` | |
| 277 class Test { | |
| 278 // An opaque ID for the test. | |
| 279 int id; | |
| 280 | |
| 281 // The name of the test, including prefixes from any containing groups. | |
| 282 String name; | |
| 283 | |
| 284 // The ID of the suite containing this test. | |
| 285 int suiteID; | |
| 286 | |
| 287 // The IDs of groups containing this test, in order from outermost to | |
| 288 // innermost. | |
| 289 List<int> groupIDs; | |
| 290 | |
| 291 // The test's metadata, including metadata from any containing groups. | |
| 292 Metadata metadata; | |
| 293 } | |
| 294 ``` | |
| 295 | |
| 296 A single test case. The test's ID is unique in the context of this test run. | |
| 297 It's used elsewhere in the protocol to refer to this test without including its | |
| 298 full representation. | |
| 299 | |
| 300 Most tests will have at least one group ID, representing the implicit root | |
| 301 group. However, some may not; these should be treated as having no group | |
| 302 metadata. | |
| 303 | |
| 304 ### Suite | |
| 305 | |
| 306 ``` | |
| 307 class Suite { | |
| 308 // An opaque ID for the group. | |
| 309 int id; | |
| 310 | |
| 311 // The platform on which the suite is running. | |
| 312 String? platform; | |
| 313 | |
| 314 // The path to the suite's file. | |
| 315 String path; | |
| 316 } | |
| 317 ``` | |
| 318 | |
| 319 A test suite corresponding to a loaded test file. The suite's ID is unique in | |
| 320 the context of this test run. It's used elsewhere in the protocol to refer to | |
| 321 this suite without including its full representation. | |
| 322 | |
| 323 A suite's platform is one of the platforms that can be passed to the | |
| 324 `--platform` option, or `null` if there is no platform (for example if the file | |
| 325 doesn't exist at all). Its path is relative to the root of the current package. | |
| 326 | |
| 327 Suites don't include their own metadata. Instead, that metadata is present on | |
| 328 the root-level group. | |
| 329 | |
| 330 ### Group | |
| 331 | |
| 332 ``` | |
| 333 class Group { | |
| 334 // An opaque ID for the group. | |
| 335 int id; | |
| 336 | |
| 337 // The name of the group, including prefixes from any containing groups. | |
| 338 String? name; | |
| 339 | |
| 340 // The ID of the suite containing this group. | |
| 341 int suiteID; | |
| 342 | |
| 343 // The ID of the group's parent group, unless it's the root group. | |
| 344 int? parentID; | |
| 345 | |
| 346 // The group's metadata, including metadata from any containing groups. | |
| 347 Metadata metadata; | |
| 348 | |
| 349 // The number of tests (recursively) within this group. | |
| 350 int testCount; | |
| 351 } | |
| 352 ``` | |
| 353 | |
| 354 A group containing test cases. The group's ID is unique in the context of this | |
| 355 test run. It's used elsewhere in the protocol to refer to this group without | |
| 356 including its full representation. | |
| 357 | |
| 358 The implicit group at the root of each test suite has `null` `name` and | |
| 359 `parentID` attributes. | |
| 360 | |
| 361 ### Metadata | |
| 362 | |
| 363 ``` | |
| 364 class Metadata { | |
| 365 // Whether the test case will be skipped by the test runner. | |
| 366 bool skip; | |
| 367 | |
| 368 // The reason the test case is skipped, if the user provided it. | |
| 369 String? skipReason; | |
| 370 } | |
| 371 ``` | |
| 372 | |
| 373 The metadata attached to a test by a user. | |
| OLD | NEW |