Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Two Bug Reports concerning Specflow
royboy23
#1 Posted : Friday, June 23, 2023 10:54:10 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
Hi Remco,

I encountered an issue while evaluating the latest version of NCrunch with Nunit and Specflow. Here's the problem I faced:

I have configured NCrunch to run impacted tests automatically. When I added a new test step in my .feature file, the test was executed as expected and failed due to the missing step definition.

However, when I added the step definition, the test didn't run again, even though it was clearly impacted. Instead, I had to run it manually.

Is there a setting or workaround that could address this issue?

Thank you for your assistance!
royboy23
#2 Posted : Friday, June 23, 2023 11:17:44 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
I just noticed something else in connection with Specflow, which is even more irritating: In earlier versions I have used, there used to be an red X marking test steps that have failed. But now, there are only the red dots on all steps (even the ones after the failed test), so there is no quick way to see where the problem is.

So I have to scroll down and read the whole output in order to find the step with the problem. This problem affects me pretty often, so it is quite annoying.
bhugot
#3 Posted : Friday, June 23, 2023 11:39:38 AM(UTC)
Rank: Member

Groups: Registered
Joined: 8/19/2018(UTC)
Posts: 10
Location: France

Thanks: 1 times
Was thanked: 1 time(s) in 1 post(s)
It maybe due to change in visual studio. With last version with incremental build the changes in feature file are not detected. You need to do a rebuild.
Remco
#4 Posted : Friday, June 23, 2023 1:12:27 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
Hi, thanks for sharing these issues.

I would need to see the exact steps and code involved to be certain, but I suspect that with this particular scenario you've hit an edge case where the impact detection doesn't work reliably.

Impact detection works by performing hash comparisons between versions of a codebase to identify which methods have changed. When a method is considered changed, any tests covering that method are marked as impacted. As you can probably imagine, this won't catch everything. For example, if you have code that manages to call through to a method in such a way that compiles but the method is never executed, then creating/fixing the method will not necessarily result in the test being considered impacted. There are a few situations where we do manage to handle this (i.e. polymorphism), but we're limited by how much we can handle without making impact detection computationally impractical. We catch most things, but if you aren't certain, it's best to just run the tests or switch to fully automatic mode.

Regarding the missing Xs; these should usually be placed through NCrunch parsing the stack traces of exceptions. When you get an exception in the test, does the exception bubble all the way up to the runner? And do you see the call stack for the exception fully reported in the Tests Window with all the line numbers and source files correct?
royboy23
#5 Posted : Friday, June 23, 2023 3:58:03 PM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
Thanks for your quick reply!

You should be able to reproduce the issue as follows:

0. Set the Engine mode to "Run impacted tests automatically, others manually"
1. Create a new .net 4.8 Project and install NCrunch 4.16.0.4 / Specflow 3.9.74 / NUnit 3.13.3
2. Create a .feature file with the following scenario

Scenario: NCrunch 4.16.0.4 / Specflow 3.9.74 / NUnit 3.13.3 regression test
When I execute this step

3. Run the test and note that it rightfully fails since the "When" step is not implemented.

3. Create a TestSteps.cs file with the following content:

using TechTalk.SpecFlow;

namespace MyNamespace
{
[Binding]
internal class TestStepscs
{

[When(@"I execute this step")]
public void WhenIExecuteThisStep()
{
throw new PendingStepException();
}

}
}

Note that the test is not automatically rerun, so the test result makes it look as if the step definition was still missing.

Also, a similar case:

When I change [When(@"I execute this step")] to [When(@"I execute this step2")], the test is rerun automatically.
But when I change it back again, the test is not automatically rerun.

As for the missing Xs: The problem might indeed be that the test runner carries on to the next step, even though the previous step has failed. For instance if the test looks like this:

Scenario: NCrunch 4.16.0.4 / Specflow 3.9.74 / NUnit 3.13.3 regression test
When I execute this step
When I execute this step

And the test step looks like this:
[When(@"I execute this step")]
public void WhenIExecuteThisStep()
{
throw new Exception();
}

Then the x is missing and I get the following Trace Output:

NCrunch: This test was executed on server '(local)'


