Skip to content

Commit

Permalink
Task 1.1: Automated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kolayne committed Feb 16, 2024
1 parent 1f2f872 commit f27e6cb
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 2 deletions.
2 changes: 1 addition & 1 deletion app_python/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM python:3.10.13-alpine3.19
WORKDIR /app
EXPOSE 5000
RUN ["adduser", "-Ds", "/usr/bin/nologin", "flask"]
COPY requirements.txt *.py /app/
COPY requirements.txt moscow_time/*.py /app/
# Note: keeping the project files owned by root so
# the web server has less privileges over them
USER flask:flask
Expand Down
24 changes: 24 additions & 0 deletions app_python/PYTHON.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,27 @@ deployed in a rather advanced way.
be set to one other than Moscow) or local time (as it may be
arbitrary), instead, it uses an external service as the source of
truth.

## Tests

For the project there are unit tests that cover key functionalities
of the web application. Tests ensure that:

- When index is queried, time is displayed. In particular, it is
tested that in a response a second later time advances, but no
more than by 2 seconds.

- Quering a URL other than index results in a 404 Not Found
response.

- Requests on index with method other than GET result in a
405 Method Not Allowed response.

Tests are implemented using best practices:

- A conventional project structure splitting source code and tests.

- Web app tests are implemented in accordance with suggestions from
the framework's documentation.

- Tests cover behavior on both valid and errornous input.
8 changes: 8 additions & 0 deletions app_python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,11 @@ docker run --rm -d -p 5000 kolay0ne/app_py
```

Replace `kolay0ne/app_py` with your image/tag name if you built it manually.

## Unit Tests

To run unit tests:

- Install `pytest` via `pip` or using your distribution-specific method

- Go to the project directory and run the `pytest` command
Empty file.
File renamed without changes.
2 changes: 1 addition & 1 deletion app_python/main.py → app_python/moscow_time/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from flask import Flask
import requests

from cache import cache_for
from .cache import cache_for


app = Flask(__name__)
Expand Down
Empty file added app_python/tests/__init__.py
Empty file.
47 changes: 47 additions & 0 deletions app_python/tests/test_web_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import re
from datetime import timedelta
from time import sleep

from pytest import fixture

from moscow_time.main import app


app.config.update({
"TESTING": True,
})
client = app.test_client()


def hms(hours: int, minutes: int, seconds: int) -> timedelta:
return timedelta(hours=hours, minutes=minutes, seconds=seconds)


def test_get_index():
resp1 = client.get('/')
sleep(1)
resp2 = client.get('/')

assert resp1.status_code == 200
assert resp2.status_code == 200

pattern = re.compile(br'(\d{1,2}):(\d{1,2}):(\d{1,2})')

data1 = pattern.search(resp1.data)
data2 = pattern.search(resp2.data)
assert data1, "Time is in the response"
assert data2, "Time is in the second response"

time1 = hms(*map(int, data1.groups()))
time2 = hms(*map(int, data2.groups()))

# Time difference is positive but no more than 2 seconds
assert timedelta(0) < time2 - time1 <= timedelta(seconds=2)

def test_wrong_url():
resp = client.get('/arbitrary/url')
assert resp.status_code == 404

def test_post_index():
resp = client.post('/')
assert resp.status_code == 405

0 comments on commit f27e6cb

Please sign in to comment.