Giter VIP home page Giter VIP logo

individual-project-example's Introduction

Recipe Sharing

Contents

Introduction

Objective

The objective provided for this project is as follows:

To create a CRUD application with utilisation of supporting tools, methodologies and technologies that encapsulate all core modules covered during training.

More specifically, the following is required:

  • Functioning CRUD application created in Python
  • Functioning front-end to website using Flask
  • Trello board or equivalent
  • Relational database - must contain at least one one-to-many relationship
  • Clear documentation
  • Detailed risk assessment
  • Automated tests
  • Fully integrated into Github or other VCS

Proposal

I've decided to make a cooking recipes sharing site, where users are able to create a profile, and then upload recipes they have found. Other users may then view uploaded recipes, and other users' profiles.

An outline of how CRUD will be implemented can be seen below.

Create:

  • user/profile information
  • recipes
    • title
    • description
    • ingredients
    • method
    • footer

Read:

  • other profiles, including post history
  • recipes

Update:

  • profile information
  • own recipes

Delete:

  • user/profile
  • own recipes

Architecture

Risk Assessment

My detailed Risk Assessment can be seen below, outlining the major and minor risks associated with this project.

risk assessment image
The highlighted rows in the table were added at a later date after new risks became clear.
The full risk assessment can be found here.

Trello Board

The progress of my project was documented using a Trello board.

I decided to use Trello over other similar tools, such as Jira, as Trello is lightweight, free-to-use, and is focused on presenting the project in a more visual way. Since this project is small scale, Trello fits my needs perfectly.

trello board image The full board can be found at https://trello.com/b/sdSEOik1/recipe-site.

Entity Relationship Diagram

My outdated ERD can be seen below, followed by the updated version to cover the changes to my project since its original proposal.

old ERD image

ERD Image

My updated ERD can be seen to the left, mapping how my database is currently structured.

The structure to the database was changed from the original proposal due to a realisation that login validation is out of the scope of this project.

I've decided to use a many-to-many relationship with the recipe_ingredient table breaking this into two many-to-one relationships. The many-to-many is formed because each recipe should have several ingredients, but several recipes may share the same ingredients.

Having this relationship allows users to simply find ingredients in the database if they're already added. This also allows further ingredient-related features to be implemented, such as having average prices for each ingredient.


Analysis of Testing

This project only includes unit and integration testing, which are both fairly basic forms of testing. There are clearly plenty of other forms of testing that could be implemented were it in the scope of this project. Some key levels of testing that aren't utilized here include system testing, and acceptance testing. More specifically, we are not testing any of the below.

image of some out-of-scope forms of testing reference


As my project utilized a test-driven approach, I created some plans for my unit and integration tests as can be seen below. As tests were made, the spreadsheet was filled in.

image of testing analysis document The original document can be viewed here

Continuous Integration

ci pipeline diagram
Continuous integration is used in my project to allow rapid and smooth development-to-deployment, focusing on automating testing. In my approach, as code is pushed to Github, Jenkins will fetch and build the repository, and then run unit and integration tests. The developer is then able to view the reports produced and can refactor the program as required.

Jenkins Script

The build script can be broken into five stages, shown below.

1. Installation of the virtual environment

sudo apt install chromium-chromedriver -y
sudo apt-get install python3-venv

python3 -m venv venv
source venv/bin/activate

pip3 install -r requirements.txt

2. Stopping existing processes that may interfere

sudo systemctl stop recipe-project
sudo rm pytest-result

3. Unit and integration testing

python3 -m pytest tests --cov=application --cov-report term-missing --disable-warnings

4. Running as-live environment on systemd process

sudo cp -r . /opt/project

sudo systemctl daemon-reload
sudo systemctl start recipe-project

5. Checking for reported failures from earlier testing - marks the build as failed if appropriate

if [ -f pytest-result ] && [ $(cat pytest-result) == 'FAIL' ]; 
	then echo "TESTING FAILED - MARKING BUILD AS FAILED"; exit 1;
fi;

As outlined in the pipeline diagram, the testing coverage report is then available on the Jenkins console.

Development

Unit Testing

Unit testing is used here by seperating the route functions and testing each function with various scenarios. These are designed to assert each function returns an expected response under each given scenario. These tests are run automatically after every Git push using Jenkins. Jenkins prints out whether or not the tests were successsful and also gives a coverage report noting the percentage of the application that was tested.

To run the unit and integration tests for yourself, follow steps 1. and 3. of the Jenkins build script

image of unit test results and coverage
If any of the unit testing fails, the entire Jenkins build is marked as a fail, as you can see in the example below. The as-live environment is still brought online for the developer to use, however.

image of failed tests

Front-End

Home Page

When navigating to the home page (/home) or to the URL with no specified path, the user is given the list of current recipe entries. Each entry is shown as the recipe's title and the recipe's description (if applicable). Tapping on the title directs the user to view the recipe.

At the top of the page is a navigation bar (defined in a base layout template, and therefore available on every page). One of the links directs the user to the home page, and the other to a recipe creation page.

home page image

CRUD implemented on this page: READ

Recipe Creation

When the user navigates to the creation page (/create) a recipe entry is immediately created in the database. The database for the entry is then updated every time the user edits and submits a field.

Since ingredients are stored in a foreign table, they work slightly differently in the form. You can't edit them the same as you can with the title, description, and method. Instead, you can delete an ingredient from the ignredients list, and you can create an ingrededient to add to the ingredients list.

recipe creation page image

CRUD implemented on this page: all

Recipe Viewing

When the user navigates to view a recipe from the home page they are given all relevant details on the recipe.

At the bottom of this page, buttons can be used to direct to edit or delete the recipe.

recipe viewing page image

CRUD implemented on this page: READ, DELETE

Integration Testing

Integration testing is used in this project to test the functional aspects of the app as a whole. In my approach I use selenium to simulate a user navigating the site (by clicking on elements in each page) and filling in forms as the testing specifies, and then my tests also check the database for the expected data.

Much like the unit tests, these tests are also automated using Jenkins.
image of integration test results
If any of the integration testing fails, the entire Jenkins build is marked as a fail.

Footer

Future Improvements

  • As mentioned in the original proposal, a future version should contain user profiles - this would also allow locking deleting/editing recipes to the recipe author or admin users.
  • The ability to set the amount of an ingredient required for the recipe, as well as how many people that amount of ingredients would serve. The former would be added to the association (recipe_ingredient) table, and the latter to the recipe table.

Author

Oliver Nichols

Acknowledgements

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.