# TerminologyEach test suite is organized as a tree, both in the filesystem and further within each file.- _Suites_, e.g. `src/webgpu/`.- _READMEs_, e.g. `src/webgpu/README.txt`.- _Test Spec Files_, e.g. `src/webgpu/examples.spec.ts`.Identified by their file path.Each test spec file provides a description and a _Test Group_.A _Test Group_ defines a test fixture, and contains multiple:- _Tests_.Identified by a comma-separated list of parts (e.g. `basic,async`)which define a path through a filesystem-like tree (analogy: `basic/async.txt`).Defines a _test function_ and contains multiple:- _Test Cases_.Identified by a list of _Public Parameters_ (e.g. `x` = `1`, `y` = `2`).Each Test Case has the same test function but different Public Parameters.## Test TreeA _Test Tree_ is a tree whose leaves are individual Test Cases.A Test Tree can be thought of as follows:- Suite, which is the root of a tree with "leaves" which are:- Test Spec Files, each of which is a tree with "leaves" which are:- Tests, each of which is a tree with leaves which are:- Test Cases.(In the implementation, this conceptual tree of trees is decomposed into one big treewhose leaves are Test Cases.)**Type:** `TestTree`## SuiteA suite of tests.A single suite has a directory structure, and many _test spec files_(`.spec.ts` files containing tests) and _READMEs_.Each member of a suite is identified by its path within the suite.**Example:** `src/webgpu/`### README**Example:** `src/webgpu/README.txt`Describes (in prose) the contents of a subdirectory in a suite.READMEs are only processed at build time, when generating the _Listing_ for a suite.**Type:** `TestSuiteListingEntryReadme`## QueriesA _Query_ is a structured object which specifies a subset of cases in exactly one Suite.A Query can be represented uniquely as a string.Queries are used to:- Identify a subtree of a suite (by identifying the root node of that subtree).- Identify individual cases.- Represent the list of tests that a test runner (standalone, wpt, or cmdline) should run.- Identify subtrees which should not be "collapsed" during WPT `cts.https.html` generation,so that that cts.https.html "variants" can have individual test expectations(i.e. marked as "expected to fail", "skip", etc.).There are four types of `TestQuery`:- `TestQueryMultiFile` represents any subtree of the file hierarchy:- `suite:*`- `suite:path,to,*`- `suite:path,to,file,*`- `TestQueryMultiTest` represents any subtree of the test hierarchy:- `suite:path,to,file:*`- `suite:path,to,file:path,to,*`- `suite:path,to,file:path,to,test,*`- `TestQueryMultiCase` represents any subtree of the case hierarchy:- `suite:path,to,file:path,to,test:*`- `suite:path,to,file:path,to,test:my=0;*`- `suite:path,to,file:path,to,test:my=0;params="here";*`- `TestQuerySingleCase` represents as single case:- `suite:path,to,file:path,to,test:my=0;params="here"`Test Queries are a **weakly ordered set**: any query is_Unordered_, _Equal_, _StrictSuperset_, or _StrictSubset_ relative to any other.This property is used to construct the complete tree of test cases.In the examples above, every example query is a StrictSubset of the previous one(note: even `:*` is a subset of `,*`).In the WPT and standalone harnesses, the query is stored in the URL, e.g.`index.html?q=q:u,e:r,y:*`.Queries are selectively URL-encoded for readability and compatibility with browsers(see `encodeURIComponentSelectively`).**Type:** `TestQuery`## ListingA listing of the **test spec files** in a suite.This can be generated only in Node, which has filesystem access (see `src/tools/crawl.ts`).As part of the build step, a _listing file_ is generated (see `src/tools/gen.ts`) so that theTest Spec Files can be discovered by the web runner (since it does not have filesystem access).**Type:** `TestSuiteListing`### Listing FileEach Suite has one Listing File (`suite/listing.[tj]s`), containing a list of the filesin the suite.In `src/suite/listing.ts`, this is computed dynamically.In `out/suite/listing.js`, the listing has been pre-baked (by `tools/gen_listings_and_webworkers`).**Type:** Once `import`ed, `ListingFile`**Example:** `out/webgpu/listing.js`## Test Spec FileA Test Spec File has a `description` and a Test Group (under which tests and cases are defined).**Type:** Once `import`ed, `SpecFile`**Example:** `src/webgpu/**/*.spec.ts`## Test GroupA subtree of tests. There is one Test Group per Test Spec File.The Test Fixture used for tests is defined at TestGroup creation.**Type:** `TestGroup`## TestOne test. It has a single _test function_.It may represent multiple _test cases_, each of which runs the same Test Function with differentParameters.A test is named using `TestGroup.test()`, which returns a `TestBuilder`.`TestBuilder.params()`/`.paramsSimple()`/`.paramsSubcasesOnly()`can optionally be used to parametrically generate instances (cases and subcases) of the test.Finally, `TestBuilder.fn()` provides the Test Function(or, a test can be marked unimplemented with `TestBuilder.unimplemented()`).### Test FunctionWhen a test subcase is run, the Test Function receives an instance of theTest Fixture provided to the Test Group, producing test results.**Type:** `TestFn`## Test Case / CaseA single case of a test. It is identified by a `TestCaseID`: a test name, and its parameters.Each case appears as an individual item (tree leaf) in `/standalone/`,and as an individual "step" in WPT.If `TestBuilder.params()`/`.paramsSimple()`/`.paramsSubcasesOnly()` are not used,there is exactly one case with one subcase, with parameters `{}`.**Type:** During test run time, a case is encapsulated as a `RunCase`.## Test Subcase / SubcaseA single "subcase" of a test. It can also be identified by a `TestCaseID`, thoughnot all contexts allow subdividing cases into subcases.All of the subcases of a case will run _inside_ the case, essentially as a for-loop wrapping thetest function. They do _not_ appear individually in `/standalone/` or WPT.If `CaseParamsBuilder.beginSubcases()` is not used, there is exactly one subcase per case.## Test Parameters / ParamsEach Test Subcase has a (possibly empty) set of Test Parameters,The parameters are passed to the Test Function `f(t)` via `t.params`.A set of Public Parameters identifies a Test Case or Test Subcase within a Test.There are also Private Parameters: any parameter name beginning with an underscore (`_`).These parameters are not part of the Test Case identification, but are still passed intothe Test Function. They can be used, e.g., to manually specify expected results.**Type:** `TestParams`## Test Fixture / Fixture_Test Fixtures_ provide helpers for tests to use.A new instance of the fixture is created for every run of every test case.There is always one fixture class for a whole test group (though this may change).The fixture is also how a test gets access to the _case recorder_,which allows it to produce test results.They are also how tests produce results: `.skip()`, `.fail()`, etc.**Type:** `Fixture`### `UnitTest` FixtureProvides basic fixture utilities most useful in the `unittests` suite.### `GPUTest` FixtureProvides utilities useful in WebGPU CTS tests.# Test Results## LoggerA logger logs the results of a whole test run.It saves an empty `LiveTestSpecResult` into its results map, then creates a_test spec recorder_, which records the results for a group into the `LiveTestSpecResult`.**Type:** `Logger`### Test Case RecorderRefers to a `LiveTestCaseResult` created by the logger.Records the results of running a test case (its pass-status, run time, and logs) into it.**Types:** `TestCaseRecorder`, `LiveTestCaseResult`#### Test Case StatusThe `status` of a `LiveTestCaseResult` can be one of:- `'running'` (only while still running)- `'pass'`- `'skip'`- `'warn'`- `'fail'`The "worst" result from running a case is always reported (fail > warn > skip > pass).Note this means a test can still fail if it's "skipped", if it failed before`.skip()` was called.**Type:** `Status`## Results FormatThe results are returned in JSON format.They are designed to be easily merged in JavaScript:the `"results"` can be passed into the constructor of `Map` and merged from there.(TODO: Write a merge tool, if needed.)```js{"version": "bf472c5698138cdf801006cd400f587e9b1910a5-dirty","results": [["unittests:async_mutex:basic:",{ "status": "pass", "timems": 0.286, "logs": [] }],["unittests:async_mutex:serial:",{ "status": "pass", "timems": 0.415, "logs": [] }]]}```