{"id":20295989,"url":"https://github.com/kkrull/javaspec","last_synced_at":"2025-04-11T12:05:42.700Z","repository":{"id":19018776,"uuid":"22241929","full_name":"kkrull/javaspec","owner":"kkrull","description":"Spec-style testing for Java","archived":false,"fork":false,"pushed_at":"2023-03-07T20:29:44.000Z","size":1776,"stargazers_count":8,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T08:21:49.464Z","etag":null,"topics":["java","junit","specifications","testing"],"latest_commit_sha":null,"homepage":"https://javaspec.info","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kkrull.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2014-07-25T02:23:57.000Z","updated_at":"2024-05-06T15:50:09.000Z","dependencies_parsed_at":"2024-11-14T15:39:44.022Z","dependency_job_id":"9dbe1364-cb35-4607-b7b6-195d559c3a1d","html_url":"https://github.com/kkrull/javaspec","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kkrull%2Fjavaspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kkrull%2Fjavaspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kkrull%2Fjavaspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kkrull%2Fjavaspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kkrull","download_url":"https://codeload.github.com/kkrull/javaspec/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248395477,"owners_count":21096769,"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":["java","junit","specifications","testing"],"created_at":"2024-11-14T15:36:54.145Z","updated_at":"2025-04-11T12:05:42.677Z","avatar_url":"https://github.com/kkrull.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- omit in toc --\u003e\n# JavaSpec\n\nJavaSpec 2 is a library for the Java Virtual Machine that lets you use lambdas\nto write specifications (unit tests) that run on the JUnit Platform.\nSpecifications run anywhere JUnit 5 runs: Gradle, JUnit Platform Console, or\nyour favorite IDE.  It does the same thing you can do with JUnit 5, but with a\nsyntax that is more descriptive–and more concise–than its JUnit counterpart.\n\nJavaSpec 2 should work just about anywhere JUnit 5 works.  All you have to do is\nadd a compile dependency for the API (providing the new spec syntax) and a\nruntime dependency for a JUnit Test Engine that knows how to turn specifications\ninto JUnit tests.\n\n_TL;DR - it's kind of like the syntax from [Jest][jest], [Mocha][mocha], and\n[Jasmine][jasmine], but for Java._\n\n**Note that this documentation is for the new version of JavaSpec**.  It uses a\ndifferent syntax than [JavaSpec 1.x][javaspec-1x].\n\n- [What does JavaSpec do?](#what-does-javaspec-do)\n- [Getting Started](#getting-started)\n  - [Add dependencies](#add-dependencies)\n  - [Write Specs](#write-specs)\n  - [Run specs with Gradle](#run-specs-with-gradle)\n  - [Run specs in your IDE](#run-specs-in-your-ide)\n  - [Run specs with JUnit Platform Console](#run-specs-with-junit-platform-console)\n  - [More helpful syntax](#more-helpful-syntax)\n- [Support](#support)\n  - [Known Issues](#known-issues)\n\n![Build Status](https://github.com/kkrull/javaspec/actions/workflows/verify.yml/badge.svg?branch=main)\n\n[jasmine]: https://jasmine.github.io/\n[javaspec-1x]: http://javaspec.info\n[jest]: https://jestjs.io/\n[mocha]: https://mochajs.org/\n\n## What does JavaSpec do?\n\nJavaSpec helps you take a JUnit test that looks like this...\n\n```java\nclass GreeterTest {\n  @Nested\n  @DisplayName(\"#greet\")\n  class greet {\n    @Test\n    @DisplayName(\"greets the world, given no name\")\n    void givenNoNameGreetsTheWorld() {\n      Greeter subject = new Greeter();\n      assertEquals(\"Hello world!\", subject.greet());\n    }\n\n    @Test\n    @DisplayName(\"greets a person by name, given a name\")\n    void givenANameGreetsThePersonByName() {\n      Greeter subject = new Greeter();\n      assertEquals(\"Hello Adventurer!\", subject.greet(\"Adventurer\"));\n    }\n  }\n}\n```\n\n...and declare it with lambdas instead:\n\n```java\n@Testable\npublic class GreeterSpecs implements SpecClass {\n  public void declareSpecs(JavaSpec javaspec) {\n    javaspec.describe(Greeter.class, () -\u003e {\n      javaspec.describe(\"#greet\", () -\u003e {\n        javaspec.it(\"greets the world, given no name\", () -\u003e {\n          Greeter subject = new Greeter();\n          assertEquals(\"Hello world!\", subject.greet());\n        });\n\n        javaspec.it(\"greets a person by name, given a name\", () -\u003e {\n          Greeter subject = new Greeter();\n          assertEquals(\"Hello Adventurer!\", subject.greet(\"Adventurer\"));\n        });\n      });\n    });\n  }\n}\n```\n\nThis results in test output that looks like this:\n\n```text\nGreeter\n\n  #greet\n\n    ✔ greets the world, given no name\n    ✔ greets a person by name, given a name\n```\n\nUsing this syntax, you can describe behavior with plain language without having\nto add extra decorators or name tests twice (one machine-readable method name\nand one human readable `@DisplayName`).\n\nIf you're into testing, like being descriptive, and don't mind lambdas: this\nmight be the testing library for you.\n\n## Getting Started\n\n### Add dependencies\n\nTo start using JavaSpec, add the following dependencies:\n\n1. `testImplementation 'info.javaspec:javaspec-api'`: the syntax you need to\n   declare specs.  This needs to be on the classpath you use for compiling test\n   sources and on the one you use when running tests.\n1. `testRuntimeOnly 'info.javaspec:javaspec-engine'`: the `TestEngine` that runs\n   specs.  This only needs to be on the classpath you use at runtime when\n   running tests.\n1. some kind of library for assertions.  For example:\n   `testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'`\n\nIn Gradle, that means adding the following to your `build.gradle` file:\n\n```groovy\n//build.gradle\ndependencies {\n  //Add these dependencies for JavaSpec\n  testImplementation 'info.javaspec:javaspec-api:\u003cversion\u003e'\n  testRuntimeOnly 'info.javaspec:javaspec-engine:\u003cversion\u003e'\n\n  //Add an assertion library (JUnit 5's assertions shown here)\n  testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'\n}\n```\n\n### Write Specs\n\nStart writing specs with JavaSpec the same way you would with JUnit: by making a\nnew class.  It is often helpful for the name of that class to end in something\nlike `Specs`, but JavaSpec does not require following any particular convention.\n\nOnce you have your new spec class:\n\n1. Implement `SpecClass` (`info.javaspec:javaspec-api`) and\n   `#declareSpecs(JavaSpec)`.\n2. Inside `declareSpecs`, call `JavaSpec#describe` with:\n   1. some description of what you are testing (or the class itself)\n   2. a lambda to hold all the specifications for what you're describing\n3. Inside the `describe` lambda, call `JavaSpec#it` with:\n   1. some description of the expected behavior\n   2. a lambda with [Arrange Act Assert][c2wiki-arrange-act-assert] in it, like\n      in any other test\n\nPut it all together, and a basic spec class looks something like this:\n\n```java\nimport info.javaspec.api.JavaSpec;\nimport info.javaspec.api.SpecClass;\n\npublic class GreeterSpecs implements SpecClass {\n  public void declareSpecs(JavaSpec javaspec) {\n    javaspec.describe(Greeter.class, () -\u003e {\n      javaspec.describe(\"#greet\", () -\u003e {\n        javaspec.it(\"greets the world, given no name\", () -\u003e {\n          Greeter subject = new Greeter();\n          assertEquals(\"Hello world!\", subject.greet());\n        });\n      });\n    });\n  }\n}\n```\n\n[c2wiki-arrange-act-assert]: http://wiki.c2.com/?ArrangeActAssert\n\n### Run specs with Gradle\n\nOnce you have the right dependencies, you need a way to run specs on the JUnit\nPlatform.  This section describes how to do that in a Gradle project.\n\nAs with regular JUnit tests, you still need to add this to your `build.gradle`:\n\n```groovy\n//build.gradle\ntest {\n  useJUnitPlatform()\n}\n```\n\nThen it's `./gradlew test` to run specs, like usual.\n\nFor extra-pretty console output, try adding the [Gradle Test Logger\nPlugin][github-gradle-test-logger-plugin] with the `mocha` theme.\n\n[github-gradle-test-logger-plugin]: https://github.com/radarsh/gradle-test-logger-plugin\n\n### Run specs in your IDE\n\nIf you have an IDE that can already run JUnit 5 tests, there's a good chance\nthat it can also run JavaSpec by following these steps:\n\n1. Make sure you have added the dependencies listed in\n   [Add Dependencies](#add-dependencies).\n2. Add the JUnit Platform Commons dependency:\n   `testImplementation 'org.junit.platform:junit-platform-commons:\u003cversion\u003e'`\n3. Add `@Testable` to each `SpecClass` that contains specifications, as a hint\n   to your IDE that this class contains some sort of tests that run on a\n   `TestEngine`.\n\nThis is usually enough for your IDE to indicate that it can run tests in a\nclass, once it has had time to download any new dependencies and index your\nsources.\n\nFor example:\n\n```java\nimport org.junit.platform.commons.annotation.Testable;\n\n@Testable //Add this IDE hint\npublic class GreeterSpecs implements SpecClass {\n  public void declareSpecs(JavaSpec javaspec) {\n    javaspec.describe(Greeter.class, () -\u003e {\n      ...\n    });\n  }\n}\n```\n\n### Run specs with JUnit Platform Console\n\nSince this is just another `TestEngine` for the JUnit Platform, you can also run\nspecs on the [JUnit Platform Console][junit-console-launcher] as seen in this\nshell snippet:\n\n```shell\njunit_console_jar='junit-platform-console-standalone-1.8.1.jar'\njava -jar \"$junit_console_jar\" \\\n  --classpath=info.javaspec.javaspec-api-0.0.1.jar \\\n  --classpath=\u003ccompiled production code and its dependencies\u003e \\\n  --classpath=\u003ccompiled specs and their dependencies\u003e \\\n  --classpath=info.javaspec.javaspec-engine-0.0.1.jar \\\n  --include-engine=javaspec-engine \\\n  ...\n```\n\nSpecifically, this means running passing the following arguments to JUnit\nPlatform Console, on top of whichever options you are already using:\n\n- `--classpath` for `javaspec-api` and `javaspec-engine`\n- `--include-engine=javaspec-engine`\n\n[junit-console-launcher]: https://junit.org/junit5/docs/current/user-guide/#running-tests-console-launcher\n\n### More helpful syntax\n\nThe JavaSpec API supports a few more things that developers often need to do\nwhile testing:\n\n- `JavaSpec#pending`: Stub in a pending / todo item reminding you to test\n  something later.  JUnit Platform skips the resulting test.\n- `JavaSpec#skip`: Skip running a spec that already has a defined procedure.\n  This can be useful for allowing a spec to be _temporarily_ disabled while you\n  fix something else.\n\nThe API also has a variety of ways to help you organize your specs:\n\n- `JavaSpec#describe` is used most often to define the class and methods being\n  tested, but it is really just a general-purpose container with no special\n  behavior of its own.\n- `JavaSpec#context` can be useful for defining any circumstances under which\n  some specifications apply.  It's not implemented any differently from\n  `#describe`, so use `#context` if you feel like it reads better.\n- `JavaSpec#given` is like the other containers, except that it adds the word\n  \"given\" before your description.  For example\n  `javaspec.given(\"a name\", () -\u003e ...)`\n  results in a container called `given a name`.\n\nNote that these containers exist simply to help you be as descriptive and\norganized as you need to be.  Try to use them judiciously to enhance human\nreadability.\n\n## Support\n\nFeel free to file an [Issue on Github][github-javaspec-issues] if you have any\nquestions about using JavaSpec, or if something is not working the way you\nexpected.\n\n[github-javaspec-issues]: https://github.com/kkrull/javaspec/issues\n\n### Known Issues\n\n- There is not an equivalent of `@BeforeEach` and `@AfterEach` yet, for defining\n  shared setup and teardown around a series of related specs.\n- Running specs in Gradle causes specs to be reported under `default-package`\n  and `UnknownClass` instead of their actual package and class names.  This\n  applies to HTML test reports in `build/reports/tests/test`.\n- Running specs in Gradle with the [Gradle Test Logger\n  Plugin][github-gradle-test-logger-plugin] causes the name of the spec class to\n  be printed _after_ all the specs in the class have run, instead of _before_\n  it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkkrull%2Fjavaspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkkrull%2Fjavaspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkkrull%2Fjavaspec/lists"}