Skip to content

Add docs for Jupyter NB test suite #653

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

Merged
merged 3 commits into from
Jan 6, 2017
Merged
Show file tree
Hide file tree
Changes from 2 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
106 changes: 106 additions & 0 deletions plotly/tests/test_optional/test_jupyter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# plotly.py Jupyter Notebook JS test suite

To make sure that plotly.py works properly inside Jupyter Notebooks in both
`plotly.plotly` and `plotly.offline`, we here run JavaScript tests in a browser.

See PR [#545](https://github.com/plotly/plotly.py/pull/545) for example of what
can go wrong in Jupyter Notebooks.


## Running the tests

Install JavaScript dependencies:

```bash
(plotly.py/plotly/tests/test_optional/test_jupyter) $ npm install
```

Run the tests:

```bash
(plotly.py/plotly/tests/test_optional/test_jupyter) $ nosetests

# or from the repo root
(plotly.py) $ nosetests plotly/tests/test_optional/test_jupyter
```

## Add a test case

- Open up `jupyter notebook`.

- Add a few code cells testing what you wish to test. No need to execute them!

- Save the resulting `.ipynb` file in `fixtures/` (e.g. `my_test.ipynb`)

- Add a JavaScript test file in `js_tests/` by first requiring the in-house
[`tape`](https://github.com/substack/tape) test wrapper found in `lib/tape-wrapper.js`.

For example,

```js
var test = require('../lib/tape-wrapper');

test('should have one plotly.js graph', function(t) {
t.plan(1);

var nodes = document.querySelectorAll('.js-plotly-plot');
t.equal(nodes.length, 1);
});
```

asserts that one plotly graph is present in the notebook.

At the moment, it is highly recommended that the js test file has the same name
(minus the extension) as the `.ipynb` fixture (i.e. `my_test.js` in this
example).

- Add a test case in `test_jupyter.py`. If both the fixture and js test file
have the same name, simply add:

```py
class MyTest(Common):
__test__ = True
name = 'my_test'
```

to `test_jupyter.py` and you're done :beers:


## How does this work?

The `Common` test class in `test_jupyter.py`:

- Loads up a given `ipynb` fixture

- Executes all code cells and converts it to HTML using the
[`nbconvert`](https://nbconvert.readthedocs.io/en/latest/) and
[`ipykernel`](http://ipython.readthedocs.io/en/stable/install/kernel_install.html)
modules.

- Saves the resulting HTML file is saved in `fixtures/` but is git-ignored.

Then, `Common` runs an `npm` command in the shell:

```bash
npm test -- <path-to-html-fixture> <path-to-js-test-file>
```

which runs a minimal server using `lib/server.js`.

In details, `lib/server.js`:

- bundles up the js test code into a single bundle using
[`browserify`](https://github.com/substack/node-browserify)

- stubs in a `<script>` tag to include the js test bundle in the fixture HTML

- starts a simple http server

- launches Chrome at the HTML fixture URL

- once the page is loaded, the js tests are run and results are logged in the
terminal


See PR [#540](https://github.com/plotly/plotly.py/pull/549) for the details on
how this suite was first implemented.
7 changes: 7 additions & 0 deletions plotly/tests/test_optional/test_jupyter/test_jupyter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@
import subprocess

PATH_ROOT = path.dirname(__file__)
PATH_NODE_MODULES = path.join(PATH_ROOT, 'node_modules')
PATH_FIXTURES = path.join(PATH_ROOT, 'fixtures')
PATH_JS_TESTS = path.join(PATH_ROOT, 'js_tests')


class PlotlyJupyterTestDeps(TestCase):

def test_node_modules(self):
self.assertTrue(path.isdir(PATH_NODE_MODULES))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@theengineear this test will fail when someone forgets to npm install before running these tests. It should make debugging a little easier.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, nice! yah, that's a simple first-pass catch for sure.



class Common(TestCase):
__test__ = False
name = None
Expand Down