When using soft asserts in SpecFlow the test case in the extent report shows test as passed but should be failed

667 Views Asked by At

I am working with a testing framework that uses BDD approach (SpecFlow), C# and ExtentReports for reporting.

I'm using soft asserts for my steps to be able to continue executing. The issue is that the test case that is FAILING locally is marked as PASSED in extent reports. How can i set status for the step definition FAILED in order to see the test case is marked as FAILED in extent reports as well? Here is my SofAssert class:

public static class SoftAssert    {

private static readonly ThreadLocal<List<string>> _assertionsMessages = new ThreadLocal<List<string>>();
        
public static void Add(Action action)         {
      _assertionsMessages.Value ? ?=new List < string > ();
      try {
        action.Invoke();
      }
      catch(Exception exception) {
        _assertionsMessages.Value.Add(exception.Message);
        LogError(exception.Message);
      }
    }
    public static void AssertAll() {
  
      Logger.Info("-----------Test Finished-----------");
      if (_assertionsMessages.Value == null || _assertionsMessages.Value.Count == 0) return;
      var messages = new List < string > (_assertionsMessages.Value);
      _assertionsMessages.Value.Clear();
      throw new AssertionException(messages);
    }

private static void LogError(string message)
        {
            Logger.Fatal("ERROR => !!!!!!");
            Logger.Fatal($"         {message}");
            Logger.Fatal("         !!!!!!");
        }
    }

here is AssertionException :

public class AssertionException : NUnit.Framework.AssertionException
    {
        public AssertionException(List<string> assertsMessages) : base($"\nAsserts fails:\n{GetFormattedLog(assertsMessages)}")
        {

        }

    private static string GetFormattedLog(List<string> assertsMessages)
    {
        var stringBuilder = new StringBuilder();
        assertsMessages.ForEach(message => stringBuilder.AppendLine(message));
        return stringBuilder.ToString();
    }
}

And here is my hooks from BaseTest class:

[BeforeFeature]
        public static void BeforeFeature(FeatureContext featureContext)
        {
            _featureName = _extentReporter.CreateTest<Feature>(featureContext.FeatureInfo.Title);
        }

    [BeforeScenario]
public void BeforeScenario()
{
  _scenarioName = _featureName.CreateNode < Scenario > (_scenarioContext.ScenarioInfo.Title);
}


    [AfterStep]
        public void InsertReportingSteps()
        {
            var stepType = _scenarioContext.StepContext.StepInfo.StepDefinitionType.ToString();

            if (_scenarioContext.TestError == null)
            {
                switch (stepType)
                {
                    case "Given":
                        _scenarioName.CreateNode<Given>(_scenarioContext.StepContext.StepInfo.Text);
                        break;
                    case "When":
                        _scenarioName.CreateNode<When>(_scenarioContext.StepContext.StepInfo.Text);
                        break;
                    case "Then":
                        _scenarioName.CreateNode<Then>(_scenarioContext.StepContext.StepInfo.Text);
                        break;
                    case "And":
                        _scenarioName.CreateNode<And>(_scenarioContext.StepContext.StepInfo.Text);
                        break;
                }
            }
            else if (_scenarioContext.TestError != null)
            {                
                switch (stepType)
                {
                    case "Given":
                        _scenarioName.CreateNode<Given>(_scenarioContext.StepContext.StepInfo.Text).Fail(_scenarioContext.TestError.Message);
  
                        break;
                    case "When":
                        _scenarioName.CreateNode<When>(_scenarioContext.StepContext.StepInfo.Text).Fail(_scenarioContext.TestError.Message);

                        break;
                    case "Then":
                        _scenarioName.CreateNode<Then>(_scenarioContext.StepContext.StepInfo.Text).Fail(_scenarioContext.TestError.Message);
                        break;
                    case "And":
                        _scenarioName.CreateNode<And>(_scenarioContext.StepContext.StepInfo.Text).Fail(_scenarioContext.TestError.Message);
                        break;
                }
            }
            else if (_scenarioContext.ScenarioExecutionStatus.ToString().Equals("StepDefinitionPending"))
            {
                switch (stepType)
                {
                    case "Given":
                        _scenarioName.CreateNode<Given>(_scenarioContext.StepContext.StepInfo.Text).Skip("Step Definition Pending");
                        break;
                    case "When":
                        _scenarioName.CreateNode<When>(_scenarioContext.StepContext.StepInfo.Text).Skip("Step Definition Pending");
                        break;
                    case "Then":
                        _scenarioName.CreateNode<Then>(_scenarioContext.StepContext.StepInfo.Text).Skip("Step Definition Pending");
                        break;
                    case "And":
                        _scenarioName.CreateNode<And>(_scenarioContext.StepContext.StepInfo.Text).Skip("Step Definition Pending");
                        break;
                }
            }
        }


[AfterScenario]
        public static void TearDownReport()
        {
            try
            {
                SoftAssert.AssertAll();
            }
            finally
            {
                try
                {
                    _extentReporter.Flush();
                    
                }
                catch (InvalidOperationException e)
                {
                    //ignored
                }
            }  
        }

the test is :

[When(@"Get Alert")]
    public void WhenTheFirstNumberIsAdded()
    {
        var alert = _Client.GetAlert();
// Making the test to FAIL. Checking status code equal to 400 
            SoftAssert.Add(() => alert.SuccessModel.StatusCode.Should().Be(400));  
        }
0

There are 0 best solutions below