Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add progress trackers during test execution #205

Merged
merged 14 commits into from May 15, 2021
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
327 changes: 155 additions & 172 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Expand Up @@ -40,7 +40,7 @@ dataclasses = { version = "^0.7", python = "3.6" }
colorama = "^0.4.0"
click = "^7.0"
termcolor = "^1.1.0"
rich = "^9.1.0"
rich = "^10.0.0"
toml = "^0.10.1"
pygments = "^2.4.2"
pprintpp = "^0.4.0"
Expand Down
14 changes: 14 additions & 0 deletions tests/test_cli.py
@@ -0,0 +1,14 @@
from click.testing import CliRunner

from ward import each, test
from ward.run import run


@test("Cannot use bar progress style with {output_style} output style")
def _(output_style=each("dots-global", "dots-module")):
runner = CliRunner()
result = runner.invoke(
run, ["test", "--progress-style", "bar", "--test-output-style", output_style]
)

assert result.exit_code == 2
39 changes: 34 additions & 5 deletions ward/run.py
Expand Up @@ -3,7 +3,7 @@
import sys
from pathlib import Path
from timeit import default_timer
from typing import Optional, Tuple
from typing import Optional, Tuple, List

import click
import click_completion
Expand All @@ -25,7 +25,13 @@
from ward.rewrite import rewrite_assertions_in_tests
from ward.suite import Suite
from ward.fixtures import _DEFINED_FIXTURES
from ward.terminal import SimpleTestResultWrite, output_fixtures, get_exit_code
from ward.terminal import (
SimpleTestResultWrite,
output_fixtures,
get_exit_code,
TestProgressStyle,
TestOutputStyle,
)

colorama.init()
click_completion.init()
Expand Down Expand Up @@ -91,10 +97,20 @@ def run(ctx: click.Context):
)
@click.option(
"--test-output-style",
type=click.Choice(
["test-per-line", "dots-global", "dots-module"], case_sensitive=False,
),
type=click.Choice(list(TestOutputStyle), case_sensitive=False),
default="test-per-line",
help="The style of output for displaying individual test results during the run.",
)
@click.option(
"--progress-style",
type=click.Choice(list(TestProgressStyle), case_sensitive=False),
multiple=True,
default=["inline"],
help=f"""\
The style of progress indicator to use during the run.
Pass multiple times to enable multiple styles.
The '{TestProgressStyle.BAR}' style is not compatible with the '{TestOutputStyle.DOTS_GLOBAL}' and '{TestOutputStyle.DOTS_MODULE}' test output styles.
""",
)
@click.option(
"--order",
Expand Down Expand Up @@ -135,13 +151,25 @@ def test(
tags: Optional[Expression],
fail_limit: Optional[int],
test_output_style: str,
progress_style: List[str],
order: str,
capture_output: bool,
show_slowest: int,
show_diff_symbols: bool,
dry_run: bool,
):
"""Run tests."""
progress_styles = [TestProgressStyle(ps) for ps in progress_style]

if TestProgressStyle.BAR in progress_styles and test_output_style in {
"dots-global",
"dots-module",
}:
raise click.BadOptionUsage(
"progress_style",
f"The '{TestProgressStyle.BAR}' progress style cannot be used with dots-based test output styles (you asked for '{test_output_style}').",
)

init_breakpointhooks(pdb, sys)
start_run = default_timer()
paths = [Path(p) for p in path]
Expand All @@ -160,6 +188,7 @@ def test(
writer = SimpleTestResultWrite(
suite=suite,
test_output_style=test_output_style,
progress_styles=progress_styles,
config_path=config_path,
show_diff_symbols=show_diff_symbols,
)
Expand Down
6 changes: 5 additions & 1 deletion ward/suite.py
Expand Up @@ -15,9 +15,13 @@ class Suite:
cache: FixtureCache = field(default_factory=FixtureCache)

@property
def num_tests(self):
def num_tests(self) -> int:
return len(self.tests)

@property
def num_tests_with_parameterisation(self) -> int:
return sum(test.find_number_of_instances() for test in self.tests)

def _test_counts_per_module(self):
module_paths = [test.path for test in self.tests]
counts = defaultdict(int)
Expand Down