From 739238feb7420ff45ef615e266e1f6f0184a91b3 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Mon, 7 Oct 2019 18:17:31 -0700 Subject: [PATCH] use pytest (#297) * use pytest --- .coveragerc | 9 +++++ .travis.yml | 3 ++ MANIFEST.in | 1 + noxfile.py | 24 ++++++++++++- setup.py | 1 + tests/test_app.py | 81 ------------------------------------------- tests/test_backend.py | 37 ++++++++++++++++++++ tests/test_main.py | 22 ++++++++++++ 8 files changed, 96 insertions(+), 82 deletions(-) create mode 100644 .coveragerc delete mode 100755 tests/test_app.py create mode 100755 tests/test_backend.py create mode 100755 tests/test_main.py diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..386202b --- /dev/null +++ b/.coveragerc @@ -0,0 +1,9 @@ +[report] +exclude_lines = + pragma: no cover + def __repr__ + if self.debug: + if settings.DEBUG + raise AssertionError + raise NotImplementedError + if __name__ == .__main__.: diff --git a/.travis.yml b/.travis.yml index 7610801..f41a55d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,9 @@ matrix: - python: '3.7' env: NOXSESSION="docs" dist: xenial + - python: '3.8-dev' + env: NOXSESSION="tests-3.8" + dist: xenial install: # commands for linux diff --git a/MANIFEST.in b/MANIFEST.in index 9ff5ec6..5e140dc 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -13,6 +13,7 @@ prune gdbgui/__pycache__ exclude mypy.ini exclude .eslintrc.json +exclude .coveragerc exclude .flake8 exclude .prettierrc.js exclude jest.config.js diff --git a/noxfile.py b/noxfile.py index 602f690..7490b1c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -13,11 +13,33 @@ lint_dependencies = ["black", "flake8", "mypy", "check-manifest"] @nox.session(python=python) def tests(session): session.install(".") - session.run("python", "-m", "unittest", "discover") + tests = session.posargs or ["tests"] + session.install(".", "pytest", "pytest-cov") + tests = session.posargs or ["tests"] + session.run( + "pytest", "--cov=gdbgui", "--cov-config", ".coveragerc", "--cov-report=", *tests + ) + session.run("yarn", "install", external=True) session.run("yarn", "test", external=True) session.run("yarn", "build", external=True) + session.notify("cover") + + +@nox.session +def cover(session): + """Coverage analysis""" + session.install("coverage") + session.run( + "coverage", + "report", + "--show-missing", + "--omit=gdbgui/SSLify.py", + "--fail-under=30", + ) + session.run("coverage", "erase") + @nox.session(python="3.7") def lint(session): diff --git a/setup.py b/setup.py index 8d52215..3a602a6 100644 --- a/setup.py +++ b/setup.py @@ -68,6 +68,7 @@ setup( "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", ], python_requires=">=3.6", project_urls={ diff --git a/tests/test_app.py b/tests/test_app.py deleted file mode 100755 index dd81b67..0000000 --- a/tests/test_app.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -Unit tests - -Run from top level directory: ./tests/test_app.py - -See more on testing Flask apps: http://flask.pocoo.org/docs/0.11/testing/ -""" - -import unittest -from gdbgui import backend -import sys -from flask_socketio import send, SocketIO # type: ignore - - -PYTHON3 = sys.version_info.major == 3 - -backend.setup_backend(testing=True) -socketio = backend.socketio - - -class TestWebsockets(unittest.TestCase): - @classmethod - def setUp(self): - pass - - def tearDown(self): - pass - - def test_connect(self): - app = backend.app - socketio = SocketIO() - - @socketio.on("connect") - def on_connect(): - send({"connected": "foo"}, json=True) - - socketio.init_app(app, cookie="foo") - client = socketio.test_client(app) - received = client.get_received() - self.assertEqual(len(received), 1) - self.assertEqual(received[0]["args"], {"connected": "foo"}) - - -class Test(unittest.TestCase): - def setUp(self): - """Built-in to unittest.TestCase""" - self.app = backend.app.test_client() - - def tearDown(self): - """Built-in to unittest.TestCase""" - pass - - def test_load_main_page(self): - response = self.app.get("/") - assert response.status_code == 200 - data = response.data.decode() if PYTHON3 else response.data - assert "" in data - - -class TestSocketError(unittest.TestCase): - def test_same_port(self): - backend.setup_backend(testing=True) - - -def main(): - loader = unittest.TestLoader() - suite = unittest.TestSuite() - - # commented out for now, seems to be a flask_socketio issue - # https://github.com/miguelgrinberg/Flask-SocketIO/issues/405 - suite.addTests(loader.loadTestsFromTestCase(TestWebsockets)) - suite.addTests(loader.loadTestsFromTestCase(Test)) - suite.addTests(loader.loadTestsFromTestCase(TestSocketError)) - - runner = unittest.TextTestRunner(verbosity=1) - result = runner.run(suite) - return len(result.errors) + len(result.failures) - - -if __name__ == "__main__": - main() diff --git a/tests/test_backend.py b/tests/test_backend.py new file mode 100755 index 0000000..c442fd5 --- /dev/null +++ b/tests/test_backend.py @@ -0,0 +1,37 @@ +from gdbgui import backend +from flask_socketio import send, SocketIO # type: ignore +import pytest # type: ignore + + +backend.setup_backend(testing=True) +socketio = backend.socketio + + +def test_connect(): + app = backend.app + socketio = SocketIO() + + @socketio.on("connect") + def on_connect(): + send({"connected": "foo"}, json=True) + + socketio.init_app(app, cookie="foo") + client = socketio.test_client(app) + received = client.get_received() + assert len(received) == 1 + assert received[0]["args"] == {"connected": "foo"} + + +@pytest.fixture +def test_client(): + return backend.app.test_client() + + +def test_load_main_page(test_client): + response = test_client.get("/") + assert response.status_code == 200 + assert "" in response.data.decode() + + +def test_same_port(): + backend.setup_backend(testing=True) diff --git a/tests/test_main.py b/tests/test_main.py new file mode 100755 index 0000000..cb91cb0 --- /dev/null +++ b/tests/test_main.py @@ -0,0 +1,22 @@ +import gdbgui +import pytest # type: ignore +import sys + + +@pytest.mark.parametrize( + "test_argv, init_bin_args, gdb_args", + [ + (["gdbgui"], [], []), + (["gdbgui", "--gdb-args", "mybin -myargs"], [], ["mybin", "-myargs"]), + (["gdbgui", "--args", "mybin", "-myargs"], ["mybin", "-myargs"], []), + ], +) +def test_argument_parsing(monkeypatch, test_argv, init_bin_args, gdb_args): + def mock_setup_backend(*args, **kwargs): + pass + + monkeypatch.setattr(gdbgui.backend, "setup_backend", mock_setup_backend) + monkeypatch.setattr(sys, "argv", test_argv) + gdbgui.backend.main() + assert gdbgui.backend.app.config.get("initial_binary_and_args") == init_bin_args + assert gdbgui.backend.app.config.get("gdb_args") == gdb_args