{"id":20442662,"url":"https://github.com/bifravst/bdd-markdown","last_synced_at":"2025-04-30T21:53:55.507Z","repository":{"id":59747206,"uuid":"538913899","full_name":"bifravst/bdd-markdown","owner":"bifravst","description":"Write BDD tests in Markdown.","archived":false,"fork":false,"pushed_at":"2025-04-29T15:23:44.000Z","size":2121,"stargazers_count":4,"open_issues_count":3,"forks_count":0,"subscribers_count":3,"default_branch":"saga","last_synced_at":"2025-04-30T21:53:27.655Z","etag":null,"topics":["bdd","iot","nrf-asset-tracker"],"latest_commit_sha":null,"homepage":"https://github.com/bifravst/bdd-markdown#readme","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bifravst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-09-20T09:44:51.000Z","updated_at":"2025-04-29T15:23:19.000Z","dependencies_parsed_at":"2024-02-10T05:23:14.562Z","dependency_job_id":"2cdd4da6-622e-4426-adbd-c01e9f3dc7a7","html_url":"https://github.com/bifravst/bdd-markdown","commit_stats":{"total_commits":273,"total_committers":4,"mean_commits":68.25,"dds":0.3992673992673993,"last_synced_commit":"904a3256a1baf8ef6cf1a87c92e59f1325fbe794"},"previous_names":["bifravst/bdd-markdown"],"tags_count":284,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bifravst%2Fbdd-markdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bifravst%2Fbdd-markdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bifravst%2Fbdd-markdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bifravst%2Fbdd-markdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bifravst","download_url":"https://codeload.github.com/bifravst/bdd-markdown/tar.gz/refs/heads/saga","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251789578,"owners_count":21644082,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","iot","nrf-asset-tracker"],"created_at":"2024-11-15T09:42:23.426Z","updated_at":"2025-04-30T21:53:55.481Z","avatar_url":"https://github.com/bifravst.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BDD Markdown [![npm version](https://img.shields.io/npm/v/@bifravst/bdd-markdown.svg)](https://www.npmjs.com/package/@bifravst/bdd-markdown)\n\n[![Test and Release](https://github.com/bifravst/bdd-markdown/actions/workflows/test-and-release.yaml/badge.svg)](https://github.com/bifravst/bdd-markdown/actions/workflows/test-and-release.yaml)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com)\n[![@commitlint/config-conventional](https://img.shields.io/badge/%40commitlint-config--conventional-brightgreen)](https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-conventional)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier/)\n[![ESLint: TypeScript](https://img.shields.io/badge/ESLint-TypeScript-blue.svg)](https://github.com/typescript-eslint/typescript-eslint)\n\nWrite BDD tests in Markdown.\n\n## Idea\n\nWriting BDD tests should be more comfortable\n[than this](https://github.com/bifravst/cloud-e2e-bdd-test-runner-example-js/blob/ca4f6e8c517c13f1c88abfdb6426c8ed6fe730e7/features/Webhook.feature),\nso why not use Markdown? It can look\n[like this](./parser/test-data/feature/Example.feature.md).\n\n- it is a well supported document format, many tools like auto-formatters\n  already exist\n- it provide good tools to structure a hierarchical document\n- it has support for embedding source code / JSON payloads, and even tables\n- front matter can be used for feature-level configuration\n\n## History\n\nWork on the original BDD e2e feature runner began in 2018, and the project has\nbeen proved very useful for testing cloud-native solutions. Read more about the\noriginal idea\n[here](https://github.com/bifravst/cloud-e2e-bdd-test-runner-js#motivation).\nHowever, the implementation had some shortcomings. Especially understanding test\nresults and the way state and retries were handled was not optimal. In addition\nwas the old codebase itself not sufficiently covered with tests. Therefore this\nproject was initiated in 2022, with four years of experience authoring and\nrunning tests. With a fresh set of eyes, the way to write test was complete\nchanged from Gherkin to Markdown which called for releasing it as a standalone\nproject.\n\n## Examples\n\n- [Demo of supported syntax](./parser/test-data/feature/Example.feature.md)\n- [Gherkin `Rule` keyword](./parser/test-data/feature/Highlander.feature.md)\n- [Mars Rover Kata](./examples/mars-rover/MarsRover.feature.md) (this\n  demonstrates the `Soon` keyword which retries steps)  \n  Run: `$(set -o pipefail \u0026\u0026 npx tsx examples/mars-rover/tests.ts | npx tsx reporter/console-cli.ts)`\n- [Firmware UART log assertions](./examples/firmware/RunFirmware.feature.md)\n  (this demonstrates the use of the `Context`, which is a global object\n  available to provide run-time settings to the test run, which replace\n  placeholders in step titles and codeblocks.)  \n  Run: `$(set -o pipefail \u0026\u0026 npx tsx examples/firmware/tests.ts | npx tsx reporter/console-cli.ts)`\n\n## Test eventual consistent systems using the `Soon` keyword\n\nLet's have a look at this scenario:\n\n```markdown\n# To Do List\n\n## Create a new todo list item\n\nGiven I create a new task named `My item`\n\nThen the list of tasks should contain `My item`\n```\n\nWhat if you are testing a todo list system, that is eventually consistent?\n\nMore specifically: creating a new task happens through a `POST` request to an\nAPI that returns a `202 Accepted` status code.\n\nThe system does not guarantee that task you've just created is _immediately_\navailable.\n\nThe `Then` assertion will fail, because it is executed immediately.\n\nFor testing eventual consistent systems, we need to either wait a reasonable\nenough time or retry the assertion.\n\nHowever, if there are many similar assertions in your test suite will quickly\nadd up to long run times.\n\nTherefore the most efficient solution is to retry the assertion until it passes,\nor times out. This way a back-off algorithm can be used to wait increasing\nlonger times and many tries during the test run will have the least amount of\nimpact on the run time.\n\nImplementing the appropriate way of retrying is left to the implementing step,\nhowever you are encourage to mark these eventual consisted steps using the\n`Soon` keyword.\n\n## Control feature execution order via dependencies\n\nBy default the features are loaded in no particular order. You _may_ attempt to\norder them using a naming convention, however this can enforce a forced ranking\nof all features, and over time files might need to get renamed to make room for\nnew features.\n\nIn this project, features can specify a dependency to one or more other features\nin their front matter, and after parsing all features files, they will be sorted\n[topologically](https://en.wikipedia.org/wiki/Topological_sorting).\n\nFeatures can define their dependencies via the `needs` keyword:\n\n```markdown\n---\nneeds:\n  - First feature\n---\n\n# Second\n\n## Scenario\n\nGiven this is the first step\n```\n\nThis feature will be run after a feature with the name `First feature`\n\n## Running features _first_ and _last_\n\nIn addition, features can specify whether they should be run before all other\nfeatures, or after all. Multiple keywords can have this flag, but dependencies\nwill take precedence.\n\n### Example: running a feature before all others\n\n```markdown\n---\norder: first\n---\n\n# Runs before all others\n\n## Scenario\n\nGiven this is the first step\n```\n\n### Example: running a feature after all others:\n\n```markdown\n---\norder: last\n---\n\n# Runs before all others\n\n## Scenario\n\nGiven this is the first step\n```\n\n## Skipping features\n\nFeatures can be skipped, this will also skip all dependent and transiently\ndependent features.\n\n### Example: skipping a feature\n\n```markdown\n---\nrun: never\n---\n\n# This feature never runs\n\n## Scenario\n\nGiven this is the first step\n```\n\n## Running only specific features\n\nFeatures can be run exclusively, this will also run all dependent and\ntransiently dependent features. All other features not marked as `run: only`\nwill be skipped.\n\n### Example: running only a specific feature\n\n```markdown\n---\nrun: only\n---\n\n# This feature runs, all other features are skipped\n\n## Scenario\n\nGiven this is the first step\n```\n\n## Variants\n\nVariants (defined in the frontmatter of a feature) can be used to run the same\nfeature in different variants. For every entry in variants, the feature file is\nrun. ([Example](./runner/test-data/runSuite/variants/Variants.feature.md))\n\n## Number placeholders in JSON\n\nFor JSON code-blocks there is a special notation to replace number placeholders,\nwhile still maintaining the JSON syntax and allow for formatters like prettier\nto format the code-block.\n\n````markdown\nGiven `v` is the number `42`\n\nAnd I store this in `result`\n\n```json\n{ \"foo\": \"$number{v}\" }\n```\n\nThen `result` should match\n\n```json\n{ \"foo\": 42 }\n```\n````\n\n## Markdown Reporter\n\nIt includes a markdown reporter, which will turn the suite result into markdown,\nsuitable for displaying it as\n[GitHub Actions job summaries](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary).\n\nExample: [Mars Rover Report](./reporter/test-data/mars-rover.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbifravst%2Fbdd-markdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbifravst%2Fbdd-markdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbifravst%2Fbdd-markdown/lists"}