SpecFlow
SpecFlow copied to clipboard
Attributes in .feature.cs files should use the global:: prefix
SpecFlow Version:
- [x] 3.7
- [ ] 3.6
- [ ] 3.5
- [ ] 3.4
- [ ] 3.3
- [ ] 3.1
- [ ] 3.0
- [ ] 2.4
- [ ] 2.3
- [ ] 2.2
- [ ] 2.1
- [ ] 2.0
- [ ] 1.9
Used Test Runner
- [ ] SpecFlow+Runner
- [ ] MSTest
- [x] NUnit
- [ ] Xunit
Version number: 3.17.0 (NUnit3TestAdapter)
Project Format of the SpecFlow project
- [ ] Classic project format using
packages.config
- [ ] Classic project format using
<PackageReference>
tags - [x] Sdk-style project format
.feature.cs files are generated using
- [x]
SpecFlow.Tools.MsBuild.Generation
NuGet package - [ ]
SpecFlowSingleFileGenerator
custom tool
Visual Studio Version
- [x] VS 2019
- [ ] VS 2017
Enable SpecFlowSingleFileGenerator Custom Tool
option in Visual Studio extension settings
- [ ] Enabled
- [x] Disabled
Are the latest Visual Studio updates installed?
- [x] Yes
- [ ] No, I use Visual Studio version
<Major>.<Minor>.<Patch>
.NET Implementation:
- [ ] .NET 5.0
- [ ] .NET Core 3.1
- [ ] .NET Core 2.1
- [x] >= .NET Framework 4.5
- [ ] before .NET Framework 4.5
Test Execution Method:
- [x] Visual Studio Test Explorer
- [ ] TFS/VSTS/Azure DevOps – Task – PLEASE SPECIFY THE NAME OF THE TASK
- [ ] Command line – PLEASE SPECIFY THE FULL COMMAND LINE
<SpecFlow> Section in app.config or content of specflow.json
Not relevant for this issue
Issue Description
The auto-generated .feature.cs
files contain some attributes such as these:
[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.7.0.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Calculator")]
public partial class CalculatorFeature
In this example, the build would fail if your project's default namespace contains a NUnit
namespace. In my case, I was just doing some trials in a new project I called SpecFlow.NUnit
, and I got errors such as: error CS0234: The type or namespace name 'Framework' does not exist in the namespace 'SpecFlow.NUnit'
.
Obviously, I should've chosen a better project name. However, defining the attributes using the global::
prefix would prevent these sort of namespace ambiguities:
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "3.7.0.0")]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::NUnit.Framework.TestFixtureAttribute()]
[global::NUnit.Framework.DescriptionAttribute("Calculator")]
public partial class CalculatorFeature
Steps to Reproduce
- Create a SpecFlow project named
Something.NUnit
with the NUnit runner selected - Build it
I am not sure if CodeDom can do that. We had problems with the global namespace in the past.
Thanks for raising this issue @fernandreu , it was driving me crazy - same as what you described, created a test solution and project (named xxx.Demo.NUnit), added the packages needed but it wouldn't build.
Do we have some updates regarding this?
No @AlissonPereiraNeves. As far as I know, there is no option for CodeDom that it generates code with the global prefix.
The workaround is to change the project's root namespace:
In your .csproj
add to your project properties:
<RootNamespace>Something.Else</RootNamespace>
The downside to this is that tooling (ReSharper for instance) will now hint about wrong namespaces in your hand-typed files and respect this setting when creating new files.
My preferred solution for this issue would be for SpecFlow to prefix the namespace in generated .feature.cs
files. I haven't used CodeDom but expect this to be doable. A suitable prefix might be GeneratedBySpecflow
.
I ran into a worse situation than OP described which boils down to the same thing: A dependency whose namespace starts with the same segment as the test project one's has a System
namespace. Note that M$'s guidlines tell you to not re-use Microsoft.*
or System.*
namespaces when creating packages but instead prefix them - which leads to this.
EDIT:
If there's concerns about backwards compatibilitiy with other tools that interact with .feature.cs
files then perhaps an option in the specflow.json
could fill the gap by allowing the user to disable the prefix and thus revert back to the old behavior. I really hope such tools don't exist though.
Just noticed: This is a duplicate of #1576 or closely related (same root cause).
Faced the same issue as the OP. We're dealing with a huge solution with projects where the NUnit tests are residing in the same projects as the production code, separated from it with just a suffix in the namespace, such as ".NUnit". Not good, I know, but it is as it is. In order to solve it we're considering step-by-step taking these tests out of their current location to projects, dedicated for tests only. It cannot be done quickly as there are zillions of tests which is impossible to move in one go.
For some of the tests we considering to start using SpecFlow as it fits best for some of the scenarios.
Unfortunately, due to the fact mentioned above we cannot start using SpecFlow as it breaks with compilation error, as OP also mentioned.
Here I've reproduced a similar, but simpler case with that error: https://github.com/hwndmaster/lab/tree/master/SpecFlowGlobalNUnitIssue.
Some details of the issue I put in this file: https://github.com/hwndmaster/lab/blob/master/SpecFlowGlobalNUnitIssue/CompanyName.ComponentX/NUnit/LegacyTestForClass1.cs
Looking forward for any ideas how to resolve it without having to rename namespaces in the current legacy code.
Yes, an idea how to fix that without replacing CodeDom would be really cool. I don't have one. Happy to see an PR to solve this issue.