{"id":19140078,"url":"https://github.com/circleci/circleci.test","last_synced_at":"2025-05-09T23:32:23.075Z","repository":{"id":54678736,"uuid":"90695954","full_name":"circleci/circleci.test","owner":"circleci","description":"Enhanced Clojure test runner for tests written with clojure.test","archived":true,"fork":false,"pushed_at":"2024-05-09T21:01:45.000Z","size":123,"stargazers_count":86,"open_issues_count":13,"forks_count":27,"subscribers_count":75,"default_branch":"master","last_synced_at":"2025-04-19T03:11:11.501Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/circleci.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-09T02:57:02.000Z","updated_at":"2024-10-28T16:47:15.000Z","dependencies_parsed_at":"2024-06-20T00:08:08.573Z","dependency_job_id":"30a69972-f402-4d82-b479-b9bba93c1b74","html_url":"https://github.com/circleci/circleci.test","commit_stats":{"total_commits":80,"total_committers":10,"mean_commits":8.0,"dds":0.5375,"last_synced_commit":"a667874c312bfb98071631804bc71bab459a1b3c"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Fcircleci.test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Fcircleci.test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Fcircleci.test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circleci%2Fcircleci.test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/circleci","download_url":"https://codeload.github.com/circleci/circleci.test/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253341963,"owners_count":21893546,"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-11-09T07:16:11.632Z","updated_at":"2025-05-09T23:32:22.807Z","avatar_url":"https://github.com/circleci.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# circleci.test\n\nA Clojure test-runner compatible with tests written using `clojure.test`.\n\nKeep your existing `deftest`s, but gain flexibility around how you run them.\n\n## Usage\n\nAdd `[circleci/circleci.test \"0.5.0\"]` to your `:dependencies` under `:dev`.\n\nIt's recommended to use this set of Leiningen aliases:\n\n```clj\n:aliases {\"test\" [\"run\" \"-m\" \"circleci.test/dir\" :project/test-paths]\n          \"tests\" [\"run\" \"-m\" \"circleci.test\"]\n          \"retest\" [\"run\" \"-m\" \"circleci.test.retest\"]}\n```\n\nYou can pass a selector to `lein test` (see below) or run just a list of\nindividual tests with `lein tests my.test.ns my.other.test.ns`.\n\nFrom inside a repl, you can run all loaded test namespaces with\n`(circleci.test/run-tests)` or pass in a list of symbols to just test a few\nnamespaces. Run individiual tests with `(circleci.test/test-var #'my.test.ns/my-test)`.\n\n### Selectors\n\nAs with Leiningen's built-in `test` task, you can tag tests with metadata\nthat allows you to run just a selection of your tests.\n\nYou can put a keyword argument on the command-line invocation before \nspecifying which test namespaces to run, and it will cause all `deftest`\nforms which aren't tagged with that metadata to be skipped.\n\n    $ lein run -m circleci.test :integration my.first.test.ns\n\nIf you need more flexibility in your test selectors you can define arbitrary\nselector functions in `dev-resources/circleci_test/config.clj`:\n\n```clj\n{:selectors {:all (constantly true)\n             :acceptance (fn [m] (or (:integration m) (:functional m)))\n             :default (complement :flaky)}}\n```\n\nIf you have the Leiningen `:aliases` set up as per above, you can pass\nin a test selector as a command-line argument:\n\n    $ lein test :acceptance\n\n### Reporters\n\n#### JUnit\n\nIn order to gather metadata about your test runs, you can configure\n`circleci.test` to emit output\nin [JUnit XML format](https://ant.apache.org/manual/Tasks/junitreport.html) by\nputting this in your `dev-resources/circleci_test/config.clj` file:\n\n```clj\n(require '[circleci.test.report.junit :as junit])\n\n{:test-results-dir \"target/test-results\"\n :reporters [circleci.test.report/clojure-test-reporter\n             junit/reporter]}\n```\n\nUnlike `clojure.test`, you can use more than one reporter at a time. It's\nrecommended to add your `:test-results-dir` directory to the ignored list of\nyour version control system.\n\nIf you use the junit test reporter, you can run `circleci.test.retest/-main` to\nre-run only the set of tests which previously failed. Adding an alias in\n`project.clj` is recommended:\n\n```clj\n:aliases {\"test\" [\"run\" \"-m\" \"circleci.test/dir\" :project/test-paths]\n          \"retest\" [\"run\" \"-m\" \"circleci.test.retest\"]}\n```\n\n#### CIDER\n\n`circleci.test` by default breaks [CIDER](https://cider.mx) test\nreports. To avoid this, use these settings in your\n`dev-resources/circleci_test/config.clj` to activate the CIDER test\nresult adapter:\n\n```clojure\n(require '[circleci.test.report.cider :as cider])\n\n{:reporters [circleci.test.report/clojure-test-reporter\n             cider/reporter]}\n```\n\n### Running tests from a repl\n\nUse `circleci.test/test-var` to run a single test fn:\n```clojure\n(circleci.test/test-var #'my.test.ns/my-test)\n```\n\nUse `circleci.test/run-tests` to run all the tests in one or more namespaces:\n```clojure\n(circleci.test/run-tests 'my.test.ns)\n(circleci.test/run-tests 'my.test.ns 'my.other.test.ns)\n```\n\nThere is also a `circleci.test/run-all-tests` function; however please note that\nthis only runs tests in namespaces that have already been loaded rather than\nrunning all tests that exist on disk.\n\n### Global fixtures\n\nIn addition to `:once` and `:each` fixtures from `clojure.test`, you can define\nglobal fixtures that are only run once for the entire test run, no matter how\nmany namespaces you run. This should be declared in your config file rather in\nany one individual test file though; otherwise it may not get loaded:\n\n```clj\n(require '[clojure.spec.test.alpha :as stest])\n{:global-fixture (fn [f]\n                   (stest/instrument)\n                   (myapp.db/migrate)\n                   (f))}\n```\n\nThe global fixture must return the return value of `f`. If you need to do a teardown step you must do something like this:\n\n```clj\n(require '[clojure.spec.test.alpha :as stest])\n{:global-fixture (fn [f]\n                   (stest/instrument)\n                   (myapp.db/migrate)\n                   (let [results (f)]\n                     (teardown)\n                     results))}\n```\n\n### Test Isolation\n\nClojure codebases that follow functional programming techniques should follow\nthe \"functional core/imperative shell\" model in which most functionality is \nimplemented with pure functions, while an outer layer of imperative code ties\nthings together. Ideally in this case most tests should be unit tests, which\nonly concern themselves with pure functions and do no I/O. However, it's easy\nfor impurity to accidentally sneak into a test. In order to prevent this, you\ncan use the `circleci.test.isolation/enforce` test fixture.\n\n```clj\n(use-fixtures :each (isolation/enforce))\n\n(deftest accidentally-uses-io\n  (is (re-find #\"cx\") (get-in (read-parse \"sample3\") [:body :content 3])))\n\n(def sample3 (read-sample \"sample3\"))\n\n(deftest actually-pure\n  (is (re-find #\"cx\") (get-in (parse sample3) [:body :content 3])))\n\n(deftest ^:io intentionally-uses-io\n  (let [sample3 (read-sample \"sample3\")\n        parsed (parse sample3)]\n    (is (re-find #\"cx\") (get-in parsed [:body :content 3]))))\n```\n\nThe first test is not a unit test because it calls `read-parse`, a function\nthat performs I/O. The `isolation/enforce` fixture will cause it to fail, while\nthe second one will succeed because it only calls `parse`, which is pure. The\nthird test will also pass because it has explicitly been flagged with `^:io`.\n\nThe default isolation blocks use of network and file access and whitelists\n`deftest`s which are tagged with `^:io` and `^:integration`. You can pass\narguments to `isolation/enforce` which will provide a fixture that looks for\ndifferent set of selector tags or uses a different predicate to determine\nwhich things to block:\n\n```clj\n(defn deny? [permission]\n  (instance? java.net.SocketPermission permission))\n\n(use-fixtures :each (isolation/enforce [:io :network] deny?))\n```\n\nIn this example we only block tests which use `SocketPermission`. The `deny?`\npredicate will be passed an instance of [java.security.Permission](https://docs.oracle.com/javase/8/docs/api/java/security/Permission.html)\nand must return a boolean indicating whether that permission should be denied.\nIn this case only `deftest` forms with `^:io` or `^:network` selector tags\nwill not have that restriction applied.\n\nThis feature sets the JVM's [SecurityManager](https://docs.oracle.com/javase/8/docs/api/java/lang/SecurityManager.html)\nfor the duration of each test, and will not work when testing code that sets or\notherwise assumes it has control of the system `SecurityManager`.\n\n## Differences from `clojure.test`\n* supports more than one test reporter at a time\n* includes elapsed time measured with `System/nanoTime` when reporting the end\n  of a `deftest`\n* test fixtures are run when testing a single test, not just a set of tests\n* `:once` fixtures are run exactly once per invocation, whether testing an\n  entire namespace or a single test\n* test selectors are a part of the library, not a monkeypatch\n  \n\n## Caveats\n* Invoking a test-fn directly will not run any fixtures at all, exactly like\n  `clojure.test`. This is due to behaviour from `clojure.test/deftest` and\n  can't be worked around without forcing use of a different `deftest`\n  implementation.\n\n## Code Coverage support\n\nYou can get code coverage support while using this library by using\nversion 1.0.10 or higher of [Cloverage](https://github.com/cloverage/cloverage)\nspecifying `circleci.test` as your test runner, like so:\n\n```\nlein cloverage --runner circleci.test\n```\n\n## Design goals\n\n#### Compatibility with tests written using `clojure.test`\n\nDon't force people to re-write tests just to use a different test runner.\n\nMaintain compatibility with the `clojure.test` assertion expansions such as\n[slingshot.test](https://github.com/scgilardi/slingshot/blob/release/src/slingshot/test.clj)\n\n#### Extensible test reporting\n\nMust be possible to use more than one test reporter at a time, for instance it's\ndesirable to produce Junit XML and console output during a test run.\n\n## License\n\nCopyright © 2017-2020 Circle Internet Services and contributors\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcircleci%2Fcircleci.test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcircleci%2Fcircleci.test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcircleci%2Fcircleci.test/lists"}