-
Notifications
You must be signed in to change notification settings - Fork 0
Snapshots
If a test returned some data, it will be saved in snapshots' directory in a file that corresponds to the name of the test for which it was taken. The default location of snapshots is test/snapshot/...
, and test/spec
with test/mask
do not participate in the path formation.
import { asyncSoftware } from './src'
const TestSuite = {
async 'supports snapshots'() {
const res = await asyncSoftware('string')
return res
},
async 'fails if snapshot is different'() {
const res = await asyncSoftware('string')
return res
},
async 'fails if snapshot exists'() {
await asyncSoftware('string')
return undefined
},
async 'fails if snapshot is of different type'() {
await asyncSoftware('string')
return { hello: 'world' }
},
}
export default TestSuite
The Service Context is a special type of context that allows to access APIs to control how snapshots are saved.
It is possible to change the file type with which the snapshot will be saved. This can be useful for visual inspection of the snapshot, for example if a program under test produces XML output, it should be saved with xml
file extension so that it is easy to see its structure when opening the file in the IDE. To achieve that, a service context is used.
The service context can be used in 2 ways, however they both require the test suite to import the Zoroaster context zoroaster
package:
import Zoroaster from 'zoroaster'
-
The extension of the whole test suite can be set by specifying a contexts which extends Zoroaster service context, and implements the
get snapshotExtension
getter. Then it can be attached to the test suite in the same way as other contexts, that is by specifying it in thecontext
property:class XmlSnapshot extends Zoroaster { static get snapshotExtension() { return 'xml' } } /** @type {Object.<string, (c: Context)>} */ const T = { context: [Context, XmlSnapshot], async 'generates XML from the JS file'({ path }) { const xml = generateXML(path) return xml }, }
-
The second way to use the service context is for individual tests, but the Zoroaster context does not have to be extended. It works by accessing the
snapshotExtension
method from the test itself:/** @type {Object.<string, (c: Context, z: Zoroaster)>} */ const T = { context: [Context, Zoroaster], async 'generates XML from the JS file'({ path }, { snapshotExtension }) { const xml = generateXML(path) snapshotExtension('xml') return xml }, }
If the test repeats the snapshot of another test in the test suite, it can point to the name of this test with the snapshotSource
method. It accepts two arguments: first, the name of the test in the test suite that should be used to query the snapshot for, and second, optional, is the snapshot extension, if such extension was set with the snapshotExtension
method in the test (because otherwise the test runner cannot know that a different extension is required, unless the extended service context is used that implements the snapshotExtension
getter).
const T = {
context: [Zoroaster, TempContext],
async 'generates correct markdown'({ snapshotExtension }) {
const markdown = await generateMarkdown()
snapshotExtension('md')
return markdown
},
async 'generates correct markdown and saves it to a file'(
{ snapshotSource }, { read, resolve },
) {
const output = resolve('output.md')
await generateMarkdown(output)
const s = await read('output.md')
snapshotSource('generates correct markdown', 'md')
return markdown
},
}
Whenever the snapshot does not match the output of the test, or its type (strings are saved as txt
files and objects as json
files), an error will be thrown. To enable updating snapshots during the test run, the -i
or --interactive
option can be passed to Zoroaster test runner. Currently, only JSON serialisation is supported, therefore there might be errors due to the JSON.stringify
method omitting undefined properties and dates.
The static serialise
method can be overridden to provide the serialisation strategy for tests. The deepEqual method from the @zoroaster/assert
package will compare objects for deep strict equality, so that when an instance of a class returned by the test, the test will fail because the instance will be of its type, whereas the expected value will be of type Object. To solve that, the serialise
method can be implemented.
import Zoroaster from 'zoroaster'
import Example from './Example'
export const withSerialisation = {
context: class extends Zoroaster {
/** @param {Example} example **/
static serialise(example) {
// prevent comparison of a date object and JSON string
example.created = example.created.toGMTString()
// prevent omitting of undefined in the JSON snapshot
Object.keys(example).forEach((key) => {
const val = example[key]
example[key] = val === undefined ? 'undefined' : val
})
return { ...example }
}
},
async 'serialises dates'() {
const instance = new Example('test', true)
return instance
},
async 'records missing properties'() {
const instance = new Example()
return instance
},
}
export const withoutSerialisation = {
async 'serialises dates'() {
const instance = new Example('test', true)
return instance
},
async 'records missing properties'() {
const instance = new Example()
return instance
},
}
Show Output
example/serialise/spec.js
withSerialisation
✓ serialises dates
✓ records missing properties
withoutSerialisation
✗ serialises dates
| AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
| + actual - expected
| + Example {
| + created: 2019-05-31T21:00:00.000Z,
| - {
| - created: '2019-05-31T21:00:00.000Z',
| isExample: true,
| name: 'test'
| }
| - Object
| + Example
✗ records missing properties
| AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
| + actual - expected
| + Example {
| + created: 2019-05-31T21:00:00.000Z,
| + isExample: undefined,
| + name: undefined
| - {
| - created: '2019-05-31T21:00:00.000Z'
| }
| - Object
| + Example
example/serialise/spec.js > withoutSerialisation > serialises dates
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ Example {
+ created: 2019-05-31T21:00:00.000Z,
- {
- created: '2019-05-31T21:00:00.000Z',
isExample: true,
name: 'test'
}
- Object
+ Example
example/serialise/spec.js > withoutSerialisation > records missing properties
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected
+ Example {
+ created: 2019-05-31T21:00:00.000Z,
+ isExample: undefined,
+ name: undefined
- {
- created: '2019-05-31T21:00:00.000Z'
}
- Object
+ Example
🦅 Executed 4 tests: 2 errors.