0.14.0 • Published 8 months ago

debris v0.14.0

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

Debris: A JavaScript Testing Framework

Debris is a JavaScript testing framework with support for fixtures, asynchronicity and spaced testing.

Features

  • No dependencies*
  • Descriptive
  • Fixtures
  • Promise support
  • Test spacing (metatesting, fuzzy testing)
  • Snapshots
  • Individual test running

* aside from runtime-compat, which reflects Flog's standard library.

Configuring

Skip this part if you don't need a custom configuration.

In your project root create a debris.json.

{
  "fixtures": "fixtures",
  "explicit": true
}

fixtures is the directory containing your test fixtures, the path is relative to your project root.

If you're interested in hidding passed tests change explicit to false.

Writing tests

If you're testing src/truth.js, create a src/truth.spec.js file.

export default test => {
  test.case("there is only *the* truth", assert => {
    assert(true).equals(true);
  });
});

Run the test.

npx debris

Adding fixtures

Fixtures represent a state of your application that you don't want to manually set each time.

Create a fixture file in the fixtures directory, truth.js (fixtures/truth.js).

export default () => true;

Fixtures are made available to all test cases as the second parameter to the case method of test.

Modify your test.

export default test => {
  test.case("there is only *the* truth", (assert, fixtures) => {
    assert(fixtures.truth).equals(true);
  });
}

The properties of fixtures reflect the filenames (without .js) of the fixtures you created. You can thus also destructure to pull in the fixtures you need for an individual case.

export default test => {
  test.case("there is only *the* truth", (assert, {truth}) => {
    assert(truth).equals(true);
  });
}

Transformed fixtures

Sometimes you need all the cases of a test to do something common that isn't necessarily achievable with fixtures. For example you might want to read a file based on a test's name and then make sure it fulfills certain criteria.

You can call the refix method of the test parameter to achieve that.

export default test => {
  test.refix(async (fixtures, {description}) => {
    const path = description.replaceAll(" ", "-") + ".html";
    // assume the function `read` returns a file's contents at `path`
    const contents = await read(path);
    return {...fixtures, contents};
  }));

  test.case("file containing the truth", (assert, {contents}) => {
    assert(contents).equals("true");
  });
}

The first of argument of refix is a mapper that takes the original fixtures parameter and the case itself as parameters and maps it to a (modified) fixtures object which is available to the case.

Case spacing / fuzzing

Sometimes you don't want individual cases with set input but the same case executed many times with different inputs. You can use the space method of test for that.

export default test => {
  test.space("there is only *the* truth", [true, false], (assert, each) => {
    assert(each).equals(true);
  });
}

This effectively creates two cases with the same definition and different input, one which will pass and another which will fail.

Spacing can be combined with fixtures, see API later on.

Snapshots

Snapshots are dynamically generated fixtures. With snapshots you can test the stability of a given object using assert(...).stable().

On the first run, the asserted value is JSON-stringified and saved to disk at the same location as the test itself. On a subsequent run, the asserted value is compared to the value on disk. For these kind of tests to be effective you should commit the dynamically generated fixtures alongside your test.

Running tests individually

If you're working on a test and aren't interested in others you can run it individually and ignore the rest. Just use the test's generated id.

This runs only the first test.

npx debris 0.0.0

Test-driven development

If you're doing TDD and want tests to explicitly fail as you write them you can use assert.fail(). Calling it is equivalent to writing assert(true).false().

API

Subject to breakage until v1.

Test (the parameter test passed to a spec)

case(String description, Function body)

Defines a case using the given description. body will be executed with assert as its first and fixtures as its second parameter.

for(Array fixtures, Case case)

Executes once per test case, transforming fixtures. The return value will be input to the case.

The default implementation unless overwritten is an identity function on fixtures (fixtures => fixtures).

This function should not be called but overwritten.

space(String description, Array inputs, Function body)

Defines a case space using the given description and inputs. body will be executed inputs.length times with the respective input from inputs as its first parameter and fixtures as its second. body will be signed in as Test.prototype.case.

Roadmap to v1

  • 100% self-coverage
  • Sane configuration defaults
  • Proper logger (stdio, file)
  • Documentation

License

MIT

0.14.0

8 months ago

0.13.1

10 months ago

0.11.0

1 year ago

0.12.0

1 year ago

0.11.1

1 year ago

0.13.0

1 year ago

0.12.1

1 year ago

0.10.0

1 year ago

0.8.5

1 year ago

0.8.4

1 year ago

0.8.6

1 year ago

0.9.0

1 year ago

0.8.1

1 year ago

0.8.0

1 year ago

0.8.3

1 year ago

0.9.1

1 year ago

0.8.2

1 year ago

0.7.1

2 years ago

0.5.0

2 years ago

0.4.0

2 years ago

0.7.0

2 years ago

0.6.0

2 years ago

0.3.0

2 years ago

0.3.1

2 years ago

0.2.1

2 years ago

0.2.2

2 years ago

0.2.0

2 years ago

0.1.0

2 years ago