Skip to content

Added option --html to convert failed notebooks to html. #22

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ TEST RESULT
```
Usage:
treon
treon [PATH] [--threads=<number>] [-v] [--exclude=<string>]...
treon [PATH] [--threads=<number>] [--html] [-v] [--exclude=<string>]...

Arguments:
PATH File or directory path to find notebooks to test. Searches recursively for directory paths. [default: current working directory]
Expand All @@ -73,6 +73,7 @@ Options:
absolute path starts with the specified string are excluded from testing. This option can be
specified more than once to exclude multiple files or directories. If the exclude path is
a valid directory name, only this directory is excluded.
--html Write executed notebook to html
-v --verbose Print detailed output for debugging.
-h --help Show this screen.
--version Show version.
Expand Down
5 changes: 3 additions & 2 deletions treon/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ def _is_verbose():


class Task:
def __init__(self, file_path):
def __init__(self, file_path, html):
self.file_path = file_path
self.is_successful = False
self.html = html

def run_tests(self):
LOG.info("Triggered test for %s", self.file_path)

try:
self.is_successful, console_output = execute_notebook(self.file_path)
self.is_successful, console_output = execute_notebook(self.file_path, self.html)
result = self.result_string()

if not self.is_successful or _is_verbose():
Expand Down
22 changes: 19 additions & 3 deletions treon/test_execution.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
import logging
import os
import textwrap
import nbformat

from nbformat.v4 import new_code_cell
from nbconvert.preprocessors import ExecutePreprocessor
from nbconvert.preprocessors import ExecutePreprocessor, CellExecutionError

LOG = logging.getLogger('treon')

def execute_notebook(path):
def execute_notebook(path, html):
notebook = nbformat.read(path, as_version=4)
notebook.cells.extend([unittest_cell(), doctest_cell()])
processor = ExecutePreprocessor(timeout=-1, kernel_name='python3')
processor.preprocess(notebook, metadata(path))
try:
processor.preprocess(notebook, metadata(path))
except CellExecutionError:
if html:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like html will only be generated if there's execution error. If there's an HTML flag then I'm guessing user is expecting HTML output even if the notebook executed successfully.

# Write executed notebook to html
from nbconvert import HTMLExporter
html_exporter = HTMLExporter()
html_exporter.template_name = 'classic'
(body, resources) = html_exporter.from_notebook_node(notebook)
html_file_path = path + '.html'
with open(html_file_path, 'w', encoding='utf-8') as html_file:
LOG.info("Writing executed notebook to " + html_file_path)
html_file.write(body)
raise

return parse_test_result(notebook.cells)


Expand Down
7 changes: 4 additions & 3 deletions treon/treon.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""
Usage:
treon
treon [PATH] [--threads=<number>] [-v] [--exclude=<string>]...
treon [PATH] [--threads=<number>] [--html] [-v] [--exclude=<string>]...

Arguments:
PATH File or directory path to find notebooks to test. Searches recursively for directory paths. [default: current working directory]
Expand All @@ -13,6 +13,7 @@
absolute path starts with the specified string are excluded from testing. This option can be
specified more than once to exclude multiple files or directories. If the exclude path is
a valid directory name, only this directory is excluded.
--html Write executed notebook to html
-v --verbose Print detailed output for debugging.
-h --help Show this screen.
--version Show version.
Expand Down Expand Up @@ -46,8 +47,9 @@ def main():
setup_logging(arguments)
LOG.info('Executing treon version %s', __version__)
thread_count = arguments['--threads'] or DEFAULT_THREAD_COUNT
html_output = arguments['--html'] or False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe convert to bool i.e. bool(arguments['--html']) so that we're sure it's a boolean.

Let's use is_html as the variable name to indicate it's a boolean.

notebooks = get_notebooks_to_test(arguments)
tasks = [Task(notebook) for notebook in notebooks]
tasks = [Task(notebook, html_output) for notebook in notebooks]
print_test_collection(notebooks)
trigger_tasks(tasks, thread_count)
has_failed = print_test_result(tasks)
Expand All @@ -65,7 +67,6 @@ def loglevel(arguments):
verbose = arguments['--verbose']
return logging.DEBUG if verbose else logging.INFO


def trigger_tasks(tasks, thread_count):
pool = ThreadPool(int(thread_count))
pool.map(Task.run_tests, tasks)
Expand Down