When I execute this step
-> error: Eine Ausnahme vom Typ "System.Exception" wurde ausgelöst. (0,0s)
When I execute this step
-> skipped because of previous errors
System.Exception : Eine Ausnahme vom Typ "System.Exception" wurde ausgelöst.
bei Zeiterfassung.UnitTests.Business.HolidayCalculation.TestStepscs.WhenIExecuteThisStep() in C:\Projects\ZeiterfassungVNext\Zeiterfassung.UnitTests\Business\HolidayCalculation\TestStepscs.cs:Zeile 13.
bei lambda_method(Closure , IContextManager )
bei TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration) in D:\a\1\s\TechTalk.SpecFlow\Bindings\BindingInvoker.cs:Zeile 68.
bei TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments, TimeSpan& duration) in D:\a\1\s\TechTalk.SpecFlow\Infrastructure\TestExecutionEngine.cs:Zeile 567.
bei TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(IContextManager contextManager, StepInstance stepInstance) in D:\a\1\s\TechTalk.SpecFlow\Infrastructure\TestExecutionEngine.cs:Zeile 480.
bei TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep() in D:\a\1\s\TechTalk.SpecFlow\Infrastructure\TestExecutionEngine.cs:Zeile 203.
bei TechTalk.SpecFlow.TestRunner.CollectScenarioErrors() in D:\a\1\s\TechTalk.SpecFlow\TestRunner.cs:Zeile 59.
bei Zeiterfassung.UnitTests.Business.HolidayCalculation.InOrderToImplementTheCalculationOfRemainingHolidaysFeature.ScenarioCleanup()
bei Zeiterfassung.UnitTests.Business.HolidayCalculation.InOrderToImplementTheCalculationOfRemainingHolidaysFeature.NCrunch4_16_0_4Specflow3_9_74NUnit3_13_3RegressionTest() in C:\Projects\ZeiterfassungVNext\Zeiterfassung.UnitTests\Business\HolidayCalculation\HolidayAdjustmentEntryGeneration.feature:Zeile 43.

Is there any workaround you could recommend for my configuration?

Also, note that none of the code lines in the trace output listed above are clickable. When I want to navigate there, I need to copy and paste them to the resharper search window. It would be much more comfortable if the line references were clickable and underlined in blue instead.


Thanks again for your help!
Remco
#6 Posted : Saturday, June 24, 2023 12:03:58 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
Thanks for these extra details. I'll take a look at this problem over the coming week and will update you with what I find.

Can you confirm for me whether these issues are new for you, or whether they may have existed for a while?
royboy23
#7 Posted : Saturday, June 24, 2023 7:03:37 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
The first issue (impacted tests are not always run) is new, but the second one might be older. I am not quite sure though since I haven't been using NCrunch for over a year now.
Remco
#8 Posted : Sunday, June 25, 2023 12:28:17 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
I've taken a close look at the impacted tests not being run issue.

This issue appears because of the mechanics involved. SpecFlow is using reflection to identify the step definitions referenced by the feature files. If the step definitions don't exist, the reflection call does not return it for SpecFlow, and it gives the error message. When the definition is then eventually implemented, there is no test coverage existing for the new method. This means NCrunch has no way to know which tests are impacted by its existence. Thus the test that depends on the new step definition is not run automatically.

You can recreate this scenario yourself without SpecFlow by using Type.GetMethod and MethodInfo.Invoke to call a method using reflection in a simple test. If you remove the method being called, then add it back in, NCrunch will not re-run the test.

The root issue here is that for impact detection purposes, NCrunch cannot traverse dependencies between code elements that work using reflection, as these dependencies are represented using run-time code and are not static IL-based dependencies. This is a constraint that has existed since the IL-based impact detection was first introduced in NCrunch, so this isn't a new issue for us.

I did at one stage do a deep dive on trying to find ways to handle this kind of scenario in NCrunch, but all solutions examined proved to be too slow, too unreliable, or too difficult to maintain for them to be practical.

The good news is that you'll only see this once for every step definition you implement. After you've placed the step definition so that SpecFlow can call it, the code coverage for the method will be detected and impact detection will begin to work as normal. I would suggest using one of NCrunch's Run Tests shortcut keys as a workaround for every time you introduce a new step definition.

