├── .editorconfig ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── appveyor.yml ├── docs └── debugging.md ├── sample └── MyCalculator │ ├── MyCalculator-SpecFlow.xUnitAdapter.sln │ └── MyCalculator.Specs │ ├── App.config │ ├── Features │ ├── Addition.feature │ └── ComplexAddition.feature │ ├── MyCalculator.Specs.csproj │ ├── Properties │ └── AssemblyInfo.cs │ ├── SpecFlow.xUnitAdapter.Config.cs │ ├── StepDefinitions │ ├── Calculator.cs │ └── CalculatorSteps.cs │ └── packages.config └── src ├── .nuget └── nuget.config ├── NuGetPackages ├── .build │ ├── build.props │ └── build.targets ├── NuGetPackages.csproj ├── Properties │ ├── MSBNuget.props │ └── build.props ├── SpecFlow.xUnitAdapter │ ├── App.config.transform │ ├── SpecFlow.xUnitAdapter.Config.cs │ ├── SpecFlow.xUnitAdapter.nuspec │ ├── SpecFlow.xUnitAdapter.nuspec.props │ └── readme.txt ├── packages.config └── publish_to_local.cmd ├── SpecFlow.xUnitAdapter.2015.ChildProcessDbgSettings ├── SpecFlow.xUnitAdapter.2015.sln ├── SpecFlow.xUnitAdapter.2017.ChildProcessDbgSettings ├── SpecFlow.xUnitAdapter.2017.sln ├── SpecFlow.xUnitAdapter.Build ├── Properties │ └── AssemblyInfo.cs ├── SpecFlow.xUnitAdapter.Build.csproj ├── SpecFlow.xUnitAdapter.props ├── SpecFlow.xUnitAdapter.targets ├── SpecFlowSourceMapAppender.cs ├── app.config └── packages.config ├── SpecFlow.xUnitAdapter.SpecFlowPlugin ├── App.config ├── Framework │ ├── SpecFlowTestDiscoverer.cs │ └── SpecFlowTestFramework.cs ├── Properties │ └── AssemblyInfo.cs ├── Runners │ ├── ScenarioTestCaseRunner.cs │ └── XUnitTraceListener.cs ├── SpecFlow.xUnitAdapter.SpecFlowPlugin.csproj ├── SpecFlowParserHelper.cs ├── TestArtifacts │ ├── EmbeddedFeatureTypeInfo.cs │ ├── FeatureFileTypeInfo.cs │ ├── ScenarioTestCase.cs │ ├── SpecFlowFeatureTestClass.cs │ ├── SpecFlowFeatureTypeInfo.cs │ ├── SpecFlowGenericFixtureType.cs │ ├── SpecFlowProjectAssemblyInfo.cs │ ├── SpecFlowReflectionAssemblyInfo.cs │ ├── SpecFlowSourceMap.cs │ └── SpecFlowSourceMapper.cs ├── XUnitAdapterPlugin.cs └── packages.config └── tests └── SpecFlow.xUnitAdapter.TestProject ├── App.config ├── Properties └── AssemblyInfo.cs ├── SpecFlow.xUnitAdapter.Config.cs ├── SpecFlow.xUnitAdapter.TestProject.csproj ├── SpecFlowFeature1.feature ├── SpecFlowFeature2.feature ├── SpecFlowFeature3.feature ├── StandardXUnitTest.cs ├── StepDefinitions.cs ├── Test └── SpecFlowFeature4.feature ├── key.snk └── packages.config /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Global settings 5 | [*] 6 | indent_style = space 7 | end_of_line = crlf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.cs] 12 | indent_size = 4 13 | 14 | [*.{config,xml}] 15 | indent_size = 2 16 | 17 | [*.{proj,props,sln,targets}] 18 | tab_width = 4 19 | 20 | [*.{csproj,json,ps1,psd1,psm1,resx,rst}] 21 | indent_size = 2 22 | 23 | [nuget.config] 24 | indent_size = 2 25 | 26 | 27 | # Advanced 28 | dotnet_sort_system_directives_first = true 29 | 30 | ############### 31 | # Code Style 32 | ############### 33 | # 'this.' preferences 34 | dotnet_style_qualification_for_field = true:none 35 | dotnet_style_qualification_for_property = true:none 36 | dotnet_style_qualification_for_method = true:none 37 | dotnet_style_qualification_for_event = true:none 38 | 39 | # Predefined type preferences 40 | dotnet_style_predefined_type_for_locals_parameters_members = true:none 41 | dotnet_style_predefined_type_for_member_access = true:none 42 | 43 | # 'var' preferences 44 | csharp_style_var_for_built_in_types = true:suggestion 45 | csharp_style_var_when_type_is_apparent = true:suggestion 46 | csharp_style_var_elsewhere = true:suggestion 47 | 48 | # Code block preferences 49 | ############ Missing Prefer braces = true:warning 50 | csharp_style_expression_bodied_methods = false:none 51 | csharp_style_expression_bodied_constructors = false:none 52 | csharp_style_expression_bodied_operators = false:none 53 | csharp_style_expression_bodied_properties = true:suggestion 54 | csharp_style_expression_bodied_indexers = true:suggestion 55 | csharp_style_expression_bodied_accessors = true:suggestion 56 | 57 | # Expression preferences 58 | dotnet_style_object_initializer = true:suggestion 59 | dotnet_style_collection_initializer = true:suggestion 60 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 61 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 62 | dotnet_style_explicit_tuple_names = true:warning 63 | 64 | # Variable preferences 65 | csharp_style_inlined_variable_declaration = true:suggestion 66 | 67 | # 'null' checking 68 | csharp_style_throw_expression = true:none 69 | csharp_style_conditional_delegate_call = true:suggestion 70 | dotnet_style_coalesce_expression = true:suggestion 71 | dotnet_style_null_propagation = true:suggestion 72 | 73 | ############### 74 | # Indentation 75 | ############### 76 | csharp_indent_block_contents = true 77 | csharp_indent_braces = false 78 | csharp_indent_case_contents = true 79 | csharp_indent_switch_labels = true 80 | csharp_indent_labels = flush_left 81 | 82 | ############# 83 | # New Lines 84 | ############# 85 | # New line options for braces 86 | csharp_new_line_before_open_brace = all 87 | 88 | # New line options for keywords 89 | csharp_new_line_before_else = true 90 | csharp_new_line_before_catch = true 91 | csharp_new_line_before_finally = true 92 | 93 | # New line options for expressions 94 | csharp_new_line_before_members_in_object_initializers = true 95 | csharp_new_line_before_members_in_anonymous_types = true 96 | csharp_new_line_between_query_expression_clauses = true 97 | 98 | ########### 99 | # Spacing 100 | ########### 101 | # Set spacing for method declarations 102 | csharp_space_between_method_call_name_and_opening_parenthesis = false 103 | csharp_space_between_method_call_parameter_list_parentheses = false 104 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 105 | 106 | # Set spacing for method calls 107 | csharp_space_between_method_declaration_name_and_open_parenthesis = false 108 | csharp_space_between_method_declaration_parameter_list_parentheses = false 109 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 110 | 111 | # Set other spacing options 112 | csharp_space_after_keywords_in_control_flow_statements = true 113 | # csharp_space_between_parentheses = none 114 | csharp_space_after_cast = false 115 | csharp_space_around_declaration_statements = do_not_ignore 116 | 117 | # Set spacing for brackets 118 | csharp_space_before_open_square_brackets = false 119 | csharp_space_between_empty_square_brackets = false 120 | csharp_space_between_square_brackets = false 121 | 122 | # Set spacing for delimiters 123 | csharp_space_after_colon_in_inheritance_clause = true 124 | csharp_space_after_comma = true 125 | csharp_space_after_dot = false 126 | csharp_space_after_semicolon_in_for_statement = true 127 | csharp_space_before_colon_in_inheritance_clause = true 128 | csharp_space_before_comma = false 129 | csharp_space_before_dot = false 130 | csharp_space_before_semicolon_in_for_statement = false 131 | 132 | # Set spacing for operators 133 | csharp_space_around_binary_operators = before_and_after 134 | 135 | ########### 136 | # Wrapping 137 | ########### 138 | csharp_preserve_single_line_blocks = true 139 | csharp_preserve_single_line_statements = false 140 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright 2017 Gaspar Nagy, Spec Solutions (http://gasparnagy.com) 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. 191 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpecFlow.xUnitAdapter 2 | 3 | SpecFlow.xUnitAdapter is an xUnit adapter for SpecFlow that allows running 4 | scenarios without code generation. 5 | 6 | Supports: 7 | 8 | * SpecFlow v2.3.1 9 | * xUnit v2.3 or above 10 | 11 | Requires: 12 | 13 | * .NET Framework 4.5 or above (new project format has limited support, see below) 14 | * Visual Studio for Windows 15 | 16 | License: Apache (https://github.com/gasparnagy/SpecFlow.xUnitAdapter/blob/master/LICENSE) 17 | 18 | NuGet: https://www.nuget.org/packages/SpecFlow.xUnitAdapter 19 | 20 | See my blog post (http://gasparnagy.com/2017/04/specflow-without-code-behind-files/) for more information and background, 21 | you can also look at the complete example at https://github.com/gasparnagy/SpecFlow.xUnitAdapter/tree/master/sample/MyCalculator or watch the 22 | video demo on [YouTube](https://youtu.be/wGuoVqG3I8M). 23 | 24 | [![Build status](https://ci.appveyor.com/api/projects/status/oshtcr06501euoih/branch/master?svg=true)](https://ci.appveyor.com/project/gasparnagy/specflow-xunitadapter/branch/master) 25 | 26 | ## Donate 27 | 28 | If you like this plugin and would like to support developing this or similar plugins, please consider donating the project. (For receiving an invoice for your donation, please [contact me](http://gasparnagy.com/about/) upfront.) 29 | 30 | [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2FHWS4JADYFZN) 31 | 32 | ## Usage 33 | 34 | ### Install plugin from NuGet into your SpecFlow project. 35 | 36 | PM> Install-Package SpecFlow.xUnitAdapter 37 | 38 | ### Disable code-behind code generation 39 | 40 | To disable the code-behind code generation, you have to REMOVE (set it to 41 | empty) the "SpecFlowSingleFileGenerator" "Custom Tool" setting on the file 42 | properties of all feature files in Visual Studio. 43 | 44 | If you do this, Visual Studio will automatically delete the code behind files 45 | and removes them from the project. 46 | 47 | ### Make sure the feature files have a `SpecFlowFeature` or `SpecFlowEmbeddedFeature` build action. 48 | 49 | The SpecFlow.xUnitAdapter currently processes feature files in the folder (or 50 | subfolders) of the SpecFlow project assembly (typically in bin\Debug) and when 51 | they are embedded into the assembly. 52 | 53 | To achieve that, you should change the `Build Action` setting of 54 | the feature files to `SpecFlowFeature` if you want them to not be 55 | embedded, or `SpecFlowEmbeddedFeature` if you want them to be embedded 56 | in the assembly. 57 | 58 | ### Setup for new project file format 59 | 60 | When using the new project file format for .NET 4.5+ projects, the build actions `SpecFlowFeature` 61 | and `SpecFlowEmbeddedFeature` are not available. Instead of that, you need to set the 62 | `Copy to Output Directory` setting to `Copy if newer` to ensure that the feature files are 63 | copied to the output directory. (Source information will not be available in this case.) 64 | 65 | Also to be able to use the extension, you have to manually add the file [SpecFlow.xUnitAdapter.Config.cs](https://raw.githubusercontent.com/gasparnagy/SpecFlow.xUnitAdapter/master/src/NuGetPackages/SpecFlow.xUnitAdapter/SpecFlow.xUnitAdapter.Config.cs) 66 | to the project. 67 | 68 | ### Install xUnit Visual Studio adapter 69 | 70 | In order to run the tests from the Visual Studio Test Explorer Window, you 71 | can install the xUnit Visual Studio adapter. 72 | 73 | PM> Install-Package xunit.runner.visualstudio 74 | 75 | ## Limitations 76 | 77 | The adapter is currently in BETA and there are some limitations. 78 | 79 | 1. If you use `SpecFlowFeature`: As Visual Studio Test Explorer window only triggers the re-discovery of tests when the output assembly changes, if you only change the feature files, but nothing else in the code, you need to _Rebuild_ the project in order to see the changes. (This is important only if the change is related to the discovered tests, so for example if you change the scenario name or the examples section of a scenario outline.) 80 | 2. The adapter currently does not load the project-level feature file language setting (but assumes `en-US`). 81 | 3. For feature files with `#language` setting, the setting will only be used for data conversions if it is a specific culture (e.g. `de-AT`). For neutral languages (e.g. `de`), currently `en-US` is used for conversions. 82 | 4. The new project file format is not fully supported, see details in section *Setup for new project file format* above. 83 | 84 | For diagnosing test discovery errors, you can add the following setting to the `App.config` file of the SpecFlow project. With this setting, the test discovery errors are displayed in the `Tests` pane of the output window. 85 | 86 | 87 | 88 | 89 | 90 | ## Release History 91 | 92 | * See https://github.com/gasparnagy/SpecFlow.xUnitAdapter/releases 93 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: build{build} 2 | 3 | image: Visual Studio 2017 4 | 5 | branches: 6 | only: 7 | - master 8 | 9 | environment: 10 | BaseVersion: 1.0.0 11 | NugetVersion: "1.0.0-ci$(APPVEYOR_BUILD_NUMBER)" 12 | 13 | cache: 14 | - src\packages -> src\**\packages.config 15 | 16 | assembly_info: 17 | patch: true 18 | file: 'src\**\AssemblyInfo.*' 19 | assembly_version: "$(BaseVersion)" 20 | assembly_file_version: "$(BaseVersion)" 21 | assembly_informational_version: "$(NugetVersion)" 22 | 23 | nuget: 24 | project_feed: true 25 | disable_publish_on_pr: true 26 | 27 | configuration: Release 28 | 29 | before_build: 30 | - cd src 31 | - appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe 32 | - appveyor DownloadFile https://raw.githubusercontent.com/appveyor/ci/master/scripts/nuget-restore.cmd 33 | - nuget-restore SpecFlow.xUnitAdapter.2017.sln 34 | - cd .. 35 | 36 | build: 37 | project: src\SpecFlow.xUnitAdapter.2017.sln 38 | verbosity: normal 39 | 40 | artifacts: 41 | - path: 'src\NuGetPackages\bin\*.nupkg' 42 | 43 | test: off 44 | -------------------------------------------------------------------------------- /docs/debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging SpecFlow xUnitAdapter 2 | In order to debug the SpecFlow xUnitAdapter, you will need to be able to attach the debugger to the process running/discovering tests. Unfortunatly, `vstest.console.exe` kicks off child processes when it runs/discovers tests. The easiest solution to this is to use an extension created by an employee at Microsoft that instructs the Visual Studio Debugger to attach to and child process spawned from the process currently attached to the debugger. You can download and install the extension from: [Microsoft Child Process Debugging Power Tool](https://visualstudiogallery.msdn.microsoft.com/a1141bff-463f-465f-9b6d-d29b7b503d7a). 3 | 4 | Once the extension is installed open the `SpecFlow.xUnitAdapter.SpecFlowPlugin` project's properties and go to the `Debug` property page. 5 | 6 | ## Start external program: 7 | Visual Studio 2015: 8 | ``` 9 | C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe 10 | ``` 11 | 12 | Visual Studio 2017: 13 | ``` 14 | C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\TestPlatform\vstest.console.exe 15 | ``` 16 | 17 | ## Command line arguments: 18 | This property will change depending on what you are trying to debug. The most common scenarios are: 19 | 20 | Test Discovery: 21 | ``` 22 | SpecFlow.xUnitAdapter.TestProject.dll /ListTests /TestAdapterPath:. 23 | ``` 24 | 25 | Test Run: 26 | ``` 27 | SpecFlow.xUnitAdapter.TestProject.dll /TestAdapterPath:. 28 | ``` 29 | 30 | ## Working directory: 31 | This should be set to the bin directory of the test project which may be different on your machine. An example might be: 32 | ``` 33 | C:\Projects\SpecFlow.xUnitAdapter\src\tests\SpecFlow.xUnitAdapter.TestProject\bin\Debug\ 34 | ``` 35 | 36 | ## Enable native code debugging: 37 | This option needt to be enabled so that the child process debugging tools work. 38 | 39 | ## Microsoft Child Process Debugging Power Tool Configuration 40 | The settings for the child process debugging are stored in the `src\SpecFlow.xUnitAdapter.2017.ChildProcessDbgSettings` file. These settings should be already configured to work correctly with the SpecFlow adapter, however if you need to modify the settings you can do so in Visual Studio using the following menu: `Debug -> Other Debug Targets -> Child Process Debugging Settings...` -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator-SpecFlow.xUnitAdapter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCalculator.Specs", "MyCalculator.Specs\MyCalculator.Specs.csproj", "{12604BA5-8B06-41F3-A52C-0C4034E4A6AF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {12604BA5-8B06-41F3-A52C-0C4034E4A6AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {12604BA5-8B06-41F3-A52C-0C4034E4A6AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {12604BA5-8B06-41F3-A52C-0C4034E4A6AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {12604BA5-8B06-41F3-A52C-0C4034E4A6AF}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/Features/Addition.feature: -------------------------------------------------------------------------------- 1 | Feature: Addition 2 | In order to avoid silly mistakes 3 | As a math idiot 4 | I want to be told the sum of two numbers 5 | 6 | @mytag 7 | Scenario: Add two numbers 8 | Given I have entered 50 into the calculator 9 | And I have entered 70 into the calculator 10 | When I press add 11 | Then the result should be 120 on the screen 12 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/Features/ComplexAddition.feature: -------------------------------------------------------------------------------- 1 | Feature: Complex Addition 2 | In order to avoid silly mistakes 3 | As a math idiot 4 | I want to be told the sum of two numbers 5 | 6 | Scenario: Add two positive numbers 7 | Given I have entered the following numbers 8 | | number | 9 | | 29 | 10 | | 13 | 11 | When I press add 12 | Then the result should be 42 on the screen 13 | 14 | Scenario Outline: Add two numbers (outline) 15 | Given I have entered into the calculator 16 | And I have entered into the calculator 17 | When I press add 18 | Then the result should be on the screen 19 | 20 | Examples: 21 | | case | a | b | result | 22 | | classic | 50 | 70 | 120 | 23 | | commutativity | 70 | 50 | 120 | 24 | | zero | 0 | 42 | 42 | 25 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/MyCalculator.Specs.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Debug 9 | AnyCPU 10 | {12604BA5-8B06-41F3-A52C-0C4034E4A6AF} 11 | Library 12 | Properties 13 | MyCalculator.Specs 14 | MyCalculator.Specs 15 | v4.5.2 16 | 512 17 | 18 | 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | ..\packages\SpecFlow.xUnitAdapter.1.2.0\lib\net45\Gherkin.dll 40 | 41 | 42 | ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll 43 | 44 | 45 | ..\packages\SpecFlow.xUnitAdapter.1.2.0\lib\net45\SpecFlow.xUnitAdapter.SpecFlowPlugin.dll 46 | 47 | 48 | 49 | 50 | ..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ..\packages\SpecFlow.2.3.1\lib\net45\TechTalk.SpecFlow.dll 60 | 61 | 62 | ..\packages\SpecFlow.xUnitAdapter.1.2.0\lib\net45\TechTalk.SpecFlow.Parser.dll 63 | 64 | 65 | ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll 66 | True 67 | 68 | 69 | ..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll 70 | 71 | 72 | ..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll 73 | 74 | 75 | ..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | Designer 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 120 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MyCalculator.Specs")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MyCalculator.Specs")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("12604ba5-8b06-41f3-a52c-0c4034e4a6af")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/SpecFlow.xUnitAdapter.Config.cs: -------------------------------------------------------------------------------- 1 | // This configuration is required by SpecFlow.xUnitAdapter. See https://github.com/gasparnagy/SpecFlow.xUnitAdapter for details. 2 | 3 | [assembly: Xunit.TestFramework("SpecFlow.xUnitAdapter.SpecFlowPlugin.SpecFlowTestFramework", "SpecFlow.xUnitAdapter.SpecFlowPlugin")] -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/StepDefinitions/Calculator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MyCalculator 4 | { 5 | public class Calculator 6 | { 7 | private readonly Stack operands = new Stack(); 8 | 9 | public int Result => operands.Peek(); 10 | 11 | public void Enter(int operand) 12 | { 13 | operands.Push(operand); 14 | } 15 | 16 | public void Add() 17 | { 18 | operands.Push(operands.Pop() + operands.Pop()); 19 | } 20 | 21 | public void Multiply() 22 | { 23 | operands.Push(operands.Pop() * operands.Pop()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/StepDefinitions/CalculatorSteps.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using TechTalk.SpecFlow; 3 | using Xunit; 4 | 5 | namespace MyCalculator.Specs.StepDefinitions 6 | { 7 | [Binding] 8 | public class CalculatorSteps 9 | { 10 | private readonly Calculator calculator = new Calculator(); 11 | 12 | [Given(@"I have entered (.*) into the calculator")] 13 | public void GivenIHaveEnteredIntoTheCalculator(int operand) 14 | { 15 | calculator.Enter(operand); 16 | } 17 | 18 | [Given(@"I have entered the following numbers")] 19 | public void GivenIHaveEnteredTheFollowingNumbers(Table table) 20 | { 21 | foreach (var number in table.Rows.Select(r => int.Parse(r["number"]))) 22 | { 23 | calculator.Enter(number); 24 | } 25 | } 26 | 27 | [When(@"I press add")] 28 | public void WhenIPressAdd() 29 | { 30 | calculator.Add(); 31 | } 32 | 33 | [When(@"I press multiply")] 34 | public void WhenIPressMultiply() 35 | { 36 | calculator.Multiply(); 37 | } 38 | 39 | [Then(@"the result should be (.*) on the screen")] 40 | public void ThenTheResultShouldBeOnTheScreen(int expectedResult) 41 | { 42 | Assert.Equal(expectedResult, calculator.Result); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sample/MyCalculator/MyCalculator.Specs/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/.nuget/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/NuGetPackages/.build/build.props: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/NuGetPackages/.build/build.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/NuGetPackages/NuGetPackages.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A} 9 | Library 10 | Properties 11 | NuGetIntegration 12 | to_be_removed 13 | v4.5 14 | 512 15 | 16 | 17 | 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | false 28 | 29 | 30 | pdbonly 31 | true 32 | bin\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Designer 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/NuGetPackages/Properties/MSBNuget.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/NuGetPackages/Properties/build.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/NuGetPackages/SpecFlow.xUnitAdapter/App.config.transform: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/NuGetPackages/SpecFlow.xUnitAdapter/SpecFlow.xUnitAdapter.Config.cs: -------------------------------------------------------------------------------- 1 | // This configuration is required by SpecFlow.xUnitAdapter. See https://github.com/gasparnagy/SpecFlow.xUnitAdapter for details. 2 | 3 | [assembly: Xunit.TestFramework("SpecFlow.xUnitAdapter.SpecFlowPlugin.SpecFlowTestFramework", "SpecFlow.xUnitAdapter.SpecFlowPlugin")] -------------------------------------------------------------------------------- /src/NuGetPackages/SpecFlow.xUnitAdapter/SpecFlow.xUnitAdapter.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SpecFlow.xUnitAdapter 5 | 1.0.0-localdev 6 | xUnit adapter for SpecFlow that allows running scenarios without code generation 7 | Gaspar Nagy, Spec Solutions 8 | Gaspar Nagy, Spec Solutions 9 | xUnit adapter for SpecFlow that allows running scenarios without code generation. 10 | xUnit adapter for SpecFlow that allows running scenarios without code generation. 11 | See GitHub project page, https://github.com/gasparnagy/SpecFlow.xUnitAdapter/releases 12 | en-US 13 | https://github.com/gasparnagy/SpecFlow.xUnitAdapter 14 | https://github.com/gasparnagy/SpecFlow.xUnitAdapter/master/LICENSE 15 | http://go.specflow.org/specflow-nuget-icon 16 | Copyright © 2017-2018 Gaspar Nagy, Spec Solutions 17 | false 18 | specflow bdd xunit 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/NuGetPackages/SpecFlow.xUnitAdapter/SpecFlow.xUnitAdapter.nuspec.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | SpecFlow.xUnitAdapter\lib\net45 5 | 6 | 7 | 8 | SpecFlow.xUnitAdapter\lib\net45 9 | 10 | 11 | 12 | SpecFlow.xUnitAdapter\lib\net45 13 | 14 | 15 | SpecFlow.xUnitAdapter\lib\net45 16 | 17 | 18 | 19 | SpecFlow.xUnitAdapter\content 20 | 21 | 22 | 23 | SpecFlow.xUnitAdapter 24 | 25 | 26 | 27 | SpecFlow.xUnitAdapter\build\net45 28 | 29 | 30 | 31 | SpecFlow.xUnitAdapter\content 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/NuGetPackages/SpecFlow.xUnitAdapter/readme.txt: -------------------------------------------------------------------------------- 1 | SpecFlow.xUnitAdapter 2 | ===================== 3 | 4 | SpecFlow.xUnitAdapter is an xUnit adapter for SpecFlow that allows running 5 | scenarios without code generation. 6 | 7 | For project details, license and donations, please check the GitHub page: 8 | https://github.com/gasparnagy/SpecFlow.xUnitAdapter 9 | 10 | The adapter is currently in BETA, with some limitations that you can find on 11 | the GitHub project page. 12 | 13 | Setting up SpecFlow.xUnitAdapter 14 | -------------------------------- 15 | 16 | 1. Disable code-behind code generation 17 | 18 | To disable the code-behind code generation, you have to REMOVE (set it to 19 | empty) the "SpecFlowSingleFileGenerator" "Custom Tool" setting on the file 20 | properties of all feature files in Visual Studio. 21 | 22 | If you do this, Visual Studio will automatically delete the code behind files 23 | and removes them from the project. 24 | 25 | 2. Make sure the feature files are copied to the target location. 26 | 27 | The SpecFlow.xUnitAdapter currently processes feature files in the folder (or 28 | subfolders) of the SpecFlow project assembly (typically in bin\Debug) and when 29 | they are embedded into the assembly. 30 | 31 | To achieve that, you should change the `Build Action` setting of 32 | the feature files to `SpecFlowFeature` if you want them to not be 33 | embedded, or `SpecFlowEmbeddedFeature` if you want them to be embedded 34 | in the assembly. 35 | 36 | 3. Install xUnit Visual Studio adapter 37 | 38 | In order to run the tests from the Visual Studio Test Explorer Window, you 39 | can install the xUnit Visual Studio adapter. 40 | 41 | PM> Install-Package xunit.runner.visualstudio 42 | 43 | 44 | Feedback 45 | -------- 46 | 47 | If you find any issue please report it on GitHub: 48 | https://github.com/gasparnagy/SpecFlow.xUnitAdapter/issues 49 | 50 | Contribution and pull requests are welcome! 51 | -------------------------------------------------------------------------------- /src/NuGetPackages/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/NuGetPackages/publish_to_local.cmd: -------------------------------------------------------------------------------- 1 | @pushd %~dp0 2 | 3 | @if "%NUGET_LOCAL_FEED%" == "" ( 4 | @echo NUGET_LOCAL_FEED environment variable is not defined! 5 | @exit /b 6 | ) 7 | 8 | set VERSION=%1 9 | set PKGVER=%1%2 10 | set CONFIG="/p:Configuration=Release" 11 | set ASSEMBLYINFO=SpecFlow.xUnitAdapter.SpecFlowPlugin\Properties\AssemblyInfo.cs 12 | 13 | @echo publishing version %VERSION%, pkg version %PKGVER%, %CONFIG%, OK? 14 | @pause 15 | 16 | cd .. 17 | 18 | copy /Y %ASSEMBLYINFO% %ASSEMBLYINFO%.bak 19 | powershell -Command "(gc '%ASSEMBLYINFO%') -replace '1.0.0-localdev', '%PKGVER%' | Out-File '%ASSEMBLYINFO%'" 20 | powershell -Command "(gc '%ASSEMBLYINFO%') -replace '1.0.0.0', '%VERSION%.0' | Out-File '%ASSEMBLYINFO%'" 21 | 22 | msbuild SpecFlow.xUnitAdapter.2017.sln %CONFIG% 23 | 24 | cd NuGetPackages 25 | 26 | msbuild NuGetPackages.csproj "/p:NuGetVersion=%PKGVER%" /p:NugetPublishToLocalNugetFeed=true /t:Publish /p:NugetPublishLocalNugetFeedFolder=%NUGET_LOCAL_FEED% %CONFIG% 27 | 28 | cd .. 29 | move /Y %ASSEMBLYINFO%.bak %ASSEMBLYINFO% 30 | 31 | @popd 32 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.2015.ChildProcessDbgSettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.2015.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecFlow.xUnitAdapter.SpecFlowPlugin", "SpecFlow.xUnitAdapter.SpecFlowPlugin\SpecFlow.xUnitAdapter.SpecFlowPlugin.csproj", "{1DD1877B-E008-4383-AE65-69A55264C5BA}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecFlow.xUnitAdapter.TestProject", "tests\SpecFlow.xUnitAdapter.TestProject\SpecFlow.xUnitAdapter.TestProject.csproj", "{23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2} = {0C35DF24-9662-4061-BAE7-8672E1CFBFB2} 11 | EndProjectSection 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGetPackages", "NuGetPackages\NuGetPackages.csproj", "{B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}" 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4DBA1825-0282-4C5D-A1DF-764DAA47216D}" 16 | ProjectSection(SolutionItems) = preProject 17 | ..\.editorconfig = ..\.editorconfig 18 | ..\appveyor.yml = ..\appveyor.yml 19 | ..\LICENSE = ..\LICENSE 20 | .nuget\nuget.config = .nuget\nuget.config 21 | ..\README.md = ..\README.md 22 | SpecFlow.xUnitAdapter.2015.ChildProcessDbgSettings = SpecFlow.xUnitAdapter.2015.ChildProcessDbgSettings 23 | EndProjectSection 24 | EndProject 25 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecFlow.xUnitAdapter.Build", "SpecFlow.xUnitAdapter.Build\SpecFlow.xUnitAdapter.Build.csproj", "{0C35DF24-9662-4061-BAE7-8672E1CFBFB2}" 26 | EndProject 27 | Global 28 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 29 | Debug|Any CPU = Debug|Any CPU 30 | Release|Any CPU = Release|Any CPU 31 | EndGlobalSection 32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 33 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Release|Any CPU.Build.0 = Release|Any CPU 49 | EndGlobalSection 50 | GlobalSection(SolutionProperties) = preSolution 51 | HideSolutionNode = FALSE 52 | EndGlobalSection 53 | EndGlobal 54 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.2017.ChildProcessDbgSettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.2017.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26419.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecFlow.xUnitAdapter.SpecFlowPlugin", "SpecFlow.xUnitAdapter.SpecFlowPlugin\SpecFlow.xUnitAdapter.SpecFlowPlugin.csproj", "{1DD1877B-E008-4383-AE65-69A55264C5BA}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecFlow.xUnitAdapter.TestProject", "tests\SpecFlow.xUnitAdapter.TestProject\SpecFlow.xUnitAdapter.TestProject.csproj", "{23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2} = {0C35DF24-9662-4061-BAE7-8672E1CFBFB2} 11 | EndProjectSection 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGetPackages", "NuGetPackages\NuGetPackages.csproj", "{B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}" 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4DBA1825-0282-4C5D-A1DF-764DAA47216D}" 16 | ProjectSection(SolutionItems) = preProject 17 | ..\.editorconfig = ..\.editorconfig 18 | ..\appveyor.yml = ..\appveyor.yml 19 | ..\LICENSE = ..\LICENSE 20 | .nuget\nuget.config = .nuget\nuget.config 21 | ..\README.md = ..\README.md 22 | SpecFlow.xUnitAdapter.2017.ChildProcessDbgSettings = SpecFlow.xUnitAdapter.2017.ChildProcessDbgSettings 23 | EndProjectSection 24 | EndProject 25 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpecFlow.xUnitAdapter.Build", "SpecFlow.xUnitAdapter.Build\SpecFlow.xUnitAdapter.Build.csproj", "{0C35DF24-9662-4061-BAE7-8672E1CFBFB2}" 26 | EndProject 27 | Global 28 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 29 | Debug|Any CPU = Debug|Any CPU 30 | Release|Any CPU = Release|Any CPU 31 | EndGlobalSection 32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 33 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {1DD1877B-E008-4383-AE65-69A55264C5BA}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {B967FFB8-7BF4-4889-99BF-D8B4FA6A0B5A}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2}.Release|Any CPU.Build.0 = Release|Any CPU 49 | EndGlobalSection 50 | GlobalSection(SolutionProperties) = preSolution 51 | HideSolutionNode = FALSE 52 | EndGlobalSection 53 | EndGlobal 54 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.Build/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("SpecFlow.xUnitAdapter.Build")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Spec Solutions")] 11 | [assembly: AssemblyProduct("SpecFlow.xUnitAdapter")] 12 | [assembly: AssemblyCopyright("Copyright © 2017 Gaspar Nagy, Spec Solutions")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("1dd1877b-e008-4383-ae65-69a55264c5ba")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.Build/SpecFlow.xUnitAdapter.Build.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0C35DF24-9662-4061-BAE7-8672E1CFBFB2} 8 | Library 9 | Properties 10 | SpecFlow.xUnitAdapter.Build 11 | SpecFlow.xUnitAdapter.Build 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Microsoft.Build.14.3.0\lib\net45\Microsoft.Build.dll 35 | 36 | 37 | ..\packages\Microsoft.Build.Framework.14.3.0\lib\net45\Microsoft.Build.Framework.dll 38 | 39 | 40 | ..\packages\Microsoft.Build.Utilities.Core.14.3.0\lib\net45\Microsoft.Build.Utilities.Core.dll 41 | 42 | 43 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | SpecFlowSourceMap.cs 57 | 58 | 59 | SpecFlowSourceMapper.cs 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Designer 68 | 69 | 70 | Designer 71 | PreserveNewest 72 | 73 | 74 | Designer 75 | PreserveNewest 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.Build/SpecFlow.xUnitAdapter.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.Build/SpecFlow.xUnitAdapter.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | $([System.IO.Path]::Combine('$(ProjectDir)','$(IntermediateOutputPath)', 'SpecFlow')) 4 | $([System.IO.Path]::Combine('$(ProjectDir)','obj', 'SpecFlow')) 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Never 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.Build/SpecFlowSourceMapAppender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.Build.Framework; 4 | using Microsoft.Build.Utilities; 5 | using Newtonsoft.Json; 6 | using SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts; 7 | 8 | namespace SpecFlow.xUnitAdapter.Build 9 | { 10 | /// 11 | /// MSBuild task that applies source maps to SpecFlow feature files. 12 | /// 13 | public class SpecFlowSourceMapAppender : AppDomainIsolatedTask 14 | { 15 | private readonly ISpecFlowSourceMapper sourceMapper = new SpecFlowSourceMapperV1(); 16 | 17 | /// 18 | /// Gets or sets the directory that the source mapped feature files should be output. 19 | /// This is usually going to be obj/SpecFlow for files that will be embedded and 20 | /// the target directory for non-embedded files. 21 | /// 22 | [Required] 23 | public string OutputDirectory { get; set; } 24 | 25 | /// 26 | /// Gets or sets the collection of feature files being transformed with source map info. 27 | /// 28 | [Required] 29 | public ITaskItem[] FeatureFiles { get; set; } 30 | 31 | /// 32 | /// Gets or sets the output files that have had source maps applied to them. 33 | /// 34 | [Output] 35 | public ITaskItem[] SourceMappedFiles { get; set; } 36 | 37 | public override bool Execute() 38 | { 39 | if (this.FeatureFiles.Length <= 0) 40 | { 41 | return true; 42 | } 43 | 44 | SourceMappedFiles = new TaskItem[this.FeatureFiles.Length]; 45 | 46 | Log.LogMessage(MessageImportance.Normal, "Appending SpecFlow SourceMaps:"); 47 | 48 | for (var i = 0; i < this.FeatureFiles.Length; i++) 49 | { 50 | var item = this.FeatureFiles[i]; 51 | 52 | this.SourceMappedFiles[i] = this.AppendSourceMap(item); 53 | } 54 | 55 | return !this.Log.HasLoggedErrors; 56 | } 57 | 58 | private ITaskItem AppendSourceMap(ITaskItem item) 59 | { 60 | var outputPath = Path.Combine(OutputDirectory, item.ToString()); 61 | 62 | this.Log.LogMessage(MessageImportance.Normal, $" {outputPath}"); 63 | 64 | var inputPath = item.GetMetadata("FullPath"); 65 | var outputDirectory = Path.GetDirectoryName(outputPath); 66 | 67 | if (!Directory.Exists(outputDirectory)) 68 | { 69 | this.Log.LogMessage(MessageImportance.Low, $"Creating directory: {outputDirectory}"); 70 | Directory.CreateDirectory(outputDirectory); 71 | } 72 | 73 | //TODO: If the file modified dates havent changes, consider not copying and appending to the file, and use the existing one. 74 | File.Copy(inputPath, outputPath, true); 75 | File.SetAttributes(outputPath, File.GetAttributes(outputPath) & ~FileAttributes.ReadOnly); 76 | File.AppendAllLines(outputPath, new[] 77 | { 78 | Environment.NewLine, 79 | this.sourceMapper.GenerateSourceMap(inputPath) 80 | }); 81 | 82 | return new TaskItem(outputPath); 83 | } 84 | } 85 | 86 | public class SpecFlowSourceMap 87 | { 88 | /// 89 | /// Gets or sets the version number that the source map is based off of. 90 | /// 91 | public int Version { get; set; } 92 | 93 | /// 94 | /// Gets or sets the source file's path. 95 | /// 96 | public string SourcePath { get; set; } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.Build/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.Build/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/Framework/SpecFlowTestDiscoverer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Gherkin.Ast; 4 | using SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts; 5 | using Xunit.Abstractions; 6 | using Xunit.Sdk; 7 | 8 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.Framework 9 | { 10 | public class SpecFlowTestDiscoverer : XunitTestFrameworkDiscoverer 11 | { 12 | public SpecFlowTestDiscoverer(IAssemblyInfo assemblyInfo, ISourceInformationProvider sourceProvider, IMessageSink diagnosticMessageSink, IXunitTestCollectionFactory collectionFactory = null) : 13 | base(CreateSpecFlowProjectAssemblyInfo(assemblyInfo), sourceProvider, diagnosticMessageSink, collectionFactory) 14 | { 15 | } 16 | 17 | private static SpecFlowProjectAssemblyInfo CreateSpecFlowProjectAssemblyInfo(IAssemblyInfo assemblyInfo) 18 | { 19 | if (assemblyInfo is IReflectionAssemblyInfo reflectionAssemblyInfo) 20 | return new SpecFlowProjectReflectionAssemblyInfo(reflectionAssemblyInfo); 21 | return new SpecFlowProjectAssemblyInfo(assemblyInfo); 22 | } 23 | 24 | private bool IsSpecFlowTypeInfo(ITypeInfo typeInfo) 25 | { 26 | return typeInfo is SpecFlowFeatureTypeInfo; 27 | } 28 | 29 | private bool IsSpecFlowTest(ITestClass testClass) 30 | { 31 | return testClass is SpecFlowFeatureTestClass; 32 | } 33 | 34 | protected override ITestClass CreateTestClass(ITypeInfo typeInfo) 35 | { 36 | if (IsSpecFlowTypeInfo(typeInfo)) 37 | { 38 | return new SpecFlowFeatureTestClass(TestCollectionFactory.Get(typeInfo), typeInfo); 39 | } 40 | return base.CreateTestClass(typeInfo); 41 | } 42 | 43 | protected override bool FindTestsForType(ITestClass testClass, bool includeSourceInformation, IMessageBus messageBus, 44 | ITestFrameworkDiscoveryOptions discoveryOptions) 45 | { 46 | if (!IsSpecFlowTest(testClass)) 47 | return base.FindTestsForType(testClass, includeSourceInformation, messageBus, discoveryOptions); 48 | 49 | var featureTestClass = ((SpecFlowFeatureTestClass)testClass); 50 | var gherkinDocument = featureTestClass.FeatureTypeInfo.GetDocument(); 51 | if (gherkinDocument?.SpecFlowFeature != null) 52 | { 53 | featureTestClass.FeatureTypeInfo.FeatureName = gherkinDocument.SpecFlowFeature.Name; 54 | var featureTags = gherkinDocument.SpecFlowFeature.Tags.GetTags().ToArray(); 55 | foreach (var scenarioDefinition in gherkinDocument.SpecFlowFeature.ScenarioDefinitions.Where(sd => !(sd is Background))) 56 | { 57 | var scenario = scenarioDefinition as Scenario; 58 | if (scenario != null) 59 | { 60 | var scenarioTestCase = new ScenarioTestCase(featureTestClass, scenario, featureTags); 61 | if (!messageBus.QueueMessage(new TestCaseDiscoveryMessage(scenarioTestCase))) 62 | return false; 63 | } 64 | var scenarioOutline = scenarioDefinition as ScenarioOutline; 65 | if (scenarioOutline != null) 66 | { 67 | foreach (var example in scenarioOutline.Examples) 68 | { 69 | foreach (var exampleRow in example.TableBody) 70 | { 71 | var parameters = SpecFlowParserHelper.GetScenarioOutlineParameters(example, exampleRow); 72 | var scenarioOutlineTestCase = new ScenarioTestCase(featureTestClass, scenarioOutline, featureTags, parameters, SpecFlowParserHelper.GetExampleRowId(scenarioOutline, exampleRow), exampleRow.Location); 73 | if (!messageBus.QueueMessage(new TestCaseDiscoveryMessage(scenarioOutlineTestCase))) 74 | return false; 75 | } 76 | } 77 | } 78 | 79 | } 80 | } 81 | return true; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/Framework/SpecFlowTestFramework.cs: -------------------------------------------------------------------------------- 1 | using SpecFlow.xUnitAdapter.SpecFlowPlugin.Framework; 2 | using Xunit.Abstractions; 3 | using Xunit.Sdk; 4 | 5 | // ReSharper disable once CheckNamespace 6 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin 7 | { 8 | public class SpecFlowTestFramework : XunitTestFramework 9 | { 10 | public SpecFlowTestFramework(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink) 11 | { 12 | } 13 | 14 | // we only override the discoverer, we can use the built-in executor as it is anyway delegates the actual exectution to the test cases (ScenarioTestCase) 15 | protected override ITestFrameworkDiscoverer CreateDiscoverer(IAssemblyInfo assemblyInfo) 16 | { 17 | return new SpecFlowTestDiscoverer(assemblyInfo, SourceInformationProvider, DiagnosticMessageSink); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SpecFlow.xUnitAdapter (SpecFlow plugin)")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Spec Solutions")] 12 | [assembly: AssemblyProduct("SpecFlow.xUnitAdapter")] 13 | [assembly: AssemblyCopyright("Copyright © 2017 Gaspar Nagy, Spec Solutions")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1dd1877b-e008-4383-ae65-69a55264c5ba")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/Runners/ScenarioTestCaseRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Globalization; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Gherkin.Ast; 10 | using SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts; 11 | using TechTalk.SpecFlow; 12 | using TechTalk.SpecFlow.Parser; 13 | using Xunit.Abstractions; 14 | using Xunit.Sdk; 15 | 16 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners 17 | { 18 | public class ScenarioTestCaseRunner : TestCaseRunner 19 | { 20 | private ITestRunner testRunner; 21 | private readonly TestOutputHelper testOutputHelper; 22 | 23 | public ScenarioTestCaseRunner(ScenarioTestCase testCase, IMessageBus messageBus, ExceptionAggregator aggregator, CancellationTokenSource cancellationTokenSource, TestOutputHelper testOutputHelper) : base(testCase, messageBus, aggregator, cancellationTokenSource) 24 | { 25 | this.testOutputHelper = testOutputHelper; 26 | } 27 | 28 | public void FeatureSetup(GherkinDocument gherkinDocument) 29 | { 30 | Debug.Assert(gherkinDocument.Feature != null); 31 | var feature = gherkinDocument.Feature; 32 | 33 | var assembly = Assembly.LoadFrom(TestCase.FeatureTypeInfo.SpecFlowProject.AssemblyPath); 34 | testRunner = TestRunnerManager.GetTestRunner(assembly); 35 | var featureInfo = new FeatureInfo(GetFeatureCulture(feature.Language), feature.Name, feature.Description, ProgrammingLanguage.CSharp, feature.Tags.GetTags().ToArray()); 36 | testRunner.OnFeatureStart(featureInfo); 37 | } 38 | 39 | private CultureInfo GetFeatureCulture(string language) 40 | { 41 | var culture = new CultureInfo(language); 42 | if (culture.IsNeutralCulture) 43 | { 44 | return new CultureInfo("en-US"); //TODO: find the "default" specific culture for the neutral culture, like 'en-US' for 'en'. This is currently in the SpecFlow generator 45 | } 46 | 47 | return culture; 48 | } 49 | 50 | public void FeatureTearDown() 51 | { 52 | testRunner.OnFeatureEnd(); 53 | testRunner = null; 54 | } 55 | 56 | public void ScenarioTearDown() 57 | { 58 | testRunner.OnScenarioEnd(); 59 | } 60 | 61 | public virtual void ScenarioSetup(ScenarioInfo scenarioInfo) 62 | { 63 | if (testOutputHelper == null) 64 | throw new SpecFlowException("SpecFlow.xUnitAdapter: Unable to find ITestOutputHelper"); 65 | 66 | testRunner.OnScenarioStart(scenarioInfo); 67 | testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(testOutputHelper); 68 | } 69 | 70 | public virtual void ScenarioCleanup() 71 | { 72 | testRunner.CollectScenarioErrors(); 73 | } 74 | 75 | 76 | protected override async Task RunTestAsync() 77 | { 78 | var test = new XunitTest(TestCase, TestCase.DisplayName); //TODO: this is a pickle, we could use the Compiler/Pickle interfaces from the Gherkin parser 79 | var summary = new RunSummary() { Total = 1 }; 80 | string output = ""; 81 | 82 | var gherkinDocument = await this.TestCase.FeatureTypeInfo.GetDocumentAsync(); 83 | 84 | 85 | Scenario scenario = null; 86 | if (gherkinDocument.SpecFlowFeature != null) 87 | { 88 | if (TestCase.IsScenarioOutline) 89 | { 90 | var scenarioOutline = gherkinDocument.SpecFlowFeature.ScenarioDefinitions.OfType().FirstOrDefault(s => s.Name == TestCase.Name); 91 | if (scenarioOutline != null && SpecFlowParserHelper.GetExampleRowById(scenarioOutline, TestCase.ExampleId, out var example, out var exampleRow)) 92 | { 93 | scenario = SpecFlowParserHelper.CreateScenario(scenarioOutline, example, exampleRow); 94 | } 95 | } 96 | else 97 | { 98 | scenario = gherkinDocument.SpecFlowFeature.ScenarioDefinitions.OfType().FirstOrDefault(s => s.Name == TestCase.Name); 99 | } 100 | } 101 | 102 | string skipReason = null; 103 | if (scenario == null) 104 | skipReason = $"Unable to find Scenario: {TestCase.DisplayName}"; 105 | else if (gherkinDocument.SpecFlowFeature.Tags.GetTags().Concat(scenario.Tags.GetTags()).Contains("ignore")) 106 | { 107 | skipReason = "Ignored"; 108 | } 109 | 110 | if (skipReason != null) 111 | { 112 | summary.Skipped++; 113 | 114 | if (!MessageBus.QueueMessage(new TestSkipped(test, skipReason))) 115 | CancellationTokenSource.Cancel(); 116 | } 117 | else 118 | { 119 | var aggregator = new ExceptionAggregator(Aggregator); 120 | if (!aggregator.HasExceptions) 121 | { 122 | aggregator.Run(() => 123 | { 124 | var stopwatch = Stopwatch.StartNew(); 125 | testOutputHelper.Initialize(MessageBus, test); 126 | try 127 | { 128 | RunScenario(gherkinDocument, scenario); 129 | } 130 | finally 131 | { 132 | stopwatch.Stop(); 133 | summary.Time = (decimal)stopwatch.Elapsed.TotalSeconds; 134 | output = testOutputHelper.Output; 135 | testOutputHelper.Uninitialize(); 136 | } 137 | } 138 | ); 139 | } 140 | 141 | var exception = aggregator.ToException(); 142 | TestResultMessage testResult; 143 | if (exception == null) 144 | testResult = new TestPassed(test, summary.Time, output); 145 | else 146 | { 147 | testResult = new TestFailed(test, summary.Time, output, exception); 148 | summary.Failed++; 149 | } 150 | 151 | if (!CancellationTokenSource.IsCancellationRequested) 152 | if (!MessageBus.QueueMessage(testResult)) 153 | CancellationTokenSource.Cancel(); 154 | } 155 | 156 | if (!MessageBus.QueueMessage(new TestFinished(test, summary.Time, output))) 157 | CancellationTokenSource.Cancel(); 158 | 159 | return summary; 160 | } 161 | 162 | private void RunScenario(SpecFlowDocument gherkinDocument, Scenario scenario) 163 | { 164 | FeatureSetup(gherkinDocument); 165 | 166 | var scenarioInfo = new ScenarioInfo(scenario.Name, scenario.Tags.GetTags().ToArray()); 167 | ScenarioSetup(scenarioInfo); 168 | 169 | IEnumerable steps = scenario.Steps.Cast(); 170 | if (gherkinDocument.SpecFlowFeature.Background != null) 171 | { 172 | steps = gherkinDocument.SpecFlowFeature.Background.Steps.Cast().Concat(steps); 173 | } 174 | 175 | try 176 | { 177 | foreach (var step in steps) 178 | { 179 | Debug.WriteLine($"> Running {step.Keyword}{step.Text}"); 180 | ExecuteStep(step); 181 | } 182 | 183 | ScenarioCleanup(); // normally this is the point when the scenario errors are thrown 184 | } 185 | finally 186 | { 187 | ScenarioTearDown(); 188 | FeatureTearDown(); 189 | } 190 | } 191 | 192 | private void ExecuteStep(SpecFlowStep step) 193 | { 194 | var docStringArg = step.Argument as DocString; 195 | string docString = docStringArg?.Content; 196 | var dataTableArg = step.Argument as DataTable; 197 | Table dataTable = null; 198 | if (dataTableArg != null && dataTableArg.Rows.Any()) 199 | { 200 | dataTable = new Table(dataTableArg.Rows.First().Cells.Select(c => c.Value).ToArray()); 201 | foreach (var row in dataTableArg.Rows.Skip(1)) 202 | { 203 | dataTable.AddRow(row.Cells.Select(c => c.Value).ToArray()); 204 | } 205 | } 206 | switch (step.StepKeyword) 207 | { 208 | case StepKeyword.Given: 209 | testRunner.Given(step.Text, docString, dataTable, step.Keyword); 210 | break; 211 | case StepKeyword.When: 212 | testRunner.When(step.Text, docString, dataTable, step.Keyword); 213 | break; 214 | case StepKeyword.Then: 215 | testRunner.Then(step.Text, docString, dataTable, step.Keyword); 216 | break; 217 | case StepKeyword.And: 218 | testRunner.And(step.Text, docString, dataTable, step.Keyword); 219 | break; 220 | case StepKeyword.But: 221 | testRunner.But(step.Text, docString, dataTable, step.Keyword); 222 | break; 223 | } 224 | } 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/Runners/XUnitTraceListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BoDi; 3 | using TechTalk.SpecFlow.Infrastructure; 4 | using TechTalk.SpecFlow.Tracing; 5 | using Xunit.Abstractions; 6 | 7 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners 8 | { 9 | // This listener can be registered into the test thread container, so there will be a new instance 10 | // created for every execution thread. Therefore it does not have to support parallel scenario executions 11 | // so it is safe to access the ScenarioContext to get testOutputHelper. 12 | public class XUnitTraceListener : ITraceListener 13 | { 14 | private readonly Lazy contextManager; 15 | 16 | public XUnitTraceListener(IObjectContainer testThreadContainer) 17 | { 18 | contextManager = new Lazy(testThreadContainer.Resolve); 19 | } 20 | 21 | private void Write(string message) 22 | { 23 | var scenarioContext = contextManager.Value.ScenarioContext; 24 | if (scenarioContext == null || !scenarioContext.ScenarioContainer.IsRegistered()) 25 | { 26 | Console.WriteLine(message); // fallback 27 | return; 28 | } 29 | scenarioContext.ScenarioContainer.Resolve().WriteLine(message); 30 | } 31 | 32 | public void WriteTestOutput(string message) 33 | { 34 | Write(message); 35 | } 36 | 37 | public void WriteToolOutput(string message) 38 | { 39 | Write("-> " + message); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/SpecFlow.xUnitAdapter.SpecFlowPlugin.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {1DD1877B-E008-4383-AE65-69A55264C5BA} 9 | Library 10 | Properties 11 | SpecFlow.xUnitAdapter.SpecFlowPlugin 12 | SpecFlow.xUnitAdapter.SpecFlowPlugin 13 | v4.5.2 14 | 512 15 | 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\SpecFlow.CustomPlugin.2.3.1\lib\net45\Gherkin.dll 38 | 39 | 40 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 41 | 42 | 43 | 44 | 45 | ..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | ..\packages\SpecFlow.2.3.1\lib\net45\TechTalk.SpecFlow.dll 55 | 56 | 57 | ..\packages\SpecFlow.CustomPlugin.2.3.1\lib\net45\TechTalk.SpecFlow.Generator.dll 58 | 59 | 60 | ..\packages\SpecFlow.CustomPlugin.2.3.1\lib\net45\TechTalk.SpecFlow.Parser.dll 61 | 62 | 63 | ..\packages\SpecFlow.CustomPlugin.2.3.1\lib\net45\TechTalk.SpecFlow.Utils.dll 64 | 65 | 66 | ..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll 67 | True 68 | 69 | 70 | ..\packages\xunit.assert.2.3.0\lib\netstandard1.1\xunit.assert.dll 71 | 72 | 73 | ..\packages\xunit.extensibility.core.2.3.0\lib\netstandard1.1\xunit.core.dll 74 | 75 | 76 | ..\packages\xunit.extensibility.execution.2.3.0\lib\net452\xunit.execution.desktop.dll 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 123 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/SpecFlowParserHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using Gherkin.Ast; 6 | using TechTalk.SpecFlow.Parser; 7 | 8 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin 9 | { 10 | public static class SpecFlowParserHelper 11 | { 12 | public static SpecFlowGherkinParser CreateParser() 13 | { 14 | var parser = new SpecFlowGherkinParser(new CultureInfo("en-US")); //TODO: use specflow configuration 15 | return parser; 16 | } 17 | 18 | public static IEnumerable GetTags(this IEnumerable tagList) 19 | { 20 | if (tagList == null) 21 | yield break; 22 | foreach (var tag in tagList) 23 | { 24 | yield return tag.Name.TrimStart('@'); 25 | } 26 | } 27 | 28 | public static string GetExampleRowId(ScenarioOutline scenarioOutline, TableRow exampleRow) 29 | { 30 | int exampleRowId = 0; 31 | foreach (var row in scenarioOutline.Examples.SelectMany(example => example.TableBody)) 32 | { 33 | ++exampleRowId; 34 | if (exampleRow == row) 35 | return exampleRowId.ToString(); 36 | } 37 | throw new InvalidOperationException("Unable to find example row"); 38 | } 39 | 40 | public static bool GetExampleRowById(ScenarioOutline scenarioOutline, string exampleRowId, out Examples example, out TableRow exampleRow) 41 | { 42 | int id = 0; 43 | foreach (var ex in scenarioOutline.Examples) 44 | { 45 | foreach (var row in ex.TableBody) 46 | { 47 | ++id; 48 | if (id.ToString() == exampleRowId) 49 | { 50 | example = ex; 51 | exampleRow = row; 52 | return true; 53 | } 54 | } 55 | } 56 | example = null; 57 | exampleRow = null; 58 | return false; 59 | } 60 | 61 | public static Dictionary GetScenarioOutlineParametersById(ScenarioOutline scenarioOutline, string exampleRowId) 62 | { 63 | int id = 0; 64 | foreach (var example in scenarioOutline.Examples) 65 | { 66 | foreach (var row in example.TableBody) 67 | { 68 | ++id; 69 | if (id.ToString() == exampleRowId) 70 | return GetScenarioOutlineParameters(example, row); 71 | } 72 | } 73 | return null; 74 | } 75 | 76 | public static Dictionary GetScenarioOutlineParameters(Examples example, TableRow exampleRow) 77 | { 78 | return example.TableHeader.Cells 79 | .Zip(exampleRow.Cells, (keyCell, valueCell) => new { Key = keyCell.Value, valueCell.Value }) 80 | .ToDictionary(arg => arg.Key, arg => arg.Value); 81 | } 82 | 83 | public static Scenario CreateScenario(ScenarioOutline scenarioOutline, Examples example, TableRow exampleRow) 84 | { 85 | var parameters = GetScenarioOutlineParameters(example, exampleRow); 86 | var steps = new List(); 87 | 88 | var tags = new List(); 89 | tags.AddRange(scenarioOutline.Tags); 90 | tags.AddRange(example.Tags); 91 | 92 | foreach (var scenarioOutlineStep in scenarioOutline.Steps.Cast()) 93 | { 94 | string stepText = Interpolate(scenarioOutlineStep.Text, parameters); 95 | var step = new SpecFlowStep(scenarioOutlineStep.Location, scenarioOutlineStep.Keyword, stepText, 96 | CreatePickleArguments(scenarioOutlineStep.Argument, parameters), 97 | scenarioOutlineStep.StepKeyword, scenarioOutlineStep.ScenarioBlock); 98 | steps.Add(step); 99 | } 100 | 101 | return new Scenario(tags.ToArray(), scenarioOutline.Location, scenarioOutline.Keyword, scenarioOutline.Name, 102 | scenarioOutline.Description, steps.ToArray()); 103 | } 104 | 105 | private static StepArgument CreatePickleArguments(StepArgument argument, Dictionary parameters) 106 | { 107 | if (argument == null) return null; 108 | if (argument is DataTable) 109 | { 110 | DataTable t = (DataTable)argument; 111 | var rows = t.Rows; 112 | var newRows = new List(rows.Count()); 113 | foreach (var row in rows) 114 | { 115 | var cells = row.Cells; 116 | var newCells = new List(); 117 | foreach (var cell in cells) 118 | { 119 | newCells.Add(new TableCell(cell.Location, Interpolate(cell.Value, parameters))); 120 | } 121 | newRows.Add(new TableRow(row.Location, newCells.ToArray())); 122 | } 123 | return new DataTable(newRows.ToArray()); 124 | } 125 | if (argument is DocString) 126 | { 127 | DocString ds = (DocString)argument; 128 | return new DocString( 129 | ds.Location, 130 | ds.ContentType, 131 | Interpolate(ds.Content, parameters) 132 | ); 133 | } 134 | throw new InvalidOperationException("Unexpected argument type: " + argument); 135 | } 136 | 137 | private static string Interpolate(string name, Dictionary parameters) 138 | { 139 | foreach (var parameter in parameters) 140 | { 141 | name = name.Replace("<" + parameter.Key + ">", parameter.Value); 142 | } 143 | return name; 144 | } 145 | 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/EmbeddedFeatureTypeInfo.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | using System.Threading.Tasks; 4 | using TechTalk.SpecFlow.Parser; 5 | 6 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 7 | { 8 | public class EmbeddedFeatureTypeInfo : SpecFlowFeatureTypeInfo 9 | { 10 | public EmbeddedFeatureTypeInfo() 11 | { 12 | } 13 | 14 | public EmbeddedFeatureTypeInfo(SpecFlowProjectAssemblyInfo specFlowProject, string resourceName) 15 | : base(specFlowProject, resourceName) 16 | { 17 | } 18 | 19 | public override SpecFlowDocument GetDocument() 20 | { 21 | var parser = SpecFlowParserHelper.CreateParser(); 22 | 23 | var assembly = Assembly.ReflectionOnlyLoadFrom(this.SpecFlowProject.AssemblyPath); 24 | 25 | using (var stream = assembly.GetManifestResourceStream(this.RelativePath)) 26 | using (var reader = new StreamReader(stream)) 27 | { 28 | var content = reader.ReadToEnd(); 29 | return ParseDocument(content, null, parser); 30 | } 31 | } 32 | 33 | public override async Task GetDocumentAsync() 34 | { 35 | var parser = SpecFlowParserHelper.CreateParser(); 36 | 37 | var assembly = Assembly.ReflectionOnlyLoadFrom(this.SpecFlowProject.AssemblyPath); 38 | 39 | using (var stream = assembly.GetManifestResourceStream(this.RelativePath)) 40 | using (var reader = new StreamReader(stream)) 41 | { 42 | var content = await reader.ReadToEndAsync(); 43 | return ParseDocument(content, null, parser); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/FeatureFileTypeInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.IO; 3 | using System.Threading.Tasks; 4 | using TechTalk.SpecFlow.Parser; 5 | 6 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 7 | { 8 | public class FeatureFileTypeInfo : SpecFlowFeatureTypeInfo 9 | { 10 | public FeatureFileTypeInfo() 11 | { 12 | } 13 | 14 | public FeatureFileTypeInfo(SpecFlowProjectAssemblyInfo specFlowProject, string relativePath) 15 | : base(specFlowProject, relativePath) 16 | { 17 | } 18 | 19 | public override SpecFlowDocument GetDocument() 20 | { 21 | var parser = SpecFlowParserHelper.CreateParser(); 22 | var path = Path.Combine(SpecFlowProject.FeatureFilesFolder, RelativePath); 23 | 24 | using (var stream = File.OpenText(path)) 25 | { 26 | var content = stream.ReadToEnd(); 27 | return ParseDocument(content, path, parser); 28 | } 29 | } 30 | 31 | public override async Task GetDocumentAsync() 32 | { 33 | var parser = SpecFlowParserHelper.CreateParser(); 34 | var path = Path.Combine(SpecFlowProject.FeatureFilesFolder, RelativePath); 35 | 36 | using (var stream = File.OpenText(path)) 37 | { 38 | var content = await stream.ReadToEndAsync(); 39 | return ParseDocument(content, path, parser); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/ScenarioTestCase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using Gherkin.Ast; 8 | using SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners; 9 | using Xunit; 10 | using Xunit.Abstractions; 11 | using Xunit.Sdk; 12 | 13 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 14 | { 15 | public class ScenarioTestCase : LongLivedMarshalByRefObject, ITestMethod, IXunitTestCase, IReflectionMethodInfo 16 | { 17 | public SpecFlowFeatureTestClass FeatureTestClass { get; private set; } 18 | public SpecFlowFeatureTypeInfo FeatureTypeInfo => FeatureTestClass.FeatureTypeInfo; 19 | public string Name { get; private set; } 20 | 21 | public string DisplayName => GetDisplayName(); 22 | public string UniqueID => $"{FeatureTypeInfo.RelativePath};{Name};{ExampleId}"; 23 | 24 | public ISourceInformation SourceInformation { get; set; } 25 | public string SkipReason { get; set; } 26 | public Dictionary> Traits { get; set; } 27 | public Dictionary ScenarioOutlineParameters { get; set; } 28 | public string ExampleId { get; set; } 29 | 30 | public bool IsScenarioOutline => !string.IsNullOrEmpty(ExampleId); 31 | 32 | object[] ITestCase.TestMethodArguments => ScenarioOutlineParameters?.Cast().ToArray(); 33 | public ITestClass TestClass => FeatureTestClass; 34 | public ITestMethod TestMethod => this; 35 | public IMethodInfo Method => this; 36 | 37 | public ScenarioTestCase() 38 | { 39 | Traits = new Dictionary>(); 40 | } 41 | 42 | private ScenarioTestCase(SpecFlowFeatureTestClass featureTestClass, ScenarioDefinition scenario, string[] featureTags, Location location) 43 | { 44 | FeatureTestClass = featureTestClass; 45 | Name = scenario.Name; 46 | SourceInformation = new SourceInformation { FileName = FeatureTypeInfo.FeatureFilePath, LineNumber = location?.Line }; 47 | Traits = new Dictionary>(); 48 | Traits.Add("Category", featureTags.Concat(((IHasTags)scenario).Tags.GetTags()).ToList()); 49 | } 50 | 51 | public ScenarioTestCase(SpecFlowFeatureTestClass featureTestClass, Scenario scenario, string[] featureTags) 52 | : this(featureTestClass, scenario, featureTags, scenario.Location) 53 | { 54 | } 55 | 56 | public ScenarioTestCase(SpecFlowFeatureTestClass featureTestClass, ScenarioOutline scenario, string[] featureTags, Dictionary scenarioOutlineParameters, string exampleId, Location exampleLocation) 57 | : this(featureTestClass, scenario, featureTags, exampleLocation) 58 | { 59 | ScenarioOutlineParameters = scenarioOutlineParameters; 60 | ExampleId = exampleId; 61 | } 62 | 63 | private string GetDisplayName() 64 | { 65 | if (ScenarioOutlineParameters != null) 66 | { 67 | return $"{Name} ({string.Join(", ", ScenarioOutlineParameters.Select(p => $"{p.Key}: {p.Value}"))})"; 68 | } 69 | return Name; 70 | } 71 | 72 | public void Deserialize(IXunitSerializationInfo data) 73 | { 74 | FeatureTestClass = data.GetValue("FeatureTestClass"); 75 | Name = data.GetValue("Name"); 76 | ExampleId = data.GetValue("ExampleId"); 77 | } 78 | 79 | public void Serialize(IXunitSerializationInfo data) 80 | { 81 | data.AddValue("FeatureTestClass", FeatureTestClass); 82 | data.AddValue("Name", Name); 83 | data.AddValue("ExampleId", ExampleId); 84 | } 85 | 86 | public virtual Task RunAsync(IMessageSink diagnosticMessageSink, 87 | IMessageBus messageBus, 88 | object[] constructorArguments, 89 | ExceptionAggregator aggregator, 90 | CancellationTokenSource cancellationTokenSource) 91 | { 92 | var testOutputHelper = constructorArguments.OfType().FirstOrDefault(); 93 | return new ScenarioTestCaseRunner(this, messageBus, aggregator, cancellationTokenSource, testOutputHelper).RunAsync(); 94 | } 95 | 96 | #region IMethodInfo default implementation 97 | bool IMethodInfo.IsAbstract => false; 98 | bool IMethodInfo.IsGenericMethodDefinition => false; 99 | bool IMethodInfo.IsPublic => true; 100 | bool IMethodInfo.IsStatic => false; 101 | ITypeInfo IMethodInfo.ReturnType => null; 102 | ITypeInfo IMethodInfo.Type => TestClass.Class; 103 | IEnumerable IMethodInfo.GetCustomAttributes(string assemblyQualifiedAttributeTypeName) => Enumerable.Empty(); 104 | IEnumerable IMethodInfo.GetGenericArguments() => Enumerable.Empty(); 105 | IEnumerable IMethodInfo.GetParameters() => Enumerable.Empty(); 106 | IMethodInfo IMethodInfo.MakeGenericMethod(params ITypeInfo[] typeArguments) 107 | { 108 | throw new NotSupportedException("ScenarioTestCase.MakeGenericMethod"); 109 | } 110 | MethodInfo IReflectionMethodInfo.MethodInfo { get { throw new NotSupportedException("MethodInfo is not available for scenarios"); } } 111 | #endregion 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/SpecFlowFeatureTestClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 6 | { 7 | public class SpecFlowFeatureTestClass : LongLivedMarshalByRefObject, ITestClass 8 | { 9 | public ITypeInfo Class { get; private set; } 10 | public ITestCollection TestCollection { get; private set; } 11 | 12 | public SpecFlowFeatureTypeInfo FeatureTypeInfo => (SpecFlowFeatureTypeInfo)Class; 13 | 14 | [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] 15 | public SpecFlowFeatureTestClass() 16 | { 17 | } 18 | 19 | public SpecFlowFeatureTestClass(ITestCollection testCollection, ITypeInfo typeInfo) 20 | { 21 | if (!(typeInfo is SpecFlowFeatureTypeInfo)) 22 | throw new ArgumentException($"Must me an instance of {nameof(SpecFlowFeatureTypeInfo)}", "typeInfo"); 23 | 24 | TestCollection = testCollection; 25 | Class = typeInfo; 26 | } 27 | 28 | public void Serialize(IXunitSerializationInfo info) 29 | { 30 | info.AddValue("TestCollection", TestCollection); 31 | info.AddValue("SpecFlowProject", FeatureTypeInfo.SpecFlowProject); 32 | info.AddValue("RelativePath", FeatureTypeInfo.RelativePath); 33 | info.AddValue("TypeInfoKind", Class.GetType().Name); 34 | } 35 | 36 | public void Deserialize(IXunitSerializationInfo info) 37 | { 38 | TestCollection = info.GetValue("TestCollection"); 39 | var specFlowProject = info.GetValue("SpecFlowProject"); 40 | var relativePath = info.GetValue("RelativePath"); 41 | var typeInfoKind = info.GetValue("TypeInfoKind"); 42 | if (typeInfoKind == nameof(FeatureFileTypeInfo)) 43 | Class = new FeatureFileTypeInfo(specFlowProject, relativePath); 44 | else if (typeInfoKind == nameof(EmbeddedFeatureTypeInfo)) 45 | Class = new EmbeddedFeatureTypeInfo(specFlowProject, relativePath); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/SpecFlowFeatureTypeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using TechTalk.SpecFlow.Parser; 7 | using Xunit; 8 | using Xunit.Abstractions; 9 | 10 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 11 | { 12 | public abstract class SpecFlowFeatureTypeInfo : LongLivedMarshalByRefObject, ITypeInfo, IReflectionTypeInfo 13 | { 14 | public string FeatureName { get; set; } 15 | public string RelativePath { get; } 16 | public SpecFlowProjectAssemblyInfo SpecFlowProject { get; } 17 | 18 | public virtual string FeatureFilePath { get; protected set; } 19 | 20 | IAssemblyInfo ITypeInfo.Assembly => SpecFlowProject; 21 | string ITypeInfo.Name => (FeatureName ?? RelativePath).Replace(".", ""); 22 | Type IReflectionTypeInfo.Type => typeof(SpecFlowGenericFixtureType); 23 | 24 | #region ITypeInfo default implementation 25 | IEnumerable ITypeInfo.GetCustomAttributes(string assemblyQualifiedAttributeTypeName) => Enumerable.Empty(); 26 | IEnumerable ITypeInfo.GetGenericArguments() => Enumerable.Empty(); 27 | IMethodInfo ITypeInfo.GetMethod(string methodName, bool includePrivateMethod) => null; 28 | IEnumerable ITypeInfo.GetMethods(bool includePrivateMethods) => Enumerable.Empty(); 29 | ITypeInfo ITypeInfo.BaseType => null; 30 | IEnumerable ITypeInfo.Interfaces => Enumerable.Empty(); 31 | bool ITypeInfo.IsAbstract => false; 32 | bool ITypeInfo.IsGenericParameter => false; 33 | bool ITypeInfo.IsGenericType => false; 34 | bool ITypeInfo.IsSealed => false; 35 | bool ITypeInfo.IsValueType => false; 36 | #endregion 37 | 38 | protected SpecFlowFeatureTypeInfo() { } 39 | 40 | protected SpecFlowFeatureTypeInfo(SpecFlowProjectAssemblyInfo specFlowProject, string relativePath) 41 | { 42 | SpecFlowProject = specFlowProject; 43 | RelativePath = relativePath; 44 | } 45 | 46 | protected ISpecFlowSourceMapper SpecFlowSourceMapper { get; } = new SpecFlowSourceMapperV1(); 47 | 48 | protected SpecFlowDocument ParseDocument(string content, string path, SpecFlowGherkinParser parser) 49 | { 50 | var sourceMap = this.SpecFlowSourceMapper.ReadSourceMap(content); 51 | 52 | this.FeatureFilePath = sourceMap?.SourcePath ?? path; 53 | 54 | return parser.Parse(new StringReader(content), this.FeatureFilePath); 55 | } 56 | 57 | public abstract SpecFlowDocument GetDocument(); 58 | 59 | public abstract Task GetDocumentAsync(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/SpecFlowGenericFixtureType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Xunit.Abstractions; 4 | 5 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 6 | { 7 | public class SpecFlowGenericFixtureType 8 | { 9 | // This constructor is used to determine the constructor arguments of the scenario 10 | // since the execution requires the ITestOutputHelper, the parameter is essential. 11 | // The ITestOutputHelper will be passed in by the runners via ScenarioTestCase.RunAsync. 12 | public SpecFlowGenericFixtureType(ITestOutputHelper testOutputHelper) 13 | { 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/SpecFlowProjectAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using Xunit; 7 | using Xunit.Abstractions; 8 | using Xunit.Sdk; 9 | 10 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 11 | { 12 | [Serializable] 13 | public class SpecFlowProjectAssemblyInfo : LongLivedMarshalByRefObject, IAssemblyInfo, IXunitSerializable 14 | { 15 | public string FeatureFilesFolder => Path.GetFullPath(Path.GetDirectoryName(originalAssemblyInfo.AssemblyPath)); 16 | 17 | protected IAssemblyInfo originalAssemblyInfo; 18 | 19 | public SpecFlowProjectAssemblyInfo() 20 | { 21 | 22 | } 23 | 24 | public SpecFlowProjectAssemblyInfo(IAssemblyInfo originalAssemblyInfo) 25 | { 26 | this.originalAssemblyInfo = originalAssemblyInfo; 27 | } 28 | 29 | public IEnumerable GetCustomAttributes(string assemblyQualifiedAttributeTypeName) 30 | { 31 | return originalAssemblyInfo.GetCustomAttributes(assemblyQualifiedAttributeTypeName); 32 | } 33 | 34 | public ITypeInfo GetType(string typeName) 35 | { 36 | return GetTypes(false).FirstOrDefault(t => t.Name == typeName); 37 | } 38 | 39 | public IEnumerable GetTypes(bool includePrivateTypes) 40 | { 41 | Console.WriteLine($" Discovering feature files embedded in assembly {this.originalAssemblyInfo.Name}"); 42 | var assembly = Assembly.ReflectionOnlyLoadFrom(this.originalAssemblyInfo.AssemblyPath); 43 | foreach (var resourceName in assembly.GetManifestResourceNames().Where(x => x.EndsWith(".feature"))) 44 | { 45 | Console.WriteLine($" {resourceName}"); 46 | yield return new EmbeddedFeatureTypeInfo(this, resourceName); 47 | } 48 | 49 | Console.WriteLine($" Discovering feature files from folder {FeatureFilesFolder}"); 50 | foreach (var featureFilePath in Directory.GetFiles(FeatureFilesFolder, "*.feature", SearchOption.AllDirectories)) 51 | { 52 | var relativePath = featureFilePath.Substring(FeatureFilesFolder.Length).TrimStart(Path.DirectorySeparatorChar); 53 | Console.WriteLine($" {relativePath}"); 54 | yield return new FeatureFileTypeInfo(this, relativePath); 55 | } 56 | 57 | // discovering "standard" xunit tests to allow incremental transition from the generated style to the new style 58 | foreach (var standardType in originalAssemblyInfo.GetTypes(includePrivateTypes)) 59 | yield return standardType; 60 | } 61 | 62 | public string AssemblyPath 63 | { 64 | get { return originalAssemblyInfo.AssemblyPath; } 65 | } 66 | 67 | public string Name 68 | { 69 | get { return originalAssemblyInfo.Name; } 70 | } 71 | 72 | public void Deserialize(IXunitSerializationInfo data) 73 | { 74 | string assemblyPath = data.GetValue("OrigAssembly"); 75 | originalAssemblyInfo = Reflector.Wrap(Assembly.LoadFrom(assemblyPath)); 76 | } 77 | 78 | public void Serialize(IXunitSerializationInfo data) 79 | { 80 | data.AddValue("OrigAssembly", AssemblyPath); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/SpecFlowReflectionAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using Xunit.Abstractions; 3 | 4 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 5 | { 6 | public class SpecFlowProjectReflectionAssemblyInfo : SpecFlowProjectAssemblyInfo, IReflectionAssemblyInfo 7 | { 8 | public SpecFlowProjectReflectionAssemblyInfo() 9 | { 10 | } 11 | 12 | public SpecFlowProjectReflectionAssemblyInfo(IReflectionAssemblyInfo originalAssemblyInfo) 13 | : base(originalAssemblyInfo) 14 | { 15 | } 16 | 17 | public Assembly Assembly => ((IReflectionAssemblyInfo)originalAssemblyInfo).Assembly; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/SpecFlowSourceMap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 5 | { 6 | 7 | public class SpecFlowSourceMap 8 | { 9 | /// 10 | /// Gets or sets the version number that the source map is based off of. 11 | /// 12 | public int Version { get; set; } 13 | 14 | /// 15 | /// Gets or sets the source file's path. 16 | /// 17 | public string SourcePath { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/TestArtifacts/SpecFlowSourceMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin.TestArtifacts 5 | { 6 | public interface ISpecFlowSourceMapper 7 | { 8 | /// 9 | /// Generates a source map line to add to a feature file. 10 | /// 11 | /// The path to the source feature file. 12 | /// The source map line to add to the feature file. 13 | string GenerateSourceMap(string sourcePath); 14 | 15 | /// 16 | /// Reads a source map from a feature file. 17 | /// 18 | /// The contents of the feature file with source maps. 19 | /// The source map data. 20 | SpecFlowSourceMap ReadSourceMap(string content); 21 | } 22 | 23 | public class SpecFlowSourceMapperV1 : ISpecFlowSourceMapper 24 | { 25 | private const int SourceMapVersion = 1; 26 | private const string SourceMapPattern = "#sourceMap="; 27 | 28 | public string GenerateSourceMap(string sourcePath) 29 | { 30 | var sourceMap = JsonConvert.SerializeObject(new SpecFlowSourceMap 31 | { 32 | Version = SourceMapVersion, 33 | SourcePath = sourcePath 34 | }); 35 | 36 | return $"{SourceMapPattern}{sourceMap}{Environment.NewLine}"; 37 | } 38 | 39 | public SpecFlowSourceMap ReadSourceMap(string content) 40 | { 41 | var index = content.IndexOf(SourceMapPattern); 42 | if (index == -1) 43 | { 44 | Console.WriteLine($"Could not find a source mapping."); 45 | return null; 46 | } 47 | 48 | var newLineIndex = content.IndexOf(Environment.NewLine, index); 49 | 50 | var sourceMap = newLineIndex == -1 51 | ? content.Substring(index + SourceMapPattern.Length) 52 | : content.Substring(index + SourceMapPattern.Length, newLineIndex - index - SourceMapPattern.Length); 53 | 54 | return JsonConvert.DeserializeObject(sourceMap); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/XUnitAdapterPlugin.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SpecFlow.xUnitAdapter.SpecFlowPlugin; 3 | using SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners; 4 | using TechTalk.SpecFlow.Plugins; 5 | using TechTalk.SpecFlow.Tracing; 6 | 7 | [assembly: RuntimePlugin(typeof(XUnitAdapterPlugin))] 8 | 9 | namespace SpecFlow.xUnitAdapter.SpecFlowPlugin 10 | { 11 | public class XUnitAdapterPlugin : IRuntimePlugin 12 | { 13 | public void Initialize(RuntimePluginEvents runtimePluginEvents, RuntimePluginParameters runtimePluginParameters) 14 | { 15 | runtimePluginEvents.CustomizeTestThreadDependencies += (sender, args) => 16 | { 17 | args.ObjectContainer.RegisterTypeAs(); 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SpecFlow.xUnitAdapter.SpecFlowPlugin/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SpecFlow.xUnitAdapter.TestProject")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Spec Solutions")] 12 | [assembly: AssemblyProduct("SpecFlow.xUnitAdapter.TestProject")] 13 | [assembly: AssemblyCopyright("Copyright © 2017 Gaspar Nagy, Spec Solutions")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("23b6fa2e-cfb0-4d32-a40d-d29c8cc8df45")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/SpecFlow.xUnitAdapter.Config.cs: -------------------------------------------------------------------------------- 1 | // This configuration is required by SpecFlow.xUnitAdapter. See https://github.com/gasparnagy/SpecFlow.xUnitAdapter for details. 2 | 3 | [assembly: Xunit.TestFramework("SpecFlow.xUnitAdapter.SpecFlowPlugin.SpecFlowTestFramework", "SpecFlow.xUnitAdapter.SpecFlowPlugin")] -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/SpecFlow.xUnitAdapter.TestProject.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Debug 10 | AnyCPU 11 | {23B6FA2E-CFB0-4D32-A40D-D29C8CC8DF45} 12 | Library 13 | Properties 14 | SpecFlow.xUnitAdapter.TestProject 15 | SpecFlow.xUnitAdapter.TestProject 16 | v4.5.2 17 | 512 18 | 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 41 | true 42 | 43 | 44 | true 45 | 46 | 47 | key.snk 48 | 49 | 50 | 51 | ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 52 | 53 | 54 | 55 | 56 | ..\..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ..\..\packages\SpecFlow.2.3.1\lib\net45\TechTalk.SpecFlow.dll 66 | 67 | 68 | ..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll 69 | True 70 | 71 | 72 | ..\..\packages\xunit.assert.2.3.0\lib\netstandard1.1\xunit.assert.dll 73 | 74 | 75 | ..\..\packages\xunit.extensibility.core.2.3.0\lib\netstandard1.1\xunit.core.dll 76 | 77 | 78 | ..\..\packages\xunit.extensibility.execution.2.3.0\lib\net452\xunit.execution.desktop.dll 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Designer 92 | 93 | 94 | PreserveNewest 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | {1dd1877b-e008-4383-ae65-69a55264c5ba} 106 | SpecFlow.xUnitAdapter.SpecFlowPlugin 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 132 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/SpecFlowFeature1.feature: -------------------------------------------------------------------------------- 1 | @featuretag 2 | Feature: SpecFlow Feature 1 3 | In order to avoid silly mistakes 4 | As a math idiot 5 | I want to be told the sum of two numbers 6 | 7 | @mytag 8 | Scenario: Add two numbers 9 | Given I have entered 50 into the calculator 10 | And I have entered 70 into the calculator 11 | When I press add 12 | Then the result should be 120 on the screen 13 | 14 | @mytag @othertag 15 | Scenario: A failing scenario 16 | Given I have entered 50 into the calculator 17 | And I have entered 70 into the calculator 18 | When there is a failing step 19 | Then the result should be 120 on the screen 20 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/SpecFlowFeature2.feature: -------------------------------------------------------------------------------- 1 | Feature: SpecFlow Feature 2 2 | In order to avoid silly mistakes 3 | As a math idiot 4 | I want to be told the sum of two numbers 5 | 6 | Background: 7 | Given I have entered 50 into the calculator 8 | 9 | @mytag 10 | Scenario: Add two numbers with Background 11 | Given I have entered 70 into the calculator 12 | When I press add 13 | Then the result should be 120 on the screen 14 | 15 | @mytag 16 | Scenario: Add two numbers with DataTable 17 | Given there is a new calcualtor 18 | And I have entered the following numbers into the calculator: 19 | | number | 20 | | 50 | 21 | | 70 | 22 | When I press add 23 | Then the result should be 120 on the screen 24 | 25 | Scenario Outline: Add two numbers as Scenario Outline 26 | Given there is a new calcualtor 27 | And I have entered into the calculator 28 | And I have entered into the calculator 29 | When I press add 30 | Then the result should be on the screen 31 | 32 | Examples: 33 | | case | a | b | result | 34 | | basic | 1 | 2 | 3 | 35 | | seven | 3 | 4 | 7 | 36 | | failing | 3 | 4 | 42 | 37 | 38 | @ignore 39 | Scenario: Ignored scenario 40 | Given something wrong 41 | 42 | Scenario: Undefined scenario 43 | Given there is an undefined step -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/SpecFlowFeature3.feature: -------------------------------------------------------------------------------- 1 | #language: de 2 | Funktionalität: German Feature 3 | 4 | Szenario: Addition in German 5 | Angenommen I have entered 50 into the calculator 6 | Und I have entered 70 into the calculator 7 | Wenn I press add 8 | Dann the result should be 120 on the screen 9 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/StandardXUnitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace SpecFlow.xUnitAdapter.TestProject 5 | { 6 | public class StandardXUnitTest 7 | { 8 | [Fact] 9 | public void ThisIsAStrandardPassingXUnitTest() 10 | { 11 | Console.WriteLine("This should be tested too"); 12 | } 13 | 14 | [Fact(DisplayName = "Failing standard test with custom display name")] 15 | public void ThisIsAStrandardFailingXUnitTest() 16 | { 17 | Assert.True(false); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/StepDefinitions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using TechTalk.SpecFlow; 5 | using Xunit; 6 | using Xunit.Abstractions; 7 | 8 | namespace SpecFlow.xUnitAdapter.TestProject 9 | { 10 | [Binding] 11 | public sealed class StepDefinitions : Steps 12 | { 13 | private List numbers = new List(); 14 | private int? result; 15 | 16 | [Given(@"there is a new calcualtor")] 17 | public void GivenThereIsANewCalcualtor() 18 | { 19 | numbers.Clear(); 20 | } 21 | 22 | [Given("I have entered (.*) into the calculator")] 23 | public void GivenIHaveEnteredSomethingIntoTheCalculator(int number) 24 | { 25 | System.Threading.Thread.Sleep(100); 26 | var outputHelper = ScenarioContext.ScenarioContainer.Resolve(); 27 | outputHelper.WriteLine("Sample output through ITestOutputHelper"); 28 | Console.WriteLine("Running Given step"); 29 | numbers.Add(number); 30 | } 31 | 32 | [Given(@"I have entered the following numbers into the calculator:")] 33 | public void GivenIHaveEnteredTheFollowingNumbersIntoTheCalculator(Table table) 34 | { 35 | foreach (var tableRow in table.Rows) 36 | { 37 | GivenIHaveEnteredSomethingIntoTheCalculator(int.Parse(tableRow["number"])); 38 | } 39 | } 40 | 41 | [When("I press add")] 42 | public void WhenIPressAdd() 43 | { 44 | Console.WriteLine("Running When step"); 45 | result = numbers.Sum(); 46 | } 47 | 48 | [When(@"there is a failing step")] 49 | public void WhenThereIsAFailingStep() 50 | { 51 | throw new Exception("this has failed"); 52 | } 53 | 54 | [Then("the result should be (.*) on the screen")] 55 | public void ThenTheResultShouldBe(int expectedResult) 56 | { 57 | Console.WriteLine("Running Then step"); 58 | Assert.Equal(expectedResult, result); 59 | } 60 | 61 | [AfterScenario] 62 | public void AfterScenario() 63 | { 64 | Console.WriteLine("after scenario"); 65 | } 66 | 67 | [AfterFeature] 68 | public static void AfterFeature() 69 | { 70 | Console.WriteLine("after feature"); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/Test/SpecFlowFeature4.feature: -------------------------------------------------------------------------------- 1 | Feature: Feature 4 2 | 3 | Scenario: Addition in a folder 4 | Given I have entered 50 into the calculator 5 | And I have entered 70 into the calculator 6 | When I press add 7 | Then the result should be 120 on the screen 8 | -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasparnagy/SpecFlow.xUnitAdapter/9ff9a4c3ed36d953df5bdccdf18581eb043b8a5d/src/tests/SpecFlow.xUnitAdapter.TestProject/key.snk -------------------------------------------------------------------------------- /src/tests/SpecFlow.xUnitAdapter.TestProject/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | --------------------------------------------------------------------------------