{"id":13431778,"url":"https://github.com/stevenknox/CoreBDD","last_synced_at":"2025-03-16T12:31:22.326Z","repository":{"id":101209682,"uuid":"143512745","full_name":"stevenknox/CoreBDD","owner":"stevenknox","description":"BDD framework for xUnit.net","archived":false,"fork":false,"pushed_at":"2020-02-18T12:05:47.000Z","size":530,"stargazers_count":18,"open_issues_count":7,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-08T00:47:17.778Z","etag":null,"topics":["bdd","csharp","dotnet","netcore","netstandard","tdd","xunit"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stevenknox.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}},"created_at":"2018-08-04T08:45:57.000Z","updated_at":"2023-07-18T19:42:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"4422b2dc-c66a-4e4c-949d-32186b723927","html_url":"https://github.com/stevenknox/CoreBDD","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/stevenknox%2FCoreBDD","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stevenknox%2FCoreBDD/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stevenknox%2FCoreBDD/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stevenknox%2FCoreBDD/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stevenknox","download_url":"https://codeload.github.com/stevenknox/CoreBDD/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243869178,"owners_count":20360967,"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","csharp","dotnet","netcore","netstandard","tdd","xunit"],"created_at":"2024-07-31T02:01:05.802Z","updated_at":"2025-03-16T12:31:22.321Z","avatar_url":"https://github.com/stevenknox.png","language":"C#","funding_links":[],"categories":["Frameworks, Libraries and Tools","框架, 库和工具"],"sub_categories":["Testing","测试"],"readme":"[![NuGet version](https://badge.fury.io/nu/CoreBDD.svg)](https://www.nuget.org/packages/CoreBDD) \n\n[![SonarQube Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=stevenknox_CoreBDD\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=stevenknox_CoreBDD) \n\n[![Twitter Follow](https://img.shields.io/twitter/follow/espadrine.svg?style=social\u0026label=Follow@stevenknox101)](https://twitter.com/stevenknox101)\n\n\n# CoreBDD\n\nBDD framework for xUnit.net\n\n## Getting started with CoreBDD\n\nThere are several ways to get started with CoreBDD. You can install the dotnet project template via\n\n```ruby\n    dotnet new -i corebdd.projecttemplate\n```\n\nThen create a new folder for your test project and run\n\n```ruby\n    dotnet new corebdd\n```\n\nAlternatively you can add CoreBDD to an existing xUnit test project via the nuget package\n\n```ruby\n    dotnet add package CoreBDD\n```\n\nThere is also an optional Command Line tool for running tests with custom output, scaffolding test classes (features/scenarios/steps) and two-way code generation (Gherkin to CoreBDD tests and vice-versa). More documentation on the CLI is available at the bottom of this page.\n\n```ruby\n   dotnet tool install -g corebdd.commandline\n```\n\nFinally if you are using VSCode I have made some code-snippets available\n[available here](https://gist.github.com/stevenknox/231f1dcf775ceeeb890edc634ad551a2)\n\n## Writing CoreBDD Tests\n\nFollowing the usual calculator example, we can start with the following model to test\n \n   \n  ``` csharp\npublic class Calculator\n    {\n        public int Add(int x, int y) =\u003e x + y;\n        public int Subtract(int x, int y) =\u003e x - y;\n    }\n```\n\nWe can define a *Feature* to collate a suite of scenarios by deriving from the *Specification* base class and decorating with the *Feature* attribute. Note both constructors are required to support the different test syntax styles.\n\n  ``` csharp\n    [Feature(\"Calculator\", \n    @\"In order to avoid silly mistakes\n    As a math idiot\n    I want to be told the sum of two numbers\")]\n    public class CalculatorFeature : Specification\n    {\n         public CalculatorFeature(SpecFixture context):base(context) \n         {\n            \n         }\n         \n         public CalculatorFeature()\n         {\n            \n         }\n    }\n```\nOnce we have created our base Feature, we have several different flavours for writing tests, first we can generate a scenario-per-class (similar to Cucumber style tests) with a method for each Given/When/Then step. To do this simply inherit from the new Feature class, decorate with an Example attribute and provide Given, When, Then methods that will execute in order\n\n  ``` csharp\n    [Example(\"Add two numbers\")]\n    public class AddTwoNumbers : CalculatorFeature\n    {\n        readonly Calculator calc;\n\n        public AddTwoNumbers(GivenWhenThenFixture state) \n            : base(state) =\u003e calc = new Calculator();\n\n        [Given(\"I have entered {0} into the calculator\", 1)]\n        public void Given(int first) =\u003e Context.Given.First = first;\n\n        [And(\"I have also entered {0} into the calculator\", 2)]\n        public void And(int second) =\u003e Context.Given.Second = second;\n\n        [When(\"I press add\")]\n        public void When() =\u003e Context.When = calc.Add(Context.Given.First, Context.Given.Second);\n\n        [Then(\"the result should be {0}\", 3)]\n        public void Then(int result) =\u003e Context.Result.ShouldBe(result);\n    }\n```\n\n\nYou can also define scenarios in a single method using delgates for each of the steps and allowing for multiple scenarios to be defined within the same class\n\n  ``` csharp\n    public class AdvancedCalculator : CalculatorFeature\n    {\n        Calculator calculator;\n\n        [Scenario(\"Multiply two numbers\")]\n        public void MultiplyTwoNumbers()\n        {\n            Given(\"I have a calculator\",           () =\u003e calculator = new Calculator());\n            When(\"I key in 10\",                    () =\u003e calculator.Key(10));\n            And(\"I key in 5 and press multiply\",  () =\u003e calculator.Multiply(5));\n            Then(\"It sets the Total to 50\",        () =\u003e calculator.Total.ShouldBe(50));\n        }\n\n        [Scenario(\"Divide two numbers\")]\n        public void DivideTwoNumbers()\n        {\n            Given(\"I have a calculator\",       () =\u003e calculator = new Calculator());\n            When(\"I key in 42\",                () =\u003e calculator.Key(42));\n\t    And(\"I key in 5 and press divide\",  () =\u003e calculator.Deivide(5));\n            Then(\"It sets the Total to 42\",    () =\u003e calculator.Total.ShouldBe(42));\n        }\n    }   \n```\n\nThe method based syntax also supports data driven tests, using xUnit InlineData (class based scenarios don't support data driven tests just yet).\n\n  ``` csharp\n        [ScenarioOutline(\"Divide two numbers\")]\n        [Examples(10, 2, 5)]\n        [Examples(20, 4, 5)]\n        public void DivideTwoNumbers(int number, int divideby, int result)\n        {\n            Given($\"I have a calculator\",                           () =\u003e calculator = new Calculator());\n            When($\"I key in {number}\",                              () =\u003e calculator.Key(number));\n            And($\"I key in {divideby} and press divide\",           () =\u003e calculator.Divide(divideby));\n            Then($\"It sets the Total to {result}\",                  () =\u003e calculator.Total.ShouldBe(result));\n        }\n```\n\nYou can generate Gherkin specs from your tests using the *CoreBDD.SpecGeneration* extension library, either by calling from an application or command line tool and passing in the path to the assembly containing tests, or by hooking up your test project to generate the specs after the test run. \n\nTo do the latter, first reference the *CoreBDD.SpecGeneration* library\n\n  ```ruby\n    dotnet add package CoreBDD.SpecGeneration\n```\n\nNext create a Fixture class within your test project, and call *GenerateSpecs.OutputFeatureSpecs* within the Dispose method, passing in the Assembly (or path to the Assembly) and the output folder for the generated specs.\n\n\n  ``` csharp\n    [CollectionDefinition(\"CoreBDD\")]\n    public class Collection : ICollectionFixture\u003cGenerateSpecsFixture\u003e { }\n\n    public class GenerateSpecsFixture : IDisposable\n    {\n        public void Dispose()\n        {\n            GenerateSpecs.OutputFeatureSpecs(this.GetType().Assembly.Location, @\"..\\..\\..\\Specs\\\");\n        }\n    }\n```\n\nWhen the tests complete running, a *FeatureName.feature* file is generated under the Specs folder of the xUnit test project. It generates Gherkin specs for the feature and related scenarios. Example *CalculatorFeature.feature* :\n\n  ``` gherkin\n    Feature: Calculator\n\tIn order to avoid silly mistakes\n    As a math idiot\n    I want to be told the sum of two numbers\n\n    Scenario: Add two numbers\n    \t\t\tGiven I have entered 1 into the calculator\n    \t\t\tAnd I have also entered 2 into the calculator\n    \t\t\tWhen I press add\n    \t\t\tThen the result should be 3\n\n    Scenario: Subtract two numbers\n    \t\t\tGiven I have entered 5 into the calculator\n    \t\t\tAnd I have also entered 2 into the calculator\n    \t\t\tWhen I press minus\n    \t\t\tThen the result should be 3\n\n```\n\n## Command Line Tool\n\nThe command line tool makes it easy to run tasks such as test execution with Gherkin style output, generating default feature and scenario test files and generating Gherkin feature files from existing tests, or generating tests from existing feature files.\n\nStarting from scratch using the dotnet template and cli tools:\n\n```ruby\n    mkdir demobdd\n    cd demobdd\n```\nNext create the new CoreBDD project\n\n```ruby\n    dotnet new corebdd\n```\n\nFind CoreBDD tests in current and sub directories and execute tests\n\n```ruby\n    corebdd test\n```\n\nRun tests then generate Gherkin .feature files in specified location\n\n```ruby\n    corebdd test --specs --output ./Specs\n```\n\nScaffold a CoreBDD feature class called 'Login' in current folder\n\n```ruby\n    corebdd generate feature --name login --namespace demobdd\n```\n\nScaffold a CoreBDD scenario class called 'LoginToWebsite' under the 'Login' feature\n\n```ruby\ncorebdd generate scenario --name LoginToWebsite --feature login --namespace demobdd\n```\n\nScaffold CoreBDD Tests from existing gherkin '.feature' files, specifiying location of feature files and target folder for generated tests.\nIf you have been following using the 'corebdd' test example, delete the 'Features' folder (leaving the Specs folder with .feature files intact) then run:\n\n```ruby\ncorebdd generate tests --path ./Specs --output ./Features --namespace demobdd\n```\n\nYou should now have test stubs regenerated using the .feature file scenarios.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevenknox%2FCoreBDD","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstevenknox%2FCoreBDD","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevenknox%2FCoreBDD/lists"}