{"id":16419180,"url":"https://github.com/cameronhunter/find-related-tests","last_synced_at":"2025-02-24T13:28:13.925Z","repository":{"id":145461693,"uuid":"579265292","full_name":"cameronhunter/find-related-tests","owner":"cameronhunter","description":"Use an inverse dependency graph and docblock pragmas to connect code changes to related functional tests.","archived":false,"fork":false,"pushed_at":"2023-02-10T01:09:42.000Z","size":248,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-06T21:42:53.952Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cameronhunter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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}},"created_at":"2022-12-17T05:26:53.000Z","updated_at":"2022-12-19T21:29:44.000Z","dependencies_parsed_at":"2023-06-04T20:45:46.419Z","dependency_job_id":null,"html_url":"https://github.com/cameronhunter/find-related-tests","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronhunter%2Ffind-related-tests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronhunter%2Ffind-related-tests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronhunter%2Ffind-related-tests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cameronhunter%2Ffind-related-tests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cameronhunter","download_url":"https://codeload.github.com/cameronhunter/find-related-tests/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240486289,"owners_count":19809156,"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":[],"created_at":"2024-10-11T07:16:10.792Z","updated_at":"2025-02-24T13:28:13.907Z","avatar_url":"https://github.com/cameronhunter.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Find Related Tests\n\nFind tests related to changed files, using a simple tagging mechanism.\n\n## Context\n\nTesting can be broadly split into two buckets: open-box and closed-box tests.\n\nUnit tests are \"open-box\" tests, they import a piece of code and place expectations and assertions on its behavior. The\nstatic import of the code under test makes it very easy to find related tests using a dependency graph. In fact, Jest\nprovides a CLI parameter for exactly this use-case: `--findRelatedTests` ([documentation](https://jestjs.io/docs/29.0/cli#--findrelatedtests-spaceseparatedlistofsourcefiles)).\n\nFunctional tests are \"closed-box\" tests, they do _not_ import code directly making it impossible to connect a change set\nto a list of related functional tests.\n\n## Connecting the dots\n\nThis library aims to connect the dots between code changes and functional tests.\nIt does this by building a dependency graph, like shown below:\n\n![A dependency graph](./docs/diagram_1.dot.svg)\n\nAs you can see, there is an application built of files that have dependencies on\neach other. There are functional tests (which we know do _not_ have a dependency\non the application), some of which may make use of a Page Object Model (POM) to\nhelp model how to programmatically interact with the application.\n\nWe begin by adding a [docblock](https://en.wikipedia.org/wiki/Docblock) to the\ntop of any application file we're interested in functionally testing. We could\nstart with just the top-level routes, but these could be anywhere in the\napplication we want.\n\n```ts\n/**\n * @tag search\n */\n```\n\nWe can also add tags to the functional test files to specify which \"tags\" we're\ntesting. Here's an example of how we could annotate our example application:\n\n![An annotated dependency graph](./docs/diagram_2.dot.svg)\n\nNotice that we don't need to annotate every file.\n\nOK, it's time to put this into action.\n\nLet's say that a developer makes a change to `Button.js`. The library will build\nan _inverse_ dependency graph, and collect tags from all dependent files (as\nwell as the tags specified in `Button.js`).\n\n![How tags are found](./docs/diagram_3.dot.svg)\n\nBy following the inverse dependencies from `Button.js`, we can see that it is\nused in `Keyboard` and `Menu`, and those components are used in `Profiles`,\n`Search`, and `Details`. This results in these tags:\n\n```ts\n['button', 'details', 'keyboard', 'profiles', 'search'];\n```\n\nWe can use these to find all tests which contain any of these tags. For our\nchange to `Button.js`, this will be:\n\n```ts\n['button.test.js', 'details.test.js', 'keyboard.test.js', 'search.test.js', 'smoke.test.js'];\n```\n\nNotice that `smoke.test.js` is included – this is because we use the dependency\ngraph to associate tags with tests. This enables us to implicitly tag tests when\nwe use shared libraries, such as the Page Object Model.\n\nAs a second example, changing `Synopsis.js` would result in:\n\n```ts\n['browse.test.js', 'details.test.js', 'smoke.test.js'];\n```\n\nThis dramatically reduces the number of tests that we need to run, while\n_knowing_ that we're not losing coverage. We're simply testing only what needs\nto be tested.\n\nSee the tests for further examples: [test/lib.test.ts](test/lib.test.ts).\n\n## Usage\n\n```sh\nnpm install @cameronhunter/find-related-tests\n```\n\nYou can use this as a library:\n\n```ts\nimport { Project } from '@cameronhunter/find-related-tests';\n\nconst project = new Project('jest.config.js');\n\nconst changedFiles = ['application/components/Button.js'];\n\nconst relatedTests = await project.findRelatedTests(changedFiles);\n```\n\nOr as a CLI:\n\n```sh\n$ find-related-tests --config jest.config.js --file application/components/Button.js\napplication/__functional__/button.test.js\napplication/__functional__/details.test.js\napplication/__functional__/keyboard.test.js\napplication/__functional__/search.test.js\napplication/__functional__/smoke.test.js\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcameronhunter%2Ffind-related-tests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcameronhunter%2Ffind-related-tests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcameronhunter%2Ffind-related-tests/lists"}