Skip to main content

HitchStory

Main branch status

Type-safe StrictYAML python integration testing framework. With this framework, your tests can:

Rewrite themselves from program output (command line test example)

Test rewriting itself

Autogenerate documentation (website test example)

Test writing docs

The tests can be run on their own or as pytest tests.

Demo projects with demo tests

Project Storytests Python code Doc template Autogenerated docs
Website add todo, correct spelling engine.py docstory.yml Add todo, Correct my spelling
REST API add todo, correct spelling engine.py docstory.yml Add todo, Correct my spelling
Interactive command line app add todo, correct spelling test_integration.py docstory.yml Add todo, Correct my spelling
A Python API add todo, correct spelling test_integration.py docstory.yml Add todo, Correct my spelling

Code Example

example.story:

Logged in:
  given:
    website: /login  # preconditions
  steps:
  - Form filled:
      username: AzureDiamond
      password: hunter2
  - Clicked: login


Email sent:
  about: |
    The most basic email with no subject, cc or bcc
    set.
  based on: logged in             # inherits from and continues from test above
  following steps:
  - Clicked: new email
  - Form filled:
      to: Cthon98@aol.com
      contents: |                # long form text
        Hey guys,

        I think I got hacked!
  - Clicked: send email
  - Email was sent

engine.py:

from hitchstory import BaseEngine, GivenDefinition, GivenProperty
from hitchstory import Failure, strings_match
from strictyaml import Str

class Engine(BaseEngine):
    given_definition = GivenDefinition(
        website=GivenProperty(Str()),
    )
    
    def __init__(self, rewrite=False):
        self._rewrite = rewrite

    def set_up(self):
        print(f"Load web page at {self.given['website']}")

    def form_filled(self, **textboxes):
        for name, contents in sorted(textboxes.items()):
            print(f"Put {contents} in name")

    def clicked(self, name):
        print(f"Click on {name}")
    
    def failing_step(self):
        raise Failure("This was not supposed to happen")
    
    def error_message_displayed(self, expected_message):
        """Demonstrates steps that can rewrite themselves."""
        actual_message = "error message!"
        try:
            strings_match(expected_message, actual_message)
        except Failure:
            if self._rewrite:
                self.current_step.rewrite("expected_message").to(actual_message)
            else:
                raise

    def email_was_sent(self):
        print("Check email was sent!")
>>> from hitchstory import StoryCollection
>>> from pathlib import Path
>>> from engine import Engine
>>> 
>>> StoryCollection(Path(".").glob("*.story"), Engine()).named("Email sent").play()
RUNNING Email sent in /path/to/working/example.story ... Load web page at /login
Put hunter2 in name
Put AzureDiamond in name
Click on login
Click on new email
Put Hey guys,

I think I got hacked!
 in name
Put Cthon98@aol.com in name
Click on send email
Check email was sent!
SUCCESS in 0.1 seconds.

Install

$ pip install hitchstory

Community

Help is available if you ask questions in these places: Github discussions | Github issues (not just for bugs) | Slack channel

Using HitchStory

Every feature of this library is documented and listed below. It is tested and documented with itself.

Using HitchStory: With Pytest

If you already have pytest set up, you can quickly and easily write a test using hitchstory that runs alongside your other pytest tests:

Using HitchStory: Engine

How to use the different features of the story engine:

Using HitchStory: Documentation Generation

How to autogenerate documentation from your tests:

Using HitchStory: Inheritance

Inheriting stories from each other:

Using HitchStory: Runner

Running the stories in different ways:

Approach to using HitchStory

Best practices, how the tool was meant to be used, etc.

Design decisions and principles

Design decisions are justified here:

Why not X instead?

HitchStory is not the only integration testing framework. This is how it compares with the others:

Using HitchStory: Setup on its own

If you want to use HitchStory without pytest:

Using HitchStory: Behavior

Miscellaneous docs about behavior of the framework:

Release files for hitchstory 0.24.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hitchstory 0.24.2
File Size Uploaded
hitchstory-0.24.2.tar.gz 34.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hitchstory 0.24.2
File Interpreter ABI Platform
hitchstory-0.24.2-py3-none-any.whl Python 3 none any Details

Total release size: 66.9 kB

Release files / hitchstory-0.24.2.tar.gz

Download URL hitchstory-0.24.2.tar.gz
Size 34.7 kB
Tags Source
SHA-256 checksum
How to use checksums
c6fc5f1c568bc2e497172c47ff1a5aad3bc8fd57733144f0a6936c94c74103a3
BLAKE2b-256 checksum
How to use checksums
df01fa4fa349653d9ad24c43d7585820ec72fd870356fe5d62659d9e63aeb4b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.15.0a1

Release files / hitchstory-0.24.2-py3-none-any.whl

Download URL hitchstory-0.24.2-py3-none-any.whl
Size 32.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b366e1ffa3ed92860e1fd8d6660e765fab0a53578f08fc0f97897b075e445703
BLAKE2b-256 checksum
How to use checksums
50df92e5e848303d9b3d7b69f78057985a4d68eb9f24007aec40a20ff3143259
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.15.0a1

Release history Release notifications | RSS feed

This release

0.24.2 This release

2 release files

0.24.0

2 release files

0.23.0

2 release files

0.19.0

2 release files

0.18.0

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.3

2 release files

0.15.2

2 release files

0.14.0

1 release file

0.13.3

1 release file

0.13.2

1 release file

0.13.1

1 release file

0.13.0

1 release file

0.12.1

1 release file

0.12.0

1 release file

0.11.3

1 release file

0.11.2

1 release file

0.11.1

1 release file

0.11.0

1 release file

0.10.3

1 release file

0.10.2

1 release file

0.10.1

1 release file

0.10.0

1 release file

0.9.1

1 release file

0.9.0

1 release file

0.8.2

1 release file

0.8.1

1 release file

0.8.0

1 release file

0.7.6

1 release file

0.7.4

1 release file

0.7.3

1 release file

0.7.2

1 release file

0.7.1

1 release file

0.7.0

1 release file

0.6.2

1 release file

0.6.1

1 release file

0.6.0

1 release file

0.5.0

1 release file

0.4.0

1 release file

0.3.1

1 release file

0.3.0

1 release file

0.2.9

1 release file

0.2.8

1 release file

0.2.7

1 release file

0.2.6

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.3

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page