This repository is a lab from the NYU DevOps and Agile Methodologies graduate course CSCI-GA.2820-001 on Behavior Driven Development with Flask and Behave
The sample code is using Flask microframework and is intented to test the Python support on IBM Cloud environment which is based on Cloud Foundry. It also uses CouchDB as a database for storing JSON objects.
There is a sibling repository that uses PostgreSQL which is the original lab-flask-bdd project that uses the same model as the lab-flask-tdd project for continuity.
One of my favorite quotes is:
“If it's worth building, it's worth testing. If it's not worth testing, why are you wasting your time working on it?”
As Software Engineers we need to have the discipline to ensure that our code works as expected and continues to do so regardless of any changes, refactoring, or the introduction of new functionality.
This lab introduces Test Driven Development using PyUnit and nose. It also explores the use of using RSpec syntax with Python through the introduction of noseOfYeti and expects as plug-ins that make test cases more readable.
It also introduces Behavior Driven Development using Behave as a way to define Acceptance Tests that customer can understand and developers can execute!
For easy setup, you need to have Vagrant and VirtualBox installed. Then all you have to do is clone this repo and invoke vagrant:
git clone https://github.com/nyu-devops/lab-flask-bdd.git
cd lab-flask-bdd
vagrant upThis will bring up the development vertual machine (VM). Next we will ssh into the VM and peerform a one time setup task of copoying the dot-env-example file to a special file called .env which will contain the environment variables foor our 12-factor application:
vagrant ssh
cd /vagrant
cp dot-env-examplee .envYou only bee to do the copy once. This will establish the following environment variables:
PORT=8080
FLASK_APP=service:app
WAIT_SECONDS=60
CLOUDANT_USERNAME=admin
CLOUDANT_PASSWORD=passThis repository has both unit tests and integration tests. You can now run nosetests and behave to run the TDD and BDD tests respectively.
This repo also has unit tests that you can run nose
nosetestsNose is configured to automatically include the flags --with-spec --spec-color so that red-green-refactor is meaningful. If you are in a command shell that supports colors, passing tests will be green while failing tests will be red.
These tests require the service to be running becasue unlike the the TDD unit tests that test the code locally, these BDD intagration tests are using Selenium to manipulate a web page on a running server.
Run the tests using behave
honcho start &
behaveNote that the & runs the server in the background. To stop the server, you must bring it to the foreground and then press Ctrl+C
Stop the server with
fg
<Ctrl+C>Alternately you can run the server in another shell by opening another terminal window and using vagrant ssh to establish a second connection to the VM. You can also suppress all log output in the current shell with this command:
honcho start 2>&1 > /dev/null &or you can supress info logging with this command:
gunicorn --bind 0.0.0.0 --log-level=error service:app &This will suppress the normal INFO logging
* ./service/routes.py -- the main Service using Python Flask
* ./service/models.py -- the data models for persistence
* ./service/eroor_handlers.py -- these error handlers send back json
* ./tests/test_routes.py -- unit test cases for the server
* ./tests/test_models.py -- unit test cases for the model
* ./features/pets.feature -- Behave feature file
* ./features/steps/web_steps.py -- Behave step definitions
If you want to deploy this example in a Docker container, you can run the tests from the container.
This service requires CouchDB so first start a CouchDB Docker container
docker run -d --name couchdb -p 5984:5984 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=pass couchdbDocker Note:
CouchDB uses /opt/couchdb/data to store its data, and is exposed as a volume
e.g., to use current folder add: -v $(pwd):/opt/couchdb/data
You can also use Docker volumes like this: -v couchdb:/opt/couchdb/data
Next build this repo as a container
docker build -t flask-bdd .This will build a Docker image with the name flask-bdd
To run nosetests just run it in a container while linking it to the couchdb container that we have running by adding --link couchdb and CLOUDANT_HOST=couchdb like this.
docker run --rm --link couchdb -e CLOUDANT_HOST=couchdb flask-bdd nosetestsThe --link couchdb inserts the IP address of the counchdb container into the /etc/hosts file and then defining the environment variable CLOUDANT_HOST=couchdb tells our models.py file to use that as the name of the database server.
To run behave tests we need an instance of our service running so it takes two docker commands, one to run our service and another to run the behave tests
docker run -d --name flask-service --link couchdb -p 8080:8080 -e CLOUDANT_HOST=couchdb flask-bdd
docker run --rm --link flask-service -e BASE_URL="http://flask-service:8080/" flask-bdd behaveNotice how we injected the URL of the running service into our container that is running the behave tests using an environment variable BASE_URL in keeping with 12-factor pratice "III. Config:
Store config in the environment" which recommends the passing of configuraition parameters as environment variables.
When you are finished exploring this lab, you can bring down these services using:
docker stop flask-bdd
docker stop couchdb...and to remove them with:
docker rm flask-bdd
docker rm couchdbThis repository is part of the NYU graduate class CSCI-GA.2810-001: DevOps and Agile Methodologies taught by John Rofrano, Adjunct Instructor, NYU Curant Institute, Graduate Division, Computer Science.