We're looking into the exception issue and will update you when we have more details.
michaelkroes
#9 Posted : Tuesday, June 27, 2023 6:29:06 PM(UTC)
Rank: NCrunch Developer

Groups: Registered
Joined: 9/22/2017(UTC)
Posts: 306
Location: Netherlands

Thanks: 138 times
Was thanked: 73 time(s) in 69 post(s)
I've looked into the exception reporting by SpecFlow. The sequence in which SpecFlow executes and reports test results plays a significant role in this situation. SpecFlow follows a sequential execution model, where it runs the steps in the order they appear within a scenario. However, when a step fails, SpecFlow immediately stops executing the remaining steps for that scenario. These skipped steps are still reported but labeled as "skipped" since they were not executed.

Consequently, the report containing the full exception is generated at the end of the steps because it includes the details of the failed step and any skipped steps. This behavior is inherent to the way SpecFlow operates, and unfortunately, there is no direct solution to change this behavior within NCrunch.

I believe that in much older versions this behaved differently and we'd actually report the failed step on the correct line in the scenario. I tried a year old NCrunch and SpecFlow but that had the same problem. So I'm not sure when this changed. It's been a while since I used it myself.

Regarding your second concern about German stack traces not being parsed correctly, I've added support for this to tests being run under a netcore runner. If you would like to try/test this let me know and I'll create a build for you.

Thanks again for taking the time to report this!
royboy23
#10 Posted : Wednesday, June 28, 2023 7:19:21 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
Hi Remco,

Thanks for taking the time to look into these issues!

The test that is not run automatically is not a big problem at all. It's easy to ignore once the I know about this.

The way that an exception is displayed is much more annoying since I have to scroll through the entire Trace output and navigate manually to the code file and line in question every time a test fails. Either this or start a debug session, which takes a few seconds to start up. The tests I am working on are often quite complex integration tests with lots of background steps, so there is quite a lot of output to scroll through. So, any feature to make this process a bit more comfortable would be very welcome. A clickable stack trace would be good, or ideally even a context menu entry that takes me directly to the top code line of the exception trace without me having to scroll through the output.

If you have an an experimental build featuring clickable stack traces I'd gladly give it a try, but I am only working on legacy .net 4.8 projects at the moment and don't expect this to change for quite some time.
michaelkroes
#11 Posted : Wednesday, June 28, 2023 6:21:14 PM(UTC)
Rank: NCrunch Developer

Groups: Registered
Joined: 9/22/2017(UTC)
Posts: 306
Location: Netherlands

Thanks: 138 times
Was thanked: 73 time(s) in 69 post(s)
Hi,

I missed in your initial comment that you were using net 4.8. I made a speculative fix for German exceptions under netcore/net5+. That does mean there is something else going on. Out tests for German exceptions are still passing. I tried copying your exception into our test, this fails. However I do expect that that has something todo with the formatting on the forum. The whitespace in front of the exception matters for our parser.

Would you mind mailing me the entire trace output of the test in a text file? You can mail it to my first name michael at ncrunch dot net. (vague for spam reasons)
royboy23
#12 Posted : Thursday, June 29, 2023 10:52:30 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
michaelkroes;16710 wrote:
Hi,

I missed in your initial comment that you were using net 4.8. I made a speculative fix for German exceptions under netcore/net5+. That does mean there is something else going on. Out tests for German exceptions are still passing. I tried copying your exception into our test, this fails. However I do expect that that has something todo with the formatting on the forum. The whitespace in front of the exception matters for our parser.

Would you mind mailing me the entire trace output of the test in a text file? You can mail it to my first name michael at ncrunch dot net. (vague for spam reasons)


No problem at all, I just sent it. Due to some weird coincidence, trace parsing actually started working again for one specific scenario, so I sent you some info on that as well.

Thanks for taking the time to look into this!
royboy23
#13 Posted : Thursday, June 29, 2023 1:03:08 PM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
Coincidently I found out a little bit more about the exception parsing error, so now I have a fully working minimalistic regression test.

This goes in the .feature file:


