Skip to content

Commit

Permalink
Merge pull request #115 from elyezer/fix-108
Browse files Browse the repository at this point in the history
Add token-prefix option
  • Loading branch information
sthirugn committed Jul 27, 2016
2 parents 316e77b + ba71f9f commit 92465ba
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 47 deletions.
23 changes: 14 additions & 9 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,14 @@ minimum-tokens

.. note::

To help test case parsing, make sure that each test case docstring has the
tokens prefixed with ``@`` and suffixed with ``:``. Otherwise, you may see
incorrect results.
To help test case parsing, make sure that each test case docstring has the
tokens in the following format ``{token_prefix}token{token_suffix}``,
where:

token_prefix
This is configurable and by default, it is ``:``.
token_suffix
This is not configurable and should always be ``:``.

Sample Test Case
++++++++++++++++
Expand All @@ -65,14 +70,14 @@ A sample python test case with test case tokens is shown below:
More description for the test.
@feature: Login
@setup: Navigate to abc.com
@steps:
:feature: Login
:setup: Navigate to abc.com
:steps:
1. Launch the url
2. Log in with valid user credentials
@assert: Log in successful
@bz: 1234567
@automated: false
:assert: Log in successful
:bz: 1234567
:automated: false
"""
In the above example, as you may guess - ``feature``, ``setup``, ``steps``,
Expand Down
5 changes: 4 additions & 1 deletion testimony/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ def __init__(self, function_def, parent_class=None, testmodule=None):
self.tokens = {}
self.invalid_tokens = {}
self.parser = DocstringParser(
SETTINGS.get('tokens'), SETTINGS.get('minimum_tokens'))
SETTINGS.get('tokens'),
SETTINGS.get('minimum_tokens'),
SETTINGS.get('token_prefix', ':'),
)
self._parse_docstring()

def _parse_docstring(self):
Expand Down
18 changes: 17 additions & 1 deletion testimony/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,36 @@
from testimony import SETTINGS, constants, main


def _validate_token_prefix(ctx, param, value):
"""Ensure single character for token prefix."""
if len(value) != 1:
raise click.BadParameter('token prefix should be a single character.')
else:
return value


@click.command()
@click.option('-j', '--json', help='JSON output', is_flag=True)
@click.option('-n', '--nocolor', default=False, help='Color output',
is_flag=True)
@click.option('--tokens', help='Comma separated list of expected tokens')
@click.option(
'--minimum-tokens', help='Comma separated list of minimum expected tokens')
@click.option(
'--token-prefix',
callback=_validate_token_prefix,
default=':',
help='Single character token prefix'
)
@click.argument('report', type=click.Choice(constants.REPORT_TAGS))
@click.argument('path', nargs=-1, type=click.Path(exists=True))
def testimony(json, nocolor, tokens, minimum_tokens, report, path):
def testimony(
json, nocolor, tokens, minimum_tokens, token_prefix, report, path):
"""Inspect and report on the Python test cases."""
if tokens:
SETTINGS['tokens'] = [token.strip() for token in tokens.split(',')]
if minimum_tokens:
SETTINGS['minimum_tokens'] = [
token.strip() for token in minimum_tokens.split(',')]
SETTINGS['token_prefix'] = token_prefix
main(report, path, json, nocolor)
10 changes: 6 additions & 4 deletions testimony/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

from testimony.constants import DEFAULT_MINIMUM_TOKENS, DEFAULT_TOKENS

TOKEN_RE = re.compile(r'^@(\w+):\s+([^@]+)(\n|$)', flags=re.MULTILINE)


class DocstringParser(object):
"""Parse docstring extracting tokens."""

def __init__(self, tokens=None, minimum_tokens=None):
def __init__(self, tokens=None, minimum_tokens=None, prefix=':'):
"""Initialize the parser with expected tokens and the minimum set."""
if tokens is None:
self.tokens = DEFAULT_TOKENS
Expand All @@ -22,6 +20,10 @@ def __init__(self, tokens=None, minimum_tokens=None):
self.minimum_tokens = minimum_tokens
self.minimum_tokens = set(self.minimum_tokens)
self.tokens = set(self.tokens)
self.token_regex = re.compile(
r'^{0}(\w+):\s+([^{0}]+)(\n|$)'.format(prefix),
flags=re.MULTILINE
)
if not self.minimum_tokens.issubset(self.tokens):
raise ValueError('tokens should contain minimum_tokens')

Expand Down Expand Up @@ -51,7 +53,7 @@ def parse(self, docstring=None):
return {}, {}
valid_tokens = {}
invalid_tokens = {}
for match in TOKEN_RE.finditer(docstring):
for match in self.token_regex.finditer(docstring):
token = match.group(1).strip().lower()
value = match.group(2).strip()
if token in self.tokens:
Expand Down
64 changes: 32 additions & 32 deletions tests/test_sample.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# -*- encoding: utf-8 -*-
"""Test class for Sample Test
@Setup: Global setup
:Setup: Global setup
"""


class Testsample1():
"""This is a dummy test file used for testing testimony
@Setup: Setup Testsample1
:Setup: Setup Testsample1
"""

# Test with incorrect doctrings:
Expand All @@ -18,21 +18,21 @@ class Testsample1():
def test_positive_login_1(self):
"""Login with right credentials
@Feture: Login - Positive
:Feture: Login - Positive
@Steps:
:Steps:
1. Login to the application with valid credentials
@Assert: Login is successful
:Assert: Login is successful
@Bug: 123456
:Bug: 123456
@Statues: Manual
:Statues: Manual
@Tags: t1, t2, t3
:Tags: t1, t2, t3
@Types: Functional
:Types: Functional
"""
# Code to perform the test
pass
Expand All @@ -46,17 +46,17 @@ def test_positive_login_2(self):
def test_positive_login_3(self):
"""Login with Latin credentials
@Setup: Setup test_positive_login_3
:Setup: Setup test_positive_login_3
@Feature: Login - Positive
:Feature: Login - Positive
@Steps:
:Steps:
1. Login to the application with valid Latin credentials
@Assert: Login is successful
:Assert: Login is successful
@Tags: t1
:Tags: t1
"""
# Code to perform the test
Expand All @@ -66,16 +66,16 @@ def test_positive_login_3(self):
def test_positive_login_4(self):
"""Login with Credentials having special characters
@Feature: Login - Positive
:Feature: Login - Positive
@Steps:
:Steps:
1. Login to the application with valid credentials having
special characters
@Assert: Activation key is created
:Assert: Activation key is created
@Status: Manual
:Status: Manual
"""
# Code to perform the test
Expand All @@ -85,15 +85,15 @@ def test_positive_login_4(self):
def test_negative_login_5(self):
"""Test missing required docstrings
@Steps:
:Steps:
1. Login to the application with invalid credentials
@BZ: 123456
:BZ: 123456
@Status: Manual
:Status: Manual
@Tags: t2
:Tags: t2
"""
# Login to the application
Expand All @@ -107,21 +107,21 @@ class Testsample2():
def test_negative_login_6(self):
"""Login with invalid credentials
@Feature: Login - Negative
:Feature: Login - Negative
@Steps:
:Steps:
1. Login to the application with invalid credentials
@Assert: Login failed
:Assert: Login failed
@BZ: 123456
:BZ: 123456
@Status: Manual
:Status: Manual
@Tags: t3
:Tags: t3
@Type: Functional
:Type: Functional
"""
# Code to perform the test
pass
Expand All @@ -135,13 +135,13 @@ class Testsample3():
def test_negative_login_7(self):
"""Login with invalid credentials
@Feature: Login - Negative
:Feature: Login - Negative
@Steps:
:Steps:
1. Login to the application with valid username and no password
@Assert: Login failed
:Assert: Login failed
"""
# Code to perform the test
Expand Down

0 comments on commit 92465ba

Please sign in to comment.