Skip to content

Commit

Permalink
Improve documentation in README
Browse files Browse the repository at this point in the history
  • Loading branch information
dmytrostriletskyi committed Sep 11, 2024
1 parent 203deca commit 975c9e9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .project-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.6
0.0.7
100 changes: 83 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
RSpec-inspired BDD-like syntax sugar to force software engineers writing descriptive test cases and express explicit intentions.
Next-gen `Arrange-Act-Assert` to structure test cases and force software engineers to express explicit intentions in
`BDD` style.

[![](https://github.com/dmytrostriletskyi/intentions/actions/workflows/main.yaml/badge.svg?branch=main)](https://github.com/dmytrostriletskyi/intentions/actions/workflows/main.yaml)
[![](https://img.shields.io/github/release/dmytrostriletskyi/intentions.svg)](https://github.com/dmytrostriletskyi/intentions/releases)
Expand All @@ -14,37 +15,102 @@ Table of content:

* [Introduction](#introduction)
* [Motivation](#motivation)
* [Clarity and readability](#clarity-and-readability)
* [Mental Load](#mental-load)
* [Maintenance](#maintenance)
* [Encourages BDD](#encourages-bdd)
* [Collaboration](#collaboration)
* [Getting Started](#getting-started)
* [How to Install](#how-to-install)
* [Usage](#Usage)

## Introduction

`intentions` is a `Python` library providing syntax sugar to force software engineers writing descriptive test cases,
express explicit intentions and facilitate test-driven and behavior-driven development.
`intentions` is a `Python` next-gen `Arrange-Act-Assert` library created to help structuring test cases and force
software engineers to express explicit intentions in `BDD` style.

Behavior-driven development is an approach in software development that emphasizes the behavior of an application for
business needs. Each feature is describe in with the following structure: initial context or setup (data, factories),
event or action (function execution, API call), expected outcome or result.
`Arrange-Act-Assert` is a pattern used to structure test cases. It provides a clear way to organize test code, making
it easier to read and understand:

Unlike many other testing libraries, `intentions` is not a test runner and not even a plugin. It is just a set of
constructs that helps defining a structure of any test on any framework and runner.
* `Arrange` block sets up the necessary objects, data, or state before the action to be tested.
* `Act` block performs the actual operation or method call that software engineer want to test.
* `Assert` block checks the results of the action comparing the actual outcome with the expected outcome.

## Motivation
`Behavior-Driven Development` is an approach in testing that emphasizes the behavior of an application for business
needs. It focuses on defining test cases in plain, simple language with use cases and user stories. It typically uses
the `Given-When-Then` format to specify the system's expected behavior in various situations:

Using `intentions`, it benefits you by:
* `Given` a context.
* `When` an action happens.
* `Then` an expected outcome.

* Making collaboration between developers, testers, and business stakeholders easier.
* Double-checking descriptions match wordings of variables and function names.
* Introducing a common language for communication and understanding.
* Enabling the behavior-driven development mindset to colleges.
* Additional focus on the expected behavior or outcomes.
* Minimizing the learning curve for new joiners.
* Reducing uncertainties.
`intentions` aims to combine those two approaches to empower software engineers for more effective testing with `when`,
`case`, and `expect` context managers using which they can build behavior-driven arrange-act-assert based test cases.

In the same time you are not required to use it everywhere, even in the single test you are able to define which
constructs to use and how many of them. For instance, you can skip it for unit tests and only use for integration tests.

```python
class TestAccountService:

def test_transfer_money_with_insufficient_balance(self):
mock_send_in_app_notification = mock('notifications.send')

receiver_account = AccountFactory()

with when('Sender account has insufficient balance'):
sender_account = AccountFactory(balance=0)

with when('Pushing in-app notifications feature flag is enabled for sender account'):
enable_in_app_notifications(account=sender_account)

with case('Transfer money from one account to another'):
AccountService.transfer_money(from=sender_account, to=receiver_account, amount=100)

with expect('No transfers have been made'):
assert not sender_account.transfers
assert not receiver_account.transfers

with expect('Increase credit limit proposal is created'):
assert Proposal.get_last(account=sender_account, type=ProposalType.INCREASE_CREDIT_LIMIT)

with expect('Sender account receives insufficient balance in-app notification'):
mock_send_in_app_notification.assert_called_with(
account_id=sender_account.id,
type=InAppNotificationType.INSUFFICIENT_BALANCE,
expired_at=None,
)
```

## Motivation

### Clarity and readability

`when`, `case` and `expect` clearly convey the purpose of each block. With them, it is easy to tell a story of what is
being tested, making it easier for someone reading the test to understand the intention behind each part. Instead of
limited `# Arrange`, `# Act` and `# Assert` comments in your test case, you can use as much the context managers as
possible emphasizing on every important detail of the test case.

### Mental Load

With `when`, `case` and `expect`, test cases are broken down clearly, reducing mental load.

### Maintenance

If the test fails, the `when`, `case` and `expect` make it easier to understand why the test was written in the first
place due to its descriptive nature. As the test case evolves, it's easier to maintain because the purpose of each step
is clear.

### Encourages BDD

It aligns with `Behavior-Driven Development` principles, as it focuses on describing the behavior of the system under a
test case, making the tests more focused on outcomes and behavior rather than implementation details.

### Collaboration

With `when`, `case` and `expect`, you introduce a common language for communication between developers, testers, and
business stakeholders and make collaboration easier. It also helps to minimize the learning curve for new joiners.

## Getting Started

### How to install
Expand Down
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
setup,
)

DESCRIPTION = 'Next-gen Arrange-Act-Assert to structure test cases and force software engineers to ' \
'express explicit intentions in BDD style.'

with open('README.md', 'r', encoding='utf-8') as read_me:
long_description = read_me.read()

Expand All @@ -15,7 +18,7 @@
setup(
version=project_version,
name='intentions',
description='RSpec-inspired BDD-like syntax sugar to force more descriptive test cases and explicit intentions.',
description=DESCRIPTION,
long_description=long_description,
long_description_content_type='text/markdown',
url='https://github.com/dmytrostriletskyi/intentions',
Expand Down

0 comments on commit 975c9e9

Please sign in to comment.