Code:
Scenario: Exception parsing does not work when using German locale
	When I execute this step with German locale
	When I execute this step with German locale

Scenario: Exception parsing works when using using EN-US locale
	When I execute this step with US locale
	When I execute this step with US locale


And this is the the steps definition:

Code:
using System;
using System.Globalization;
using System.Threading;
using TechTalk.SpecFlow;

namespace SpecflowRegression
{
    [Binding]
    internal class TestStepscs
    {
        [When(@"I execute this step with German locale")]
        public void WhenIExecuteThisStepWithGermanLocale()
        {
            var cultureInfo=CultureInfo.CreateSpecificCulture("de-DE");
            Thread.CurrentThread.CurrentCulture = cultureInfo;
            Thread.CurrentThread.CurrentUICulture = cultureInfo;
            throw new Exception();
        }

        [When(@"I execute this step with US locale")]
        public void WhenIExecuteThisStepWithUSLocale()
        {
            var cultureInfo=CultureInfo.CreateSpecificCulture("en-US");
            Thread.CurrentThread.CurrentCulture = cultureInfo;
            Thread.CurrentThread.CurrentUICulture = cultureInfo;
            throw new Exception();
        }

    }
}
Remco
#14 Posted : Friday, June 30, 2023 6:57:28 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
We suspect the root of this issue is that the culture being used by SpecFlow is different to that being used by NUnit.

Apparently, SpecFlow will reset the culture according to its configuration when it executes the step definitions (see for more info: https://github.com/SpecFlowOSS/SpecFlow/issues/1275).

Between test execution, NCrunch will run code that tries to capture the current culture, and will store this against the test result. It then uses this culture when trying to parse exceptions. We suspect that because SpecFlow has set your culture to de-DE but NUnit thinks that the culture is en-US, the culture used to parse the exception doesn't match the stack trace and the parsing fails.

We don't have a way to reproduce this problem as there seem to be environmental components to it. Assuming we're right about what's causing this, you need to force SpecFlow to use the same culture as NUnit. The link above contains some suggestions for how to do this.
1 user thanked Remco for this useful post.
royboy23 on 6/30/2023(UTC)
royboy23
#15 Posted : Friday, June 30, 2023 8:30:44 AM(UTC)
Rank: Member

Groups: Registered
Joined: 3/3/2014(UTC)
Posts: 21
Location: Germany

Thanks: 3 times
I can confirm that making the following two settings in the specflow.json fixes the problem in some instances:

"language": { "feature": "en-US" },
"bindingCulture": {"name": "en-US"},


However, it is not a reliable workaround. Once these settings are made, using some functions from the SpecFlow framework such as table.CompareToSet<T> set System.Threading.Thread.CurrentThread.CurrentUICulture and System.Threading.Thread.CurrentThread.CurrentCulture to the cultures specified in the json file as a side effect. Afterwards, ncrunch exception parsing works for the remainder of the given step. But when the next step starts, the same problem exists again. Also, if I am not using any such framework functions or if an exception occurs before the framework function call, then the exception is not parsed.

It seems that the only reliable way to work around this issue is to excplicitly set System.Threading.Thread.CurrentThread.CurrentUICulture and System.Threading.Thread.CurrentThread.CurrentCulture to en-US at the beginning of each step as shown in my tests above. Fortunately this is easy to achieve with a BeforeStep hook as documented at https://docs.specflow.or...est/Bindings/Hooks.html

However, it still far from ideal since it forces me to write my specifications with en-US locale, which can be a bit of a nuisance for me as an european as I often need to work with date and time values in the specifications.
Remco
#16 Posted : Friday, June 30, 2023 1:46:16 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
Something else you can try is the reverse - to force NUnit to use de-DE by declaring SetCultureAttribute at assembly level.

Sadly, there isn't much we can do to fix this behaviour in NCrunch - as technically, the problem isn't in the NCrunch codebase. At some level you need to have a consistent culture which can be used for the parsing of exceptions. In situations where this is non-deterministic (as when SpecFlow overrides it), we don't have a way to effectively handle it.

Sorry, but we can't build in a solution for this in NCrunch itself. You'll need to resort to a workaround.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.142 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download