Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/chase-moskal/cynic
simple async run-anywhere js testing framework
https://github.com/chase-moskal/cynic
browser commonjs esm esmodules javascript node puppeteer test-automation test-runner testing testing-framework testing-tools typescript
Last synced: about 1 month ago
JSON representation
simple async run-anywhere js testing framework
- Host: GitHub
- URL: https://github.com/chase-moskal/cynic
- Owner: chase-moskal
- License: mit
- Created: 2015-11-02T06:31:04.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2023-03-25T21:03:03.000Z (over 1 year ago)
- Last Synced: 2024-09-30T16:10:52.066Z (about 2 months ago)
- Topics: browser, commonjs, esm, esmodules, javascript, node, puppeteer, test-automation, test-runner, testing, testing-framework, testing-tools, typescript
- Language: TypeScript
- Homepage:
- Size: 291 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: readme.md
- License: license
Awesome Lists containing this project
README
# 🧐 cynic
## async testing framework for es modules
- cynic is designed to be dirt-simple, because i'm sick of overcomplicated testing frameworks
- the test suites are just nested async functions
- the whole framework is just simple es modules that run anywhere: node, browser, puppeteer, deno
- no magic assumptions are made about or foisted onto the environment: the assertion library and everything else is just simply imported like from any other module
- examples here are shown in typescript, but of course you can use vanilla js## let's get cynical, and make a damn test suite!
1. install cynic into your project
```sh
npm install --save-dev cynic
```2. write a test suite, `example.test.ts`
```ts
import {Suite, assert, expect} from "cynic"export default {
"alpha system": {
"can sum two numbers (boolean return)": async() => {
const a = 1
const b = 2
// no assertion library required:
// simply returning false, or throwing, will fail a test
return (a + b) === 3
},
"can sum three numbers (assert)": async() => {
const a = 1
const b = 2
const c = 3
// benefits of 'assert'
// - you get a stack trace
// - you can provide a custom message for each failure
assert((a + b + c) === 6, `sum is wrong`)
}
},
"bravo system": {
"can multiply numbers (expect)": async() => {
const a = 2
const b = 3
// benefits of 'expect'
// - you get a stack trace
// - cynic tries to invent a message about the failure
expect(a * b).equals(6)
expect(a * b * a).equals(12)
}
}
}
```## now run it!
- ### **you can run the suite file through the cynic cli**
```sh
# run your tests in node
cynic node example.test.js# run your tests in browser
cynic browser example.test.js# run your tests in puppeteer (headless browser)
cynic puppeteer example.test.js# use node debugger
node inspect node_modules/cynic/dist/cli.js node example.test.js
```cynic executes the default export as a test suite
optional arguments for *all* runtimes:
- `--label="test suite"` — the report titleoptional arguments for *browser* and *puppeteer* runtimes:
- `--open=false` — true to prompt open your default browser
- `--port=8021` — run the server on a different port
- `--origin="http://localhost:8021"` — connect to the server via an alternative url (mind the port number!)
- `--cynic-path=node_modules/cynic` — use an alternative path to the cynic library's root
- `--importmap-path=./dist/importmap.json` — provide an import map for your test suitesif puppeteer isn't running properly, see puppeteer's [troubleshooting.md](https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md)
- ### **or you can just execute your test suite, manually, anywhere**
this should work anywhere you can import an es module
```ts
import {test} from "cynic"
import suite from "./example.test.js";(async() => {
// run the test suite
const {report, ...stats} = await test("example suite", suite)// emit the report text to console
console.log(report)// handle results programmatically
if (stats.failed === 0) console.log("done")
else console.log("failed!")// returns stats about the test run results
console.log(stats)})()
```see which stats are available in the `Stats` interface in [types.ts](./source/types.ts)
## so what do the console reports look like?
- **report: successful run**
```
cynic example suite
▽ examples
▽ alpha system
✓ can sum two numbers (boolean return)
✓ can sum three numbers (assertion)
▽ bravo system
✓ can multiply numbers (expectation)
0 failed tests
0 thrown errors
3 passed tests
3 total tests
0.00 seconds
```- **report: a test returns false**
return false to indicate a failed test```
cynic example suite
▽ examples
▽ alpha system
═════ ✘ can sum two numbers (boolean return)
▽ bravo system✘ can sum two numbers (boolean return) — failed
1 FAILED tests
0 thrown errors
2 passed tests
3 total tests
0.00 seconds
```- **report: a test throws**
a thrown string or error will be shown as the failure reason```
cynic example suite▽ examples
▽ alpha system═════ ✘ can sum two numbers (boolean return)
――――――― arithmetic failed for interesting reasons▽ bravo system
✘ can sum two numbers (boolean return) — arithmetic failed for interesting reasons
1 FAILED tests
1 thrown errors
2 passed tests
3 total tests
0.00 seconds
```- **report: a test fails an assertion**
assertions will display a stack trace, and optional custom message```
cynic example suite▽ examples
▽ alpha system
═════ ✘ can sum three numbers (assertion)
――――――― CynicBrokenAssertion: sum is wrong
at assert (file:///work/cynic/dist/assert.js:7:15)
at can sum three numbers (assertion) (file:///work/cynic/dist/internals/example.test.js:13:20)
at execute (file:///work/cynic/dist/internals/execute.js:13:34)
[...]▽ bravo system
✘ can sum three numbers (assertion) — CynicBrokenAssertion: sum is wrong
1 FAILED tests
1 thrown errors
2 passed tests
3 total tests
0.00 seconds
```- **report: a test fails an expectation**
stack trace is provided, and a failure reason is generated automatically```
cynic example suite
▽ examples
▽ alpha system
▽ bravo system═════ ✘ can multiply numbers (expectation)
――――――― CynicBrokenExpectation: expect(7).equals(6): not equal, should be
at composite (file:///work/cynic/dist/expect.js:46:19)
at Object.equals (file:///work/cynic/dist/expect.js:25:125)
at can multiply numbers (expectation) (file:///work/cynic/dist/internals/example.test.js:20:39)
at execute (file:///work/cynic/dist/internals/execute.js:13:34)
[...]✘ can multiply numbers (expectation) — CynicBrokenExpectation: expect(7).equals(6): not equal, should be
1 FAILED tests
1 thrown errors
2 passed tests
3 total tests
0.00 seconds
```## hot tips for big brains
- use object nesting to group and organize tests arbitrarily
```ts
import {Suite} from "cynic"
export default {
"nested tests": {
"more nested": {
"exceedingly nested": {
"it works": async() => true
}
}
}
}
```- you can just throw strings as assertions
```ts
import {Suite} from "cynic"
export default {
"assertions and expectations": async() => {
const example = "abc"// let's call it "the spartan assertion"
if (!example.includes("b"))
throw `expected example to include "b"`return true
}
}
```- or you can use the handy `assert` function to do that, you get stack traces
```ts
import {Suite, assert} from "cynic"
export default {
"using 'assert'": async() => {
const example = "abc"
assert(example === "abc", `example must equal "abc"`)
assert(example.includes("b"), `example should include "b"`)
}
}
```- or you can also use the experimental new `expect` api, you get auto-generated messages and stack traces
```ts
import {Suite, expect} from "cynic"
export default {
"using 'expect'": async() => {
const example = "abc"
expect(example).defined()
expect(example).equals("abc")
}
}
```- a suite or test can return another suite or test — *easy setups!*
```ts
export default (async() => {// doing some async setup
const myFile = await loadFile("myfile.json")// returning more tests
return {
"group of tests": {
"my file exists": async() => {
return !!myFile
}
}
}
})
```## food for thought
- 🥃 chase moskal made this with open source love. please contribute!