可以将自定义日志添加到Gherkin测试故事吗?

huangapple go评论55阅读模式
英文:

Is it possible to add custom logs to the Gherkin test narrative?

问题

Sure, here is the translated content:

我们有一些遵循这种模式的测试:

Scenario: 示例测试
    给定一个条件
    并且另一个条件
    然后发生一个操作
    并且测试一个条件

当我们运行测试时,“然后发生一个操作”短语启动一个进程并接收一个 ID,该 ID 也被后续测试步骤用于访问相同的进程。是否可能将该 ID(或任何自定义消息)写入测试输出?我正在寻找的示例如下,以“=>”开头的行:

给定一个条件
-> 完成:TestStepDefinition.GivenACondition()(2,0s)
并且另一个条件
-> 完成:TestStepDefinition.GivenAnotherCondition()(0,0s)
然后发生一个操作
=> 带有进程 ID 的自定义日志消息
-> 完成:TestStepDefinition.ThenAnActionOccurs()(6,1s)
并且测试一个条件
-> 完成:TestStepDefinition.ThenAConditionIsTested()(1,3s)

请注意,我只提供了要翻译的部分,不包括您的要求或其他内容。

英文:

We have some tests that follow this pattern:

Scenario: Example Test
    Given a condition
    And another condition
    Then an action occurs
    And a condition is tested

When we run the test the Then an action occurs phrase starts a process and receives an id, which is also used by later test steps to access the same process. Is it possible to write the id (or any custom message) to the test output? Anexample of what I'm looking for is below, on the line starting with =>.

Given a condition
-> done: TestStepDefinition.GivenACondition() (2,0s)
And another condition
-> done: TestStepDefinition.GivenAnotherCondition() (0,0s)
Then an action occurs
=> Custom log message with a process id
-> done: TestStepDefinition.ThenAnActionOccurs() (6,1s)
And a condition is tested
-> done: TestStepDefinition.ThenAConditionIsTested() (1,3s)

答案1

得分: 2

以下是您要翻译的部分:

"The SpecFlow Output API provides a means to write additional messages to the standard output. The ISpecFlowOutputHelper interface is an object automatically registered in the SpecFlow DI container, which gives you methods for writing to the standard output while a test is running. This should be available via context injection to hooks and step definitions."

Logging in Step Definitions

Simply declare an ISpecFlowOutputHelper parameter in the constructor for your step definition file:

[Binding]
public class YourSteps
{
    private readonly ISpecFlowOutputHelper logger;

    public YourSteps(ISpecFlowOutputHelper logger)
    {
        this.logger = logger;
    }

    [Given("X")]
    public void GivenX()
    {
        logger.WriteLine("...");
    }

    [When("Y")]
    public void WhenY()
    {
        logger.WriteLine("...");
    }

    [Then("Y")]
    public void ThenY()
    {
        logger.WriteLine("...");
    }
}

Logging in Hooks

I haven't tried every single hook, but you can use constructor injection or method injection. Constructor injection in a hooks file works the same as in a step definition file. Plus you can use method injection, and mix-and-match in the same file:

[Binding]
public class Hooks
{
    private readonly ISpecFlowOutputHelper logger;

    public Hooks(ISpecFlowOutputHelper logger)
    {
        this.logger = logger;
    }

    [BeforeScenario]
    public void BeforeScenario()
    {
        // Passed in via constructor injection
        logger.WriteLine("...");
    }

    [AfterScenario]
    public void AfterScenario(ISpecFlowOutputHelper output)
    { //                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        // Passed in via method injection (parameter name can be anything you like)
        output.WriteLine("...");
    }// ^^^^^^
}

I haven't verified this bit, however you should be able to use method injection for hooks that must be executed from a static context. This includes hooks like [BeforeFeature]:

[Binding]
public class Hooks
{
    [BeforeFeature]
    public static void BeforeFeature(ISpecFlowOutputHelper logger)
    {
        logger.WriteLine("...");
    }
}

Note that you can mix-and-match constructor injection and method injection in a single class, plus you can mix-and-match hooks executed from an instance or static context.

There are other methods available on the ISpecFlowOutputHelper interface. If you want some standard formatting for your output messages, consider placing them in extension methods:

namespace TechTalk.SpecFlow.Infrastructure
{
    public static class SpecFlowOutputHelperExtensions
    {
        public static void Info(this ISpecFlowOutputHelper logger, string message)
        {
            logger.WriteLine($"[{DateTime.Now}, Info]: {message}");
        }
    }
}

In the example above, you have a new method available to simplify logging:

[AfterScenario]
public void AfterScenario(ISpecFlowOutputHelper logger)
{
    logger.Info("Your info message here");
英文:

The SpecFlow Output API provides a means to write additional messages to the standard output. The ISpecFlowOutputHelper interface is an object automatically registered in the SpecFlow DI container, which gives you methods for writing to the standard output while a test is running. This should be available via context injection to hooks and step definitions.

Logging in Step Definitions

Simply declare an ISpecFlowOutputHelper parameter in the constructor for your step definition file:

[Binding]
public class YourSteps
{
    private readonly ISpecFlowOutputHelper logger;

    public YourSteps(ISpecFlowOutputHelper logger)
    {
        this.logger = logger;
    }

    [Given("X")]
    public void GivenX()
    {
        logger.WriteLine("...");
    }

    [When("Y")]
    public void WhenY()
    {
        logger.WriteLine("...");
    }

    [Then("Y")]
    public void ThenY()
    {
        logger.WriteLine("...");
    }
}

Logging in Hooks

I haven't tried every single hook, but you can use constructor injection or method injection. Constructor injection in a hooks file works the same as in a step definition file. Plus you can use method injection, and mix-and-match in the same file:

[Binding]
public class Hooks
{
    private readonly ISpecFlowOutputHelper logger;

    public Hooks(ISpecFlowOutputHelper logger)
    {
        this.logger = logger;
    }

    [BeforeScenario]
    public void BeforeScenario()
    {
        // Passed in via constructor injection
        logger.WriteLine("...");
    }

    [AfterScenario]
    public void AfterScenario(ISpecFlowOutputHelper output)
    { //                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        // Passed in via method injection (parameter name can be anything you like)
        output.WriteLine("...");
    }// ^^^^^^
}

I haven't verified this bit, however you should be able to use method injection for hooks that must be executed from a static context. This includes hooks like [BeforeFeature]:

[Binding]
public class Hooks
{
    [BeforeFeature]
    public static void BeforeFeature(ISpecFlowOutputHelper logger)
    {
        logger.WriteLine("...");
    }
}

Note that you can mix-and-match constructor injection and method injection in a single class, plus you can mix-and-match hooks executed from an instance or static context.

There are other methods available on the ISpecFlowOutputHelper interface. If you want some standard formatting for your output messages, consider placing them in extension methods:

namespace TechTalk.SpecFlow.Infrastructure
{
    public static class SpecFlowOutputHelperExtensions
    {
        public static void Info(this ISpecFlowOutputHelper logger, string message)
        {
            logger.WriteLine($"[{DateTime.Now}, Info]: {message}");
        }
    }
}

In the example above, you have a new method available to simplify logging:

[AfterScenario]
public void AfterScenario(ISpecFlowOutputHelper logger)
{
    logger.Info("Your info message here");

huangapple
  • 本文由 发表于 2023年5月22日 14:19:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76303465.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定