Skip to content

dave-shawley/readit

Repository files navigation

Read It!

This started out life as a simple web app that solved a problem that I have been experiencing. I need a good way to keep track of the stuff on the web that I have read. The solution is obvious - write a web app in Python, host it on Heroku, keep the data in MongoDB, and use some authentication scheme that is based on a whitelist of allowed users.

Technology Stack

Functionality Component(s)
Web Application flask
Test Environment unittest, mock
Persistence pymongo
Authentication Flask-OpenID
Packaging setuptools, pip

Development Tasks

This section describes some of the common development tasks and the tools that are used to accomplish them.

Initial Environment

  1. Pull source code from repository.

  2. Setup a virtual environment using virtualenv:

    readit$ virtualenv --no-site-packages --quiet env
    readit$ source env/bin/activate
    (env) readit$
    
  3. Use pip to install the packages listed in requirements.txt as well as those in dev-requirements.txt:

    (env) readit$ pip install -r requirements.txt
    ... lots of output
    (env) readit$ pip install -r dev-requirements.txt
    ... lots more output
    
  4. Run the tests to make sure everything is set up correctly:

    (env) readit$ nosetests
    

Minimal Test Environment

You can run tests without installing py.test or nose though I would highly recommend installing the latter. You do need to install mock since the unit tests themselves depend on it. Once you have mock installed, you can run the unit tests using the unittest module directly:

(env) readit$ python -m unittest tests
.....................................................................
-------------------------------------------------------------------------
Ran 92 tests in 0.200s

OK
(env) readit$

Realistic Unit Testing

A more realistic development environment, and the one that I use personally, includes installing the nose and coverage packages and running nosetests religiously. This will ensure that additional code is at least executed during the test process. The tests should not take more than a few seconds to execute and you get a warm and fuzzy feeling when the "Missing" column is still empty at the end of the day:

(env) readit$ nosetests
....................................................................
Name                  Stmts   Miss  Cover   Missing
---------------------------------------------------
readit                    7      0   100%
readit.flaskapp         141      0   100%
readit.helpers           42      0   100%
readit.json_support      54      0   100%
readit.mongo             54      0   100%
readit.reading           45      0   100%
readit.user              46      0   100%
---------------------------------------------------
TOTAL                   389      0   100%
----------------------------------------------------------------------
Ran 100 tests in 3.787s

OK

Astute readers may have noticed that the number of tests executed between the minimalistic environment and nosetests differs. This is expected. Nose also executes the any defined doctest blocks.

Javascript Unit Testing

In addition to Python code, the application contains a bit of Javascript and HTML that implements the browser-based interface. Just like Python code, Javascript requires testing or it feels shoddy to me. After quite a bit of playing around, I have settled on using the QUnit framework developed by the same folk that brought us jQuery. I load both of them dynamically from the appropriate CDNs so testing is easy. Simply open /javascript/test.html in a web browser. This will run a bunch of Unit Tests and present a nice test report in your browser. It should show a nice green bar that means success.

The next step is to run a coverage tool on the Javascript code. That took a little more work but the JSCover tool was surprisingly easy to integrate into the chain. It requires that you have Java installed. If you do, then you can run the following command:

(env) readit$ java -jar tools/JSCover-all.jar -ws --port=9001 \
    --document-root=javascript --report-dir=reports \
    --no-instrument=test --no-instrument=ext

Then point a web browser at https://localhost:9001/jscoverage.html?test.html and you should be shown the QUnit page as a frame in the JSCover UI. The Summary tab will show you the breakdown of unit test coverage per Javascript file. The coverage report is saved off in the reports child of the project root.

todo:one day soon I will take the time to write a setup.py extension that automates this!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published