跳到内容

实验性

此功能处于 Alpha 阶段。API 可能会在次要版本增量中更改。

hitchstory YAML 故事旨在尽可能地易于阅读,同时仍然简洁且去重。这意味着这些故事对于不了解代码的人来说不会那么容易阅读。

在简洁和去重优先于可读性的情况下,前者优先。YAML 故事本身并非旨在替代利益相关者文档。

然而,YAML 故事旨在用于生成可读的文档,供利益相关者使用。

下面显示的示例演示了如何将故事通过 jinja2 转换为 markdown。然后可以使用此 markdown 通过静态站点生成器生成 HTML。

虽然 markdown 是给出的示例,但原则上,任何类型的文本标记都可以使用故事生成。

代码示例

example.story

Login:
  about: Simple log in.
  jiras: AZT-344, AZT-345
  with:
    username: AzureDiamond
    password: hunter2
  given:
    url: /loginurl
  steps:
  - Fill form:
      username: (( username ))
      password: (( password ))
  - Click: login
  - Drag:
      from item: left
      to item: right
  - Click:
      item: right
      double: yes


Log in on another url:
  about: Alternate log in URL.
  jiras: AZT-344, AZT-589
  based on: login
  given:
    url: /alternativeloginurl

Log in as president:
  about: For stories that involve Trump.
  jiras: AZT-611
  based on: login
  with:
    username: DonaldTrump
    password: iamsosmrt
engine.py

from hitchstory import BaseEngine, GivenDefinition, GivenProperty
from hitchstory import InfoDefinition, InfoProperty, validate
from strictyaml import Map, Int, Str, Bool, Optional, CommaSeparated


class Engine(BaseEngine):
    given_definition = GivenDefinition(
        url=GivenProperty(schema=Str()),
    )

    info_definition = InfoDefinition(
        jiras=InfoProperty(schema=CommaSeparated(Str())),
    )

    def set_up(self):
        print("visit {0}".format(self.given['url']))

    def fill_form(self, **textboxes):
        for name, text in sorted(textboxes.items()):
            print("with {0}".format(name))
            print("enter {0}".format(text))

    def drag(self, from_item, to_item):
        print(f"drag {from_item} to {to_item}")

    @validate(double=Bool())
    def click(self, item, double=False):
        if double:
            print(f"double clicked on {item}")
        else:
            print(f"clicked on {item}")
index.jinja2

{% for story in story_list %}
{{ story.documentation() }}
{% endfor %}
document.yaml

story: |
  # {{ name }}

  {{ info.jiras.documentation() }}

  {{ about }}

  {% for name, property in given.items() %}
  {{ given[name].documentation() }}
  {% endfor %}
  {% for step in steps %}
  {{ step.documentation() }}
  {% endfor %}

  ## Automatically generated

  Automatically generated from {{ filename.name }}
info:
  jiras: |
    {% for jira in jiras -%}
    * https://yourproject.jira.com/JIRAS/{{ jira }}
    {% endfor %}
given:
  url: 'Load: {{ url }}'
steps:
  fill form: |-
    {% for name, value in textboxes.items() %}
    - Enter text '{{ value }}' in {{ name }}.
    {%- endfor %}

    ![](screenshots/{{ this_story.slug }}-{{ this_step.index }}-{{ this_step.slug }}.png)
  click: |
    '* {% if double %}Double click{% else %}Click{% endif %} on {{ item }}'

    ![](screenshots/{{ this_story.slug }}-{{ this_step.index }}-{{ this_step.slug }}.png)
  drag: |
    '* Drag from {{ from_item }} to {{ to_item }}.'

    ![](screenshots/{{ this_story.slug }}-{{ this_step.index }}-{{ this_step.slug }}.png)

带代码

from hitchstory import StoryCollection
from pathlib import Path
from engine import Engine
from path import Path
import jinja2

jenv = jinja2.Environment(
    undefined=jinja2.StrictUndefined, loader=jinja2.BaseLoader
)

story_collection = StoryCollection(
    Path(".").glob("*.story"), Engine()
).non_variations()
print(
    jenv.from_string(Path("index.jinja2").read_text()).render(
        story_list=story_collection.with_documentation(
            Path("document.yaml").read_text(),
        ).ordered_by_file()
    )
)

将输出

# Login

* https://yourproject.jira.com/JIRAS/AZT-344
* https://yourproject.jira.com/JIRAS/AZT-345


Simple log in.


Load: /loginurl



- Enter text '(( username ))' in username.
- Enter text '(( password ))' in password.

![](screenshots/login-0-fill_form.png)

'* Click on login'

![](screenshots/login-1-click.png)

'* Drag from left to right.'

![](screenshots/login-2-drag.png)

'* Double click on right'

![](screenshots/login-3-click.png)


## Automatically generated

Automatically generated from example.story

# Log in on another url

* https://yourproject.jira.com/JIRAS/AZT-344
* https://yourproject.jira.com/JIRAS/AZT-589


Alternate log in URL.


Load: /alternativeloginurl



- Enter text '(( username ))' in username.
- Enter text '(( password ))' in password.

![](screenshots/log-in-on-another-url-0-fill_form.png)

'* Click on login'

![](screenshots/log-in-on-another-url-1-click.png)

'* Drag from left to right.'

![](screenshots/log-in-on-another-url-2-drag.png)

'* Double click on right'

![](screenshots/log-in-on-another-url-3-click.png)


## Automatically generated

Automatically generated from example.story

# Log in as president

* https://yourproject.jira.com/JIRAS/AZT-611


For stories that involve Trump.


Load: /loginurl



- Enter text '(( username ))' in username.
- Enter text '(( password ))' in password.

![](screenshots/log-in-as-president-0-fill_form.png)

'* Click on login'

![](screenshots/log-in-as-president-1-click.png)

'* Drag from left to right.'

![](screenshots/log-in-as-president-2-drag.png)

'* Double click on right'

![](screenshots/log-in-as-president-3-click.png)


## Automatically generated

Automatically generated from example.story