Skip to content

Commit

Permalink
test suite: basic online interface test & caching
Browse files Browse the repository at this point in the history
Logging in and fetching raw HTML data from Filmweb is crucial,
therefore it needs to be tested first. We isolate this test in
a separate case class, and additionally cache its results (i.e.
fetched pages) so that more detailed tests (parsing etc.) don't
need the user to log in every time.
  • Loading branch information
Noiredd committed Jan 28, 2020
1 parent dd4d728 commit 33dbf75
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 0 deletions.
27 changes: 27 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Filmatyk - test suite

### API tests
[`test.api`](test_api.py) performs tests of the `FilmwebAPI` class
([`filmweb.py`](../filmatyk/filmweb.py)) - fetching and parsing content from Filmweb.

Testing the whole program would typically require logging in to Filmweb.pl,
which might get cumbersome after a while.
Therefore, tests are split into two convenient parts: online and offline.
The basic online interface test is tested first, during which data is fetched
and cached locally.
This allows the more detailed tests to run without the need for online connection,
instead these cached files are used as data source.

#### Basic online test: `TestAPIBasics`

Test class `TestAPIBasics` encapsulates tests of the most fundamental functionalities:
* logging in to Filmweb.pl,
* fetching raw HTML data.

However, the most important one is the `fetch_save` test, which not only grabs online data,
but also **stores it locally** (in `test/assets`), to simplify performing other tests.
Since this activity prompts for a Filmweb.pl **log-in**, it is disabled by default.
However, it is **required** to execute this test at least once -
otherwise other tests will error out.
To do this:
`cd test && python test_api.py all`
100 changes: 100 additions & 0 deletions test/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import functools
import getpass
import os
import sys
import unittest

from bs4 import BeautifulSoup as BS

sys.path.append(os.path.join('..', 'filmatyk'))
import containers
import filmweb

class TestAPIBasics(unittest.TestCase):
"""Test basic API funcionality: login & fetching raw HTML data from Filmweb.
This test is skipped by default, as it requires obtaining a session (and that
requires logging in, which would become rather tedious when experimenting).
It however produces assets later used by other tests, therefore it is crucial
that it be run before any other tests at least once.
"""
noTests = True

@classmethod
def setUpClass(self):
self.api = None
self.assets_path = 'assets'

@classmethod
def storeAPI(self, api):
self.api = api

def setUp(self):
"""Ensure the tests are skipped if the flag is set."""
if self.noTests:
self.skipTest(reason='Basics tests skipped by default!')

@staticmethod
def login_callback(username, password, *args, **kwargs):
"""Fake callback for FilmwebAPI, to pass instead of a GUI login handler.
"username" and "password" must be supplied prior to passing to FilmwebAPI
by functools.partial (or similar).
"""
isOK, session = filmweb.FilmwebAPI.login(username, password)
if not isOK:
session = None
return (session, username)

def test_01_login(self):
"""Attempt to log in to Filmweb. Requires credentials."""
username = input('Username: ').strip()
password = getpass.getpass().strip()
login_callback = functools.partial(
self.login_callback,
password=password,
)
api = filmweb.FilmwebAPI(login_callback, username)
self.assertIsNotNone(api)
api.checkSession()
self.assertIsNotNone(api.session)
self.storeAPI(api)

def test_02_fetch_one(self):
"""Attempt to download a single page of movie ratings from Filmweb."""
self.assertIsNotNone(self.api)
self.assertIsNotNone(self.api.session)
url = self.api.Constants.getUserMoviePage(
self.api.username,
page=1,
)
page = self.api._FilmwebAPI__fetchPage(url)
text = page.prettify()
self.assertIsInstance(text, str)
self.assertGreater(len(text), 100 * 2 ** 10)

def test_03_fetch_save(self):
"""Attempt to download 3 pages of movie ratings from Filmweb.
This also stores them as "assets" for other tests.
"""
N_PAGES = 3
for i in range(N_PAGES):
url = self.api.Constants.getUserMoviePage(self.api.username, page=i+1)
page = self.api._FilmwebAPI__fetchPage(url)
path = os.path.join('assets', 'movies_{}.html'.format(i+1))
with open(path, 'w', encoding='utf-8') as html:
text = page.prettify()
self.assertGreater(len(text), 100 * 2 ** 10)
html.write(text)
for i in range(N_PAGES):
self.assertIn('movies_{}.html'.format(i+1), os.listdir('assets'))


if __name__ == "__main__":
try:
TestAPIBasics.noTests = (sys.argv[1] != 'all')
del sys.argv[1]
except IndexError:
pass
unittest.main()

0 comments on commit 33dbf75

Please sign in to comment.