From e2a5c38b549655a7765472de5cbe19ba17f2c4a7 Mon Sep 17 00:00:00 2001 From: Andreas <andreasv@fsmpi.rwth-aachen.de> Date: Sat, 2 Dec 2017 21:22:37 +0100 Subject: [PATCH] added some unit tests --- .gitignore | 2 ++ README.md | 6 ++++++ db.py | 2 ++ server.py | 12 +++++++++++- tests.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100755 tests.py diff --git a/.gitignore b/.gitignore index 2886e55..299c19d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ nginx.log nginx.pid nginx.conf uwsgi.sock +.coverage +htmlcov/ diff --git a/README.md b/README.md index 5089659..b8d5b45 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,11 @@ Hinweis: diese Variante startet eine lokale Testversion der Website, es sind nic Alternativ, insbesondere zum Testen der Zugriffsbeschränkungen: Siehe `nginx.example.conf`. +### Unittests +Tests können mittels `./tests.py` ausgeführt werden. + +Coverage Tests können mittels `rm .coverage; python -m coverage run tests.py; python -m coverage html` ausgeführt werden. Dies erstellt einen Ordner `htmlcov` in dem HTML Output liegt. + ### Zum Mitmachen: 1. Repo für den eigenen User forken, dafür den "Fork-Button" auf der Website verwenden 2. Sicherstellen, dass der Upstream richtig konfiguriert ist: @@ -39,6 +44,7 @@ Optional (wird für einzelne Features benötigt): * python-ldap (Login mit Fachschaftsaccount) * python-icalendar (SoGo-Kalenderimport für Sitzungsankündigungen) * python-mysql-connector (wenn MySQL als Datenbank verwendet werden soll) +* python-coverage (Für Coverage Tests benötigt) Kurzform unter Ubuntu: `sudo apt install python3 python3-flask sqlite python3-requests python3-lxml python3-ldap3 python3-icalendar python3-mysql.connector` diff --git a/db.py b/db.py index 04f7fe8..f64e6a3 100644 --- a/db.py +++ b/db.py @@ -23,8 +23,10 @@ if config['DB_ENGINE'] == 'sqlite': db = sqlite3.connect(config['SQLITE_DB']) cur = db.cursor() if config['SQLITE_INIT_SCHEMA']: + print('Init db schema') cur.executescript(open(config['DB_SCHEMA']).read()) if config['SQLITE_INIT_DATA'] and created: + print('Init db data') cur.executescript(open(config['DB_DATA']).read()) db.commit() db.close() diff --git a/server.py b/server.py index 0d68848..b13d02c 100644 --- a/server.py +++ b/server.py @@ -25,6 +25,16 @@ if sys.argv[0].endswith('run.py'): config['SQLITE_INIT_DATA'] = True config['DEBUG'] = True config.from_pyfile('config.py', silent=True) +if sys.argv[0].endswith('tests.py'): + print('running in test mode') + import tempfile + # ensure we always use a clean sqlite db for tests + config['DB_ENGINE'] = 'sqlite' + config['SQLITE_DB'] = tempfile.mktemp(prefix='flasktestingtmp') + print('DB File: {}'.format(config['SQLITE_DB'])) + config['SQLITE_INIT_DATA'] = True + config['SQLITE_INIT_SCHEMA'] = True + config['DEBUG'] = True if config['DEBUG']: app.jinja_env.auto_reload = True @@ -338,7 +348,7 @@ def login(): user = userinfo.get('uid') if not check_mod(user, groups): flash('Login fehlgeschlagen!') - return render_template('login.html') + return make_response(render_template('login.html'), 403) session['user'] = userinfo dbuser = query('SELECT * FROM users WHERE name = ?', user) if not dbuser: diff --git a/tests.py b/tests.py new file mode 100755 index 0000000..d0a7a69 --- /dev/null +++ b/tests.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import os +import unittest +import server + +import flask + +class VideoTestCase(unittest.TestCase): + @classmethod + def setUpClass(cls): + server.app.testing = True + + @classmethod + def tearDownClass(cls): + os.unlink(server.app.config['SQLITE_DB']) + + def setUp(self): + self.app = server.app.test_client() + + def test_index(self): + r = self.app.get('/') + assert r.status_code == 200 + + def test_courses(self): + r = self.app.get('/courses') + assert r.status_code == 200 + + def test_faq(self): + r = self.app.get('/faq') + assert r.status_code == 200 + + def test_sitemap(self): + r = self.app.get('/sitemap.xml') + assert r.status_code == 200 + + def test_login(self): + # test login page + r = self.app.get('/internal/login') + assert r.status_code == 200 + # test successfull login + with self.app as c: + r = c.post('/internal/login', data={'user': 'videoag', 'password': 'videoag', 'ref': '/'}) + assert flask.session['user'] + assert r.status_code == 302 + assert '<a href="/">' in r.data.decode() + # test unsuccessfull login + with self.app as c: + r = c.post('/internal/login', data={'user': 'videoag', 'password': 'asd', 'ref': '/'}) + assert flask.session['user'] + assert r.status_code == 403 + assert 'Login fehlgeschlagen' in r.data.decode() + + +if __name__ == '__main__': + unittest.main() + -- GitLab