Skip to content

Commit f27e6cb

Browse files
committed
Task 1.1: Automated tests
1 parent 1f2f872 commit f27e6cb

File tree

8 files changed

+81
-2
lines changed

8 files changed

+81
-2
lines changed

app_python/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ FROM python:3.10.13-alpine3.19
33
WORKDIR /app
44
EXPOSE 5000
55
RUN ["adduser", "-Ds", "/usr/bin/nologin", "flask"]
6-
COPY requirements.txt *.py /app/
6+
COPY requirements.txt moscow_time/*.py /app/
77
# Note: keeping the project files owned by root so
88
# the web server has less privileges over them
99
USER flask:flask

app_python/PYTHON.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,27 @@ deployed in a rather advanced way.
2424
be set to one other than Moscow) or local time (as it may be
2525
arbitrary), instead, it uses an external service as the source of
2626
truth.
27+
28+
## Tests
29+
30+
For the project there are unit tests that cover key functionalities
31+
of the web application. Tests ensure that:
32+
33+
- When index is queried, time is displayed. In particular, it is
34+
tested that in a response a second later time advances, but no
35+
more than by 2 seconds.
36+
37+
- Quering a URL other than index results in a 404 Not Found
38+
response.
39+
40+
- Requests on index with method other than GET result in a
41+
405 Method Not Allowed response.
42+
43+
Tests are implemented using best practices:
44+
45+
- A conventional project structure splitting source code and tests.
46+
47+
- Web app tests are implemented in accordance with suggestions from
48+
the framework's documentation.
49+
50+
- Tests cover behavior on both valid and errornous input.

app_python/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,11 @@ docker run --rm -d -p 5000 kolay0ne/app_py
5151
```
5252

5353
Replace `kolay0ne/app_py` with your image/tag name if you built it manually.
54+
55+
## Unit Tests
56+
57+
To run unit tests:
58+
59+
- Install `pytest` via `pip` or using your distribution-specific method
60+
61+
- Go to the project directory and run the `pytest` command

app_python/moscow_time/__init__.py

Whitespace-only changes.
File renamed without changes.

app_python/main.py renamed to app_python/moscow_time/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from flask import Flask
44
import requests
55

6-
from cache import cache_for
6+
from .cache import cache_for
77

88

99
app = Flask(__name__)

app_python/tests/__init__.py

Whitespace-only changes.

app_python/tests/test_web_app.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import re
2+
from datetime import timedelta
3+
from time import sleep
4+
5+
from pytest import fixture
6+
7+
from moscow_time.main import app
8+
9+
10+
app.config.update({
11+
"TESTING": True,
12+
})
13+
client = app.test_client()
14+
15+
16+
def hms(hours: int, minutes: int, seconds: int) -> timedelta:
17+
return timedelta(hours=hours, minutes=minutes, seconds=seconds)
18+
19+
20+
def test_get_index():
21+
resp1 = client.get('/')
22+
sleep(1)
23+
resp2 = client.get('/')
24+
25+
assert resp1.status_code == 200
26+
assert resp2.status_code == 200
27+
28+
pattern = re.compile(br'(\d{1,2}):(\d{1,2}):(\d{1,2})')
29+
30+
data1 = pattern.search(resp1.data)
31+
data2 = pattern.search(resp2.data)
32+
assert data1, "Time is in the response"
33+
assert data2, "Time is in the second response"
34+
35+
time1 = hms(*map(int, data1.groups()))
36+
time2 = hms(*map(int, data2.groups()))
37+
38+
# Time difference is positive but no more than 2 seconds
39+
assert timedelta(0) < time2 - time1 <= timedelta(seconds=2)
40+
41+
def test_wrong_url():
42+
resp = client.get('/arbitrary/url')
43+
assert resp.status_code == 404
44+
45+
def test_post_index():
46+
resp = client.post('/')
47+
assert resp.status_code == 405

0 commit comments

Comments
 (0)