Skip to content

Commit 5fca719

Browse files
authored
Run the entire test suite using pytest (#109)
* move conftest * cleanup tests load fixtures declaratively we don't need to call_command('loaddata') by hand remove unused imports * test config * fix user model Django's ORM internally expects this to be a method, not a property https://docs.djangoproject.com/en/3.0/ref/models/instances/#get-absolute-url Making it a property causes django to throw `TypeError: 'str' object is not callable` when creating a link to a user object * run pytest in CI, remove standalone manage container - run pytest in CI - scrap the standalone manage container - run console commands against app container - update docs
1 parent 2683d9a commit 5fca719

File tree

10 files changed

+40
-59
lines changed

10 files changed

+40
-59
lines changed

.github/workflows/test.yml

+3-11
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,10 @@ jobs:
1717
- name: Run application
1818
run: docker-compose up -d web
1919

20-
- name: Test Resources
21-
run: docker-compose run --rm manage test resources
22-
if: always()
23-
24-
- name: Test Users
25-
run: docker-compose run --rm manage test users
26-
if: always()
27-
28-
- name: Test UserAuth
29-
run: docker-compose run --rm manage test userauth
20+
- name: Run test suite
21+
run: docker-compose run -T --rm app pytest -v
3022
if: always()
3123

3224
- name: Check Migrations are up-to-date
33-
run: docker-compose run --rm manage makemigrations --check
25+
run: docker-compose run -T --rm app ./manage.py makemigrations --check
3426
if: always()

README.md

+11-6
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ To stop the application and remove all containers, run the following.
5959
docker-compose down
6060
```
6161

62-
5. Create a superuser so that you can log into http://localhost:8000/admin by running the following in your terminal: `$ docker-compose run --rm manage createsuperuser`
62+
5. Create a superuser so that you can log into http://localhost:8000/admin by running the following in your terminal: `$ docker-compose run --rm app ./manage.py createsuperuser`
6363

6464
## Editing Code
6565

@@ -89,17 +89,22 @@ If you would like to tail the logs in the console then you remove the detach fla
8989

9090
The following are examples of some common Django management commands that you may need to run.
9191

92-
* Make Migrations: `docker-compose run --rm manage makemigrations`
93-
* Merge Migrations: `docker-compose run --rm manage makemigrations --merge`
94-
* Run Migrations: `docker-compose run --rm manage`
95-
* Test: `docker-compose run --rm manage test`
92+
* Make Migrations: `docker-compose run --rm app ./manage.py makemigrations`
93+
* Merge Migrations: `docker-compose run --rm app ./manage.py makemigrations --merge`
94+
* Run Migrations: `docker-compose run --rm app ./manage.py migrate`
9695

9796
To see the full list of management commands use `help`.
9897

9998
```plain
100-
docker-compose run --rm manage help
99+
docker-compose run --rm app ./manage.py help
101100
```
102101

102+
### Automated Tests
103+
104+
* We use [pytest](https://docs.pytest.org/en/latest/contents.html) with the [pytest-django](https://pytest-django.readthedocs.io/en/latest/) plugin for running tests.
105+
* Please add tests for your code when contributing.
106+
* Run the test suite using `docker-compose run --rm app pytest`
107+
103108
### Import Postman collection
104109
Postman is a free interactive tool for verifying the APIs of your project. You can download it at postman.com/downloads.
105110

docker-compose.yaml

+1-15
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ services:
3333
sh -c "python /opt/codebuddies/manage.py collectstatic --clear --no-input &&
3434
python /opt/codebuddies/manage.py migrate &&
3535
uwsgi --ini /opt/codebuddies/uwsgi.ini"
36+
working_dir: /opt/codebuddies
3637
volumes:
3738
- ./project:/opt/codebuddies
3839
environment:
@@ -76,18 +77,3 @@ services:
7677
restart: on-failure
7778
ports:
7879
- 8025:8025
79-
80-
# Manager allows you to run Django management tasks on the application.
81-
manage:
82-
container_name: manage
83-
restart: on-failure
84-
build: ./project
85-
command: shell
86-
entrypoint: /usr/local/bin/python3 /opt/codebuddies/manage.py
87-
volumes:
88-
- ./project:/opt/codebuddies
89-
environment:
90-
- DATABASE_URL=postgres://babyyoda:mysecretpassword@db:5432/codebuddies
91-
- EMAIL_HOST=mailhog
92-
depends_on:
93-
- db

project/config/settings/test.py

-7
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
"DJANGO_SECRET_KEY",
1515
default="AcnZMguCngDeMgbwXf6l9d2arow2lU9ZkDweNnoCZmZ2qH6pinB4tLhEYI4Fgf6Y",
1616
)
17-
# https://docs.djangoproject.com/en/dev/ref/settings/#test-runner
18-
TEST_RUNNER = "django.test.runner.DiscoverRunner"
1917

2018
# CACHES
2119
# ------------------------------------------------------------------------------
@@ -27,11 +25,6 @@
2725
}
2826
}
2927

30-
# PASSWORDS
31-
# ------------------------------------------------------------------------------
32-
# https://docs.djangoproject.com/en/dev/ref/settings/#password-hashers
33-
PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"]
34-
3528
# TEMPLATES
3629
# ------------------------------------------------------------------------------
3730
TEMPLATES[0]["OPTIONS"]["loaders"] = [ # noqa F405
File renamed without changes.

project/core/templates/base.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -140,19 +140,19 @@ <h2>Application urls</h2>
140140
<h2>docker-compose commands</h2>
141141
<ul>
142142
<li>
143-
<code>docker-compose run --rm manage createsuperuser</code> - Command
143+
<code>docker-compose run --rm app ./manage.py createsuperuser</code> - Command
144144
to create a superuser
145145
</li>
146146
<li>
147-
<code>docker-compose run --rm manage tests</code>- Command to run
147+
<code>docker-compose run --rm app pytest</code> - Command to run
148148
tests
149149
</li>
150150
<li>
151-
<code>docker-compose run --rm makemigrations</code> - Command to make
151+
<code>docker-compose run --rm app ./manage.py makemigrations</code> - Command to make
152152
migrations (necessary if you change the models)
153153
</li>
154154
<li>
155-
<code>docker-compose run --rm migrate</code> - Command to migrate the
155+
<code>docker-compose run --rm app ./manage.py migrate</code> - Command to migrate the
156156
migrations (necessary if you ran the previous makemigrations step)
157157
</li>
158158
</ul>

project/pytest.ini

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[pytest]
2+
python_files = tests.py test_*.py *_tests.py
3+
norecursedirs = staticfiles .git templates __pycache__
4+
DJANGO_SETTINGS_MODULE = config.settings.test
5+
FAIL_INVALID_TEMPLATE_VARS = 1

project/resources/tests.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
from rest_framework import status, serializers
1+
from rest_framework import status
22
from rest_framework.test import APITestCase
33
from rest_framework_jwt.settings import api_settings
4-
from django.core.management import call_command
54

65
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
76
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
87

98
class ResourcesTests(APITestCase):
109

11-
def setUp(self):
12-
call_command('loaddata', 'users.json', verbosity=0)
13-
call_command('loaddata', 'resources.json', verbosity=0)
14-
call_command('loaddata', 'tagging.json', verbosity=0)
15-
call_command('loaddata', 'taggeditems.json', verbosity=0)
10+
fixtures = [
11+
'users',
12+
'resources',
13+
'tagging',
14+
'taggeditems'
15+
]
1616

17+
def setUp(self):
1718
url = '/auth/obtain_token/'
1819
#to do: choose a user at random from loaded users.json
1920
data = {"username": "JuJu", "password": "codebuddies"}

project/userauth/tests.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import unittest
21
from unittest.mock import patch
32
from rest_framework import status, serializers
43
from rest_framework.test import APITestCase
54
from rest_framework_jwt.settings import api_settings
6-
from django.core.management import call_command
75
from django.contrib.auth import get_user_model
86

97

@@ -12,14 +10,16 @@
1210

1311
class UserauthTests(APITestCase):
1412

13+
fixtures = ['users']
14+
1515
def setUp(self):
16-
"""
17-
Loads users.json fixture into test DB and directly creates a new user.
18-
"""
19-
call_command('loaddata', 'users.json', verbosity=0)
16+
# create a new user
2017
model = get_user_model()
21-
self.person = model.objects.create_user(username='PetuniaPig', email='[email protected]',
22-
password='codebuddies')
18+
self.person = model.objects.create_user(
19+
username='PetuniaPig',
20+
21+
password='codebuddies'
22+
)
2323

2424

2525
def test_jwt_not_authed(self):

project/users/models.py

-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@ class User(AbstractUser):
1010
# around the globe.
1111
name = CharField(_("Name of User"), blank=True, max_length=255)
1212

13-
@property
1413
def get_absolute_url(self):
1514
return reverse("users:detail", kwargs={"username": self.username})

0 commit comments

Comments
 (0)