【问题标题】:documentation through testing Commands and events通过测试命令和事件记录文档
【发布时间】:2012-05-04 15:49:51
【问题描述】:

我愿意通过我的测试生成一些文档。到目前为止,我的测试看起来像这样:

 public class creation_of_a_new_inventory_item : BaseClass<CreateInventoryItem>
    {
    private Guid _Id = Guid.NewGuid();
    private string _Name = "test";

    public override CommandHandler<CreateInventoryItem> OnHandle(IRepository repository)
    {
        return  new CreateInventoryItemHandler(repository);
    }

    protected override IEnumerable<IEvent> Given()
    {
        yield break;
    }

    protected override CreateInventoryItem When()
    {
        return new CreateInventoryItem()
        {
            Id = _Id,
            Name = _Name
        };
    }

    protected override IEnumerable<IEvent> Expect()
    {
        yield return new InventoryItemCreatedAdded()
                         {
                             Id = _Id,
                             Name = _Name
                         };
    }

   [Test]
    public void does_not_throw_an_Exception()
    {
        Assert.IsNull(Caught);
    }
}

不幸的是,在使用 Nunit 时,我很难获得所需的信息以生成一些漂亮且易于阅读的文档。

你们中有没有人使用 Nunit 来做到这一点?你能给我指出一些有趣的资源吗,我会在网上忽略吗?您是否使用其他工具从测试中生成文档?

[编辑] 我的意图是从我的代码中产生类似这样的东西:

 creation of a new inventory item
     When I Create Inventory Item 
        Id:{id},
        Name:{name}
     Then 
         Inventory Item is Created ({Success/Fail})
             Id:{id},
             Name:{name} 
     And does not throw an Exception ({Success/Fail})

这适用于第一种方法。我以后可能会改变,但主要目标是这个。我的目标是在不让他输入代码的情况下写出老板可能会理解的东西。

[/编辑]

【问题讨论】:

  • 你用什么来“生成文档”?
  • 起初我打算使用带有 eventlistenner 的 Nunit 插件来获得我的测试结果。但是我的项目对这个插件的依赖太多了,所以我想知道找到更好的方法......

标签: c# testing documentation cqrs event-sourcing


【解决方案1】:

不要为 NUnit 烦恼。只需使用反射扫描您的程序集。您的测试夹具的结构将始终相同,因此生成文档非常容易。您还可以将类似 Description() 格式化方法添加到所有命令和事件中,以获得具有实际值的描述性输出。

【讨论】:

    【解决方案2】:

    我在 Documently 中得到了类似的东西:

    [Subject(typeof(Customer))]
    public class When_customer_relocates
        : Handler_and_Aggregate_spec
    {
        static NewId AggregateId = NewId.Next();
    
        static RelocateTheCustomerHandler handler;
    
        Establish context = () =>
            {
                setup_repository_for<Customer>();
                has_seen_events<Customer>(CustomerTestFactory.Registered(AggregateId));
                handler = new RelocateTheCustomerHandler(() => repo);
            };
    
        Because of = () =>
            handler.Consume(a_command<RelocateTheCustomer>(new MsgImpl.Relocate
                {
                    AggregateId = AggregateId,
                    NewAddress = new MsgImpl.Address
                        {
                            City = "Berlin",
                            PostalCode = "4566",
                            Street = "FünfteStrasse",
                            StreetNumber = 45
                        },
                    Version = 1U
                }));
    
        It should_have_loaded_existing = () =>
            A.CallTo(() => repo.GetById<Customer>(AggregateId, 1)).MustHaveHappened(Repeated.Exactly.Once);
    
        It should_have_published_relocated_event = () => 
            yieldedEvents.ShouldContain<Relocated>(
                r => r.City.ShouldEqual("Berlin"));
    
        Behaves_like<Event_versions_are_greater_than_zero> should_specify_versions_above_zero;
        Behaves_like<Event_versions_are_monotonically_increasing> should_specify_monotonically_increasing_versions;
        Behaves_like<Events_has_non_default_aggregate_root_id> should_have_non_default_ar_ids;
    }
    

    但是,您可以自行判断它的可读性。

    另一种选择可能是 SpecFlow,如下所示:

    Feature: Score Calculation 
      In order to know my performance
      As a player
      I want the system to calculate my total score
    
    Scenario: Gutter game
      Given a new bowling game
      When all of my balls are landing in the gutter
      Then my total score should be 0
    
    Scenario: Beginners game
      Given a new bowling game
      When I roll 2 and 7
      And I roll 3 and 4
      And I roll 8 times 1 and 1
      Then my total score should be 32
    
    Scenario: Another beginners game
      Given a new bowling game
      When I roll the following series: 2,7,3,4,1,1,5,1,1,1,1,1,1,1,1,1,1,1,5,1
      Then my total score should be 40
    
    Scenario: All Strikes
      Given a new bowling game
      When all of my rolls are strikes
      Then my total score should be 300
    
    Scenario: One single spare
       Given a new bowling game 
       When I roll the following series: 2,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
       Then my total score should be 29
    
    Scenario: All spares
      Given a new bowling game
      When I roll 10 times 1 and 9
      And I roll 1
      Then my total score should be 110
    

    如果取决于您所说的文档;规范流程实际上非常接近文档。

    【讨论】:

    • 谢谢 Henrik,我会看看 Documently 是如何完成的。它可能会给我一些关于如何进行的好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多