SpecFlow icon indicating copy to clipboard operation
SpecFlow copied to clipboard

WIP. xUnit Collection name and Collection fixture class full name tags #1430

Open Eshva opened this issue 5 years ago • 7 comments

Namaste! I tried to solve #1430. But because I can't build NuGet-package and run tests locally I can't validate my work. I'm very new to BDD and SpecFlow. So what I tried to accomplish:

  1. The @xunit:collection tag is broken. The problem was collection name could be any string not just a valid identifier. I've fixed that. Now I require that tag should be in a form (note the quotes):
@xunit:collection("collection name event with spaces and любые национальные символы")
  1. There is no need to specify CollectionAttribute on a text class to make it parallelizable or not. If there is no CollectionAttribute on a class it has a virtual one by default, every class is a separate collection.
  2. I've added a tag for collection fixture class name: @xunit:collectionFixtureClassFullName. Yes it's a bit long but at least self describing. The value of this tag is the full class name of a test collection fixture. I tried to use collection class full name (because collection class has it's name in the attribute and collection fixture class name in type declaration) but realized that I have no access to actual user code during code generation pass. The best user can specify is the collection fixture class full name. Usage (once again quotes are required):
@xunit:collectionFixtureClassFullName("Some.User.Namespace.CollectionFixture")

The class name can contain any word characters not only Latin. Please don't forget about other languages and cultures. They are and .NET allows to use those characters for valid literals. 4. Collection name and Collection fixture class full name tags are mutually exclusive. The user should one or another or non at all.

Thank you for your attention and I'm ready to discuss the change.

Types of changes

  • [x] Bug fix (non-breaking change which fixes an issue).
  • [x] New feature (non-breaking change which adds functionality).
  • [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected).

Checklist:

  • [ ] I've added tests for my code.
  • [x] My change requires a change to the documentation.
  • [ ] I have updated the documentation accordingly.
  • [ ] I have added an entry to the changelog

Eshva avatar Dec 23 '19 23:12 Eshva

https://github.com/techtalk/SpecFlow/issues/686#issuecomment-452057928 collection name was limited to alpha,numeric, _- for the purpose, because tag names has this limit. I am trying to find out why tags originally has such limitation

sphinxy avatar Dec 30 '19 12:12 sphinxy

Sorry that I come so late to this PR. We were a little bit preoccupied in the last weeks with other stuff (https://specflow.org/2020/tricentis-acquires-specflow/).

Thanks for the PR!

What I would like to see is a better scenario to test the functionality. You added one in Tests/TechTalk.SpecFlow.Specs/Features/UnitTestProviderSpecific/XUnit/XUnit2Provider.feature, but the assertations has nothing todo with the attribute. Can you get somehow the xUnit collection of your testclass and assert of it? Or something else. Currently we only know that the generated project builds and the test will be green. If I remove all the generation code, the scenario will still be clean.

SabotageAndi avatar Jan 17 '20 14:01 SabotageAndi

Hey guys,

I'm seeing the same issue #1430, two instances are created and the second time it doesn't call the InitiliazeAsync method.

I'm trying to start async a docker container in this method, and the second time it passes by the constructor of my fixture it recreates my container instance, but doesn't call the InitiliazeAsync method. So in the end, I have the instance the second time, but it is not initialized.

Do you guys have any plans for this fix? Or do you know any workarounds for this?

Thanks in advance :)

jdelucaa avatar May 20 '20 18:05 jdelucaa

@jdelucaa Yes a workaround for this is to avoid injecting the fixture in the step constructor and initialize a static property (Singleton-ish hack) and then from your binding classes you can access the collection fixture via this static property. You need also to use the @xunit:collection(<Collection Name>) tag in your feature files in order for this hack to work

`public class TestAppFixture : IAsyncLifetime { private IHost _host;

    public async Task InitializeAsync()
    {
        if (Default != null)
            throw new InvalidOperationException("Can't Initialize Collection Fixture Twice");

        var hostBuilder = new HostBuilder()
            .ConfigureWebHost(webHost =>
            {
                webHost.UseTestServer();
                webHost.UseEnvironment("Test");
                webHost.UseStartup<Startup>();
            });

        _host = await hostBuilder.StartAsync();
        Default = this;
    }

    public static TestAppFixture Default { get; private set; }

    public HttpClient HttpClient => _host.GetTestClient();

    public Task DisposeAsync()
    {
        _host?.Dispose();
        return Task.CompletedTask;
    }
}`

iabdelkareem avatar Aug 23 '20 08:08 iabdelkareem

Hi Any update? Thank you

zegsampaio avatar Nov 27 '20 19:11 zegsampaio

Any plans on fixing this issue?

rdasan avatar Feb 16 '21 23:02 rdasan