{"id":37023364,"url":"https://github.com/kidsoncoffee/cheesecakes","last_synced_at":"2026-01-14T02:48:18.074Z","repository":{"id":45534864,"uuid":"175961394","full_name":"kidsoncoffee/cheesecakes","owner":"kidsoncoffee","description":"Cheesecakes is a data-driven testing framework built on top of Junit","archived":false,"fork":false,"pushed_at":"2022-11-16T09:20:57.000Z","size":573,"stargazers_count":5,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-08T08:55:41.949Z","etag":null,"topics":["behavior-driven-development","data-driven-tests","java","junit","test"],"latest_commit_sha":null,"homepage":"","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/kidsoncoffee.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}},"created_at":"2019-03-16T11:07:27.000Z","updated_at":"2020-03-06T18:02:53.000Z","dependencies_parsed_at":"2023-01-23T10:15:38.579Z","dependency_job_id":null,"html_url":"https://github.com/kidsoncoffee/cheesecakes","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/kidsoncoffee/cheesecakes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidsoncoffee%2Fcheesecakes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidsoncoffee%2Fcheesecakes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidsoncoffee%2Fcheesecakes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidsoncoffee%2Fcheesecakes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kidsoncoffee","download_url":"https://codeload.github.com/kidsoncoffee/cheesecakes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidsoncoffee%2Fcheesecakes/sbom","scorecard":{"id":559652,"data":{"date":"2025-08-11","repo":{"name":"github.com/kidsoncoffee/cheesecakes","commit":"664967c19ceb849959fecbf736c4eb6cdc7ce3ce"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-j288-q9x7-2f5v"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T13:18:01.224Z","repository_id":45534864,"created_at":"2025-08-20T13:18:01.224Z","updated_at":"2025-08-20T13:18:01.224Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["behavior-driven-development","data-driven-tests","java","junit","test"],"created_at":"2026-01-14T02:48:17.339Z","updated_at":"2026-01-14T02:48:18.061Z","avatar_url":"https://github.com/kidsoncoffee.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"images/cheesecakes_logo.png\" alt=\"Cheesecakes\" width=\"400\"\u003e\n  \u003cbr\u003e\n  Cheesecakes\n  \u003cbr\u003e\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003eA data-driven testing framework built on top of \u003ca href=\"https://junit.org/junit4/\" target=\"_blank\"\u003eJunit\u003c/a\u003e.\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://oss.sonatype.org/#nexus-search;quick~kidsoncoffee\"\u003e\n    \u003cimg alt=\"Sonatype Nexus (Releases)\" src=\"https://img.shields.io/nexus/r/https/oss.sonatype.org/com.github.kidsoncoffee/cheesecakes.svg?style=popout-square\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://circleci.com/gh/kidsoncoffee/workflows/cheesecakes\"\u003e\n      \u003cimg src=\"https://circleci.com/gh/kidsoncoffee/cheesecakes.svg?style=svg\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/kidsoncoffee/cheesecakes/issues\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/issues/kidsoncoffee/cheesecakes.svg\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\"/\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003ca href=\"#\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/contributions-welcome-orange.svg\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://gitter.im/cheesecakes-ddt\"\u003e\n    \u003cimg src=\"https://badges.gitter.im/cheesecakes-ddt.svg\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://saythanks.io/to/kidsoncoffee\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/SayThanks.io-%E2%98%BC-1EAEDB.svg\"/\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#key-features\"\u003eKey features\u003c/a\u003e •\n  \u003ca href=\"#quickstart\"\u003eQuickstart\u003c/a\u003e •\n  \u003ca href=\"#deep-dive\"\u003eDeep dive\u003c/a\u003e •\n  \u003ca href=\"#download\"\u003eDownload\u003c/a\u003e •\n  \u003ca href=\"#related\"\u003eRelated\u003c/a\u003e \n\u003c/p\u003e\n\n## Key Features\n\n* Write test scenarios using *data-driven* tables, with the test method **Javadoc** as the single source of information\n* Injects requisites and expectations directly into the test method parameters\n* Use auto-generated builders to write scenarios programmatically\n\n## Quickstart\n\nThe following steps goes through all aspects of creating *data-driven* scenarios using **Cheesecakes**. \n\nAll throughout the instructions are links to more advanced features or in-depth explanation of a particular concept. \n\nWe assume that **you are already familiar with Junit** (if that's not the case give [this](https://junit.org/junit4/) a reading) but if you never used **Junit parameterized tests**, it is recommended that you follow this quickstart and then go back and customize to fit your needs.\n\n### Import the dependency\n\n#### Maven\n\n```diff\n\u003cdependencies\u003e\n\n+    \u003cdependency\u003e\n+      \u003cgroupId\u003ecom.github.kidsoncoffee\u003c/groupId\u003e\n+      \u003cartifactId\u003echeesecakes\u003c/artifactId\u003e\n+      \u003cversion\u003e...\u003c/version\u003e\n+      \u003cscope\u003etest\u003c/scope\u003e\n+    \u003c/dependency\u003e\n\n\u003c/dependencies\u003e\n```\n\n#### Gradle\n\n```diff\ndependencies {\n\n+  testImplementation 'com.github.kidsoncoffee:cheesecakes:...'\n\n}\n```\n\n### Add the custom runner to your Junit test class\n\n```diff\npackage examples;\n\n+ import com.kidsoncoffee.cheesecakes.runner.Cheesecakes;\nimport org.junit.Test;\n+ import org.junit.runner.RunWith;\n\n+ @RunWith(Cheesecakes.class)\npublic class MyDataDrivenExampleTest {\n\n  /**\n   * Checks that the first and last name are concatenated correctly.\n   */\n  @Test\n  public void concatenatesSuccessfully() {\n\n  }\n}\n```\n\n### Write the test's scenario examples\n\n```diff\npackage examples;\n\nimport com.kidsoncoffee.cheesecakes.runner.Cheesecakes;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n@RunWith(Cheesecakes.class)\npublic class MyDataDrivenExampleTest {\n\n  /**\n   * Checks that the first and last name are concatenated correctly.\n+   *\n+   * \u003cpre\u003e\n+   * Examples:\n+   *\n+   * firstName | lastName | completeName\n+   * --------- | -------- | --------------\n+   * John      | Doe      | John Doe\n+   * Exene     | Cervenka | Exene Cervenka\n+   * \u003c/pre\u003e\n   */\n  @Test\n  public void concatenatesSuccessfully() {\n\n  }\n}\n```\n\nThis step can be done after writing the test logic as well.\n\n### Write the test case logic\n\n```diff\npackage examples;\n\n+ import com.kidsoncoffee.cheesecakes.Parameter.Expectation;\n+ import com.kidsoncoffee.cheesecakes.Parameter.Requisite;\nimport com.kidsoncoffee.cheesecakes.runner.Cheesecakes;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n@RunWith(Cheesecakes.class)\npublic class MyDataDrivenExampleTest {\n\n  /**\n   * Checks that the first and last name are concatenated correctly.\n   *\n   * \u003cpre\u003e\n   * Examples:\n   *\n   * firstName | lastName | completeName\n   * --------- | -------- | --------------\n   * John      | Doe      | John Doe\n   * Exene     | Cervenka | Exene Cervenka\n   * \u003c/pre\u003e\n   */\n  @Test\n-   public void concatenatesSuccessfully() {\n+   public void concatenatesSuccessfully(\n+       @Requisite final String firstName,\n+       @Requisite final String lastName,\n+       @Expectation final String completeName) {\n+     final String actualCompleteName;\n+\n+     when:\n+     actualCompleteName = String.format(\"%s %s\", firstName, lastName);\n\n+     then:\n+     assert actualCompleteName.equals(completeName);\n  }\n}\n\n```\n\n### Run the tests\n\nNow you should be able to run this test successfully and see that each **scenario example** runs independently.\n\n\u003cimg src=\"images/quickstart_intellij_success.png\" alt=\"Successfull on Intellij\"\u003e\n\u003cbr/\u003e\n\u003cimg src=\"images/quickstart_maven_success.png\" alt=\"Successfull on Maven\"\u003e\n\n* [How to run tests in Intellij](https://www.jetbrains.com/help/idea/performing-tests.html)\n* [How to run tests in Maven](http://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html)\n\n## Deep Dive\n\n### Concepts\n\nIn general, *Cheesecakes* concepts tries to be close to *[Gherkin](https://cucumber.io/docs/gherkin/reference/)* concepts, but as it needs to translate to *Java* code as well, some simplification needed to happen.\n\n#### Feature or Feature test class\n\nIn *Gherkin*: \n\u003e The purpose of the Feature keyword is to provide a high-level description of a software feature, and to group related scenarios.\n\nIn *Cheesecakes*, **a *Feature* is a test class that groups related scenarios.**\n\nFor example, a class named *Aggregator*, being the unit under test, has an accompanying class named *AggregatorTest*, which contains all test cases related to that unit. This *AggregatorTest* class is the *Feature test class*.\n\n#### Scenario or Scenario method\n\nIn *Gherkin*:\n\n\u003e This is a concrete example that illustrates a business rule. It consists of a list of steps.\n\u003e The keyword Scenario is a synonym of the keyword Example.\n\nIn *Cheesecakes*, **a *Scenario* is a test method that describe an expected behavior of the unit under test**. It also consists of a list of steps. \n\nA *Scenario* may be parameterized to indicate requisites and expectation values that are important for the execution of that test case. \n\nA *Scenario* may be executed more than once but with different input values.\n\n#### Example\n\nIn *Gherkin*, a *Scenario* and an *Example* are synonyms but they also have a keyword to describe something more close to an *Example* in *Cheesecakes*. This is how a *Scenario Outline* is described:\n\n\u003e The Scenario Outline keyword can be used to run the same Scenario multiple times, with different combinations of values.\n\nIn *Cheesecakes*, **an *Example* is the definition of requisites and expectations values of a *Scenario***.\n\nThere are a couple of different ways to create *Examples* for a given *Scenario*:\n* Programmatically with a builder-like syntax\n* Through a data-driven table in the *Scenario* method *Javadoc*.\n\n### Creating an *Example* for a *Scenario*\n\n#### Data tables\n\nAs shown in the *Quickstart*, data tables are probably the most effective way for writing and reading test cases that have similar behavior for different requisites and expectations.\n\n```java\n/**\n * \u003cpre\u003e                                                   // Pre-formatted text prevents the IDE from formatting\n * Examples:                                               // Mandatory line with the keyword Examples:\n *                                                         // Empty lines are ignored\n * requisiteA | requisiteB | expectationA | expectationB   // The data table header row\n * ---------- | ---------- | ------------ | ------------   // The data table separator row\n * 1          | 2          | A            | B              // The first example\n * 3          | 4          | X            | Y              // The second example\n * \u003c/pre\u003e\n */                                                         \n```\n\nThe example are written on the *Scenario* method *Javadoc*, but needs to follow these guidelines:\n* The data table should be the last thing in the *Javadoc* (beside closing `\u003cpre\u003e`, `@param`, `@return` and other usual tags).\n* Just before the data table the keyword `Examples:` should be present (empty lines are ignored).\n* The data table should contain a *header row*, a *separator row* and at least one *example row*.\n* The data table columns should be separated by:\n  * A single pipe symbol (`|`) for all values, except for the case below.\n* The data table should have the same number of columns\n\nOptionally but recommended, wrap all above in `\u003cpre\u003e` tags, so you can control formatting.\n\n#### Programmatically\n\n##### One *Example* by field\n\nDuring the annotation processing phase in the build, some classes are auto generated based on the *Scenario* method signature. This gives a lot of flexibility to the developer and can be very powerful when generating requisites and expectations values dynamically.\n\nFor example, for the *Feature* class in the *Quickstart*, the same *Examples* could be written like this:\n\n```java\npackage examples;\n\nimport com.kidsoncoffee.cheesecakes.Example;\nimport com.kidsoncoffee.cheesecakes.Parameter.Expectation;\nimport com.kidsoncoffee.cheesecakes.Parameter.Requisite;\nimport com.kidsoncoffee.cheesecakes.runner.Cheesecakes;\nimport examples.MyProgrammaticallyExampleTest_ExampleBuilder.ConcatenatesSuccessfully;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n@RunWith(Cheesecakes.class)\npublic class MyProgrammaticallyExampleTest {\n\n  private static Example.Builder JOHN_DOE_EXAMPLE =\n      ConcatenatesSuccessfully.given()\n          .firstName(\"John\")\n          .lastName(\"Doe\")\n          .then()\n          .completeName(\"John Doe\")\n          .getExample();\n\n  private static Example.Builder EXENE_CERVENKA_EXAMPLE =\n      ConcatenatesSuccessfully.given()\n          .firstName(\"Exene\")\n          .lastName(\"Cervenka\")\n          .then()\n          .completeName(\"Exene Cervenka\")\n          .getExample();\n\n  @Test\n  public void concatenatesSuccessfully(\n      @Requisite final String firstName,\n      @Requisite final String lastName,\n      @Expectation final String completeName) {\n    final String actualCompleteName;\n\n    when:\n    actualCompleteName = String.format(\"%s %s\", firstName, lastName);\n\n    then:\n    assert actualCompleteName.equals(completeName);\n  }\n}\n```\n\nAn auto-generated *Example* class can be instantiated following the pattern: `\u003cNAME_OF_THE_FEATURE_CLASS\u003e_ExampleBuilder.\u003cNAME_OF_THE_SCENARIO_METHOD\u003e.given()`. For example, looking at the example above, for the *Feature* class **MyTest** and *Scenario* method **test**, an *Example* class is instantiated with **MyProgrammaticallyExampleTest_ExampleBuilder.ConcatenatesSuccessfully.given()**. Note that the *Scenario* method equivalent in the *Example* class is in *Pascal Case*.\n\nIt is required that the *Example* field in the *Feature* class is declared as **static**.\n\n##### Multiple *Examples* by field\n\n```java\npackage examples;\n\nimport com.kidsoncoffee.cheesecakes.Example;\nimport com.kidsoncoffee.cheesecakes.Parameter;\nimport com.kidsoncoffee.cheesecakes.runner.Cheesecakes;\nimport examples.MyProgrammaticallyMultipleExamplesTest_ExampleBuilder.ConcatenatesSuccessfully;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static com.kidsoncoffee.cheesecakes.Example.multiple;\n\n@RunWith(Cheesecakes.class)\npublic class MyProgrammaticallyMultipleExamplesTest {\n\n  private static Example.Multiple SUCCESS_EXAMPLES =\n      multiple(\n          ConcatenatesSuccessfully.given()\n              .firstName(\"John\")\n              .lastName(\"Doe\")\n              .then()\n              .completeName(\"John Doe\")\n              .getExample(),\n          ConcatenatesSuccessfully.given()\n              .firstName(\"Exene\")\n              .lastName(\"Cervenka\")\n              .then()\n              .completeName(\"Exene Cervenka\")\n              .getExample());\n\n  @Test\n  public void concatenatesSuccessfully(\n      @Parameter.Requisite final String firstName,\n      @Parameter.Requisite final String lastName,\n      @Parameter.Expectation final String completeName) {\n    final String actualCompleteName;\n\n    when:\n    actualCompleteName = String.format(\"%s %s\", firstName, lastName);\n\n    then:\n    assert actualCompleteName.equals(completeName);\n  }\n}\n\n```\n\nYou can also use the `Example.multiple` aggregator to have only one *Example* static field declared. Even though that may turn into identation hell in some cases, it might help legibility in others.\n\nThis can be used to generate test cases dynamically as well.\n\n### Parameters injection\n\nIf you are writing your examples with the *builder-like* syntax you are already writing code to match the types of the parameters in the *Scenario* method. But if you are writing them with data tables, you will need to convert that *String* value into the appropriate type of the *Scenario* method parameters.\n\n#### Common Java types\n\nFor the most common types, **Cheesecakes** provides conversion out-of-the-box.\n\n* `short` and `Short`\n* `byte` and `Byte`\n* `int`and `Integer`\n* `long`and `Long`\n* `float` and `Float`\n* `double` and `Double`\n* `boolean` and `Boolean`\n* `char` and `String`\n* `Class`\n* `enum`\n\n#### Custom types\n\nTo register custom type converter is easy:\n\n```java\npackage examples;\n\nimport com.kidsoncoffee.cheesecakes.Parameter;\nimport com.kidsoncoffee.cheesecakes.Parameter.Conversion;\nimport com.kidsoncoffee.cheesecakes.Parameter.Expectation;\nimport com.kidsoncoffee.cheesecakes.Parameter.Requisite;\nimport com.kidsoncoffee.cheesecakes.runner.Cheesecakes;\nimport org.apache.commons.lang3.text.WordUtils;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport java.util.function.Function;\n\n@RunWith(Cheesecakes.class)\npublic class MyCustomConverterExampleTest {\n\n  /**\n   * Checks that the first and last name are concatenated correctly.\n   *\n   * \u003cpre\u003e\n   * Examples:\n   *\n   * firstName | lastName | completeName\n   * --------- | -------- | --------------\n   * JOHN      | DOE      | John Doe\n   * \u003c/pre\u003e\n   */\n  @Test\n  public void concatenatesSuccessfully(\n      @Requisite @Conversion(PascalCaseConverter.class) final String firstName,\n      @Requisite @Conversion(PascalCaseConverter.class) final String lastName,\n      @Expectation final String completeName) {\n    final String actualCompleteName;\n\n    when:\n    actualCompleteName = String.format(\"%s %s\", firstName, lastName);\n\n    then:\n    assert actualCompleteName.equals(completeName);\n  }\n\n  private class PascalCaseConverter extends Parameter.Converter\u003cString\u003e {\n\n    @Override\n    public Class\u003cString\u003e getTargetType() {\n      return String.class;\n    }\n\n    @Override\n    public Function\u003cParameter.Convertible, String\u003e getConverter() {\n      return raw -\u003e WordUtils.capitalize(raw.getValue().toLowerCase());\n    }\n  }\n}\n```\n\nLooking at the example above, for a parameter to be specifically converted, is required:\n* The custom converter to implement `Parameter.Converter`\n* The parameter to be converted to be annotated with `@Parameter.Conversion` and the class of the custom converter to be passed as the value to the converter.\n\n## Release\n\n* https://central.sonatype.org/pages/apache-maven.html\n* https://central.sonatype.org/pages/releasing-the-deployment.html\n\n## Related\n\n* [Data driven testing @ wikipedia](https://en.wikipedia.org/wiki/Data-driven_testing)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidsoncoffee%2Fcheesecakes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkidsoncoffee%2Fcheesecakes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidsoncoffee%2Fcheesecakes/lists"}