Skip to content

Reqnroll-generated feature classes fail with InvariantGlobalization=true #1110

Description

@verdie-g

Reqnroll Version

3.3.4

Which test runner are you using?

NUnit

Test Runner Version Number

1.65.38 (TUnit)

.NET Implementation

.NET 9.0

Test Execution Method

Command line – PLEASE SPECIFY THE FULL COMMAND LINE

Content of reqnroll.json configuration file

{
  "$schema": "https://schemas.reqnroll.net/reqnroll-config-latest.json"
}

Issue Description

Reqnroll tests fail during feature-class initialization when the test project enables globalization-invariant mode:

<InvariantGlobalization>true</InvariantGlobalization>

Reqnroll generates a static FeatureInfo field that constructs a named CultureInfo:

private static global::Reqnroll.FeatureInfo featureInfo =
    new global::Reqnroll.FeatureInfo(
        new global::System.Globalization.CultureInfo("en-US"),
        /* ... */);

Since .NET 6, globalization-invariant mode disallows creating named cultures by default. Initializing the generated feature class therefore throws:

System.TypeInitializationException:
The type initializer for 'UsersFeature' threw an exception.

System.Globalization.CultureNotFoundException:
Only the invariant culture is supported in globalization-invariant mode.
(Parameter 'name')
en-US is an invalid culture identifier.
at System.Globalization.CultureInfo..ctor(String name, Boolean useUserOverride)
at Test.Features.UsersFeature..cctor()

The same incompatibility also appears in Reqnroll runtime configuration: ConfigurationLoader.GetDefault() constructs the default feature language using CultureInfo.GetCultureInfo("en-US").

The expected behavior is that Reqnroll can run with invariant globalization when tests do not require culture-specific parsing or formatting. Alternatively, Reqnroll should explicitly document invariant mode as unsupported and provide a clear diagnostic.

The following workaround allows Reqnroll to construct named cultures while retaining invariant globalization:

<InvariantGlobalization>true</InvariantGlobalization>
<PredefinedCulturesOnly>false</PredefinedCulturesOnly>

With this configuration, named cultures use invariant culture data. The previously failing scenario passes. Culture-specific conversions are naturally still unavailable.

Steps to Reproduce

  1. Create a Reqnroll test project using Reqnroll.TUnit 3.3.4 and TUnit 1.65.38.
  2. Enable invariant globalization:
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net11.0</TargetFramework>
    <InvariantGlobalization>true</InvariantGlobalization>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Reqnroll.TUnit" Version="3.3.4" />
    <PackageReference Include="TUnit" Version="1.65.38" />
  </ItemGroup>

</Project>
  1. Add an English feature:
    Feature: Invariant globalization

  Scenario: Run a scenario
    Given the application uses invariant globalization
  1. Add a matching binding:
   using Reqnroll;

[Binding]
public sealed class Steps
{
   [Given("the application uses invariant globalization")]
   public void GivenTheApplicationUsesInvariantGlobalization()
   {
   }
}
  1. Run the test project:
   dotnet run --project Repro.csproj -- --disable-logo
  1. Observe that the generated feature class throws CultureNotFoundException while constructing CultureInfo("en-US").
  2. Add the workaround and rerun:
   <PredefinedCulturesOnly>false</PredefinedCulturesOnly>
  1. Observe that the feature class initializes and the scenario executes.

Link to Repro Project

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions