Skip to content
This repository was archived by the owner on Mar 27, 2023. It is now read-only.

Commit 1a32b43

Browse files
committed
Merge branch 'feature-cypress-gitlab-ci-no-compose' into 'develop'
Feature cypress gitlab ci no compose See merge request verbose-equals-true/django-postgres-vue-gitlab-ecs!5
2 parents 1d1397d + c677c74 commit 1a32b43

File tree

20 files changed

+287
-113
lines changed

20 files changed

+287
-113
lines changed

.gitlab-ci.yml

Lines changed: 29 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Build Documentation:
8181
-f nginx/ci/Dockerfile .
8282
- docker push $CI_REGISTRY_IMAGE/frontend:latest
8383

84-
.Build backend:
84+
Build backend:
8585
stage: build
8686
image: docker:stable
8787
variables:
@@ -90,7 +90,6 @@ Build Documentation:
9090
services:
9191
- docker:dind
9292
before_script:
93-
- cd backend
9493
- |
9594
docker login \
9695
-u $CI_REGISTRY_USER \
@@ -100,76 +99,49 @@ Build Documentation:
10099
- |
101100
docker build \
102101
-t $CI_REGISTRY_IMAGE/backend:latest \
103-
-f scripts/prod/Dockerfile .
102+
-f backend/scripts/prod/Dockerfile .
104103
- docker push $CI_REGISTRY_IMAGE/backend:latest
105104
after_script:
106105
- echo "Build backend complete"
107106

108-
.e2e cypress tests with docker-compose:
107+
# gitlab-runner exec docker "e2e cypress tests without docker-compose"
108+
e2e: &cypress
109109
stage: integration
110-
image: docker:stable
111-
variables:
112-
DOCKER_HOST: tcp://docker:2375
113-
DOCKER_DRIVER: overlay2
110+
image: $CI_REGISTRY_IMAGE/backend:latest
114111
services:
115-
- docker:dind
116-
before_script:
117-
- apk add --update py-pip
118-
- pip install docker-compose~=1.23.0
119-
script:
120-
- ls
121-
- pwd
122-
- sh integration-tests.sh
123-
after_script:
124-
- echo "Integration tests passed."
125-
artifacts:
126-
paths:
127-
- cypress/videos/
128-
- tests/screenshots/
129-
expire_in: 7 days
130-
131-
.e2e: &e2e
132-
image: cypress/base:8
133-
stage: integration
112+
- postgres:latest
113+
- redis:latest
134114
variables:
135-
# variables passed as env vars to *all services*
136115
SECRET_KEY: 'secret'
137-
DEBUG: ''
138-
DJANGO_SETTINGS_MODULE: 'backend.settings.gitlab-ci'
139-
CELERY_TASK_ALWAYS_EAGER: 'True'
140-
services:
141-
- name: postgres
142-
- name: $CI_REGISTRY_IMAGE/backend:latest
143-
alias: backend
144-
command: ["/start_ci.sh"]
145-
- name: redis
146-
- name: $CI_REGISTRY_IMAGE/frontend:latest
147-
alias: frontend
116+
DEBUG: 'True'
117+
DJANGO_EMAIL_HOST: 'mail'
118+
DJANGO_EMAIL_PORT: '1025'
119+
DJANGO_SETTINGS_MODULE: backend.settings.gitlab-ci
120+
GITHUB_KEY: 'github123'
121+
GITHUB_SECRET: 'github123'
122+
GOOGLE_OAUTH2_KEY: 'google123'
123+
GOOGLE_OAUTH2_SECRET: 'google123'
148124
before_script:
149-
- npm install --save-dev cypress
150-
- $(npm bin)/cypress verify
125+
- python backend/manage.py migrate
126+
- python backend/manage.py create_default_user
127+
- cp /static/index.html backend/templates/
128+
- /start_asgi.sh &
151129
script:
152-
- $(npm bin)/cypress run --config baseUrl=http://frontend
153-
after_script:
154-
- echo "Cypress tests complete"
130+
- npm install cypress
131+
- cp cypress.json backend/
132+
- cp -r cypress/ backend/cypress
133+
- cd backend
134+
- $(npm bin)/cypress run
155135
artifacts:
156136
paths:
157-
- cypress/videos/
158-
- cypress/screenshots/
137+
- backend/cypress/videos/
138+
- backend/cypress/screenshots/
159139
expire_in: 7 days
160140

161-
# for testing/debugging with gitlab-runner locally
141+
# use this test with gitlab-runner locally
162142
.e2e-local:
163-
<<: *e2e
164-
services:
165-
- name: postgres
166-
- name: localhost:5000/backend:latest
167-
alias: backend
168-
command: ["/start_ci.sh"]
169-
- name: redis
170-
- name: localhost:5000/frontend:latest
171-
alias: frontend
172-
artifacts: {}
143+
<<: *cypress
144+
image: localhost:5000/backend:latest
173145

174146
Build Quasar PWA Assets:
175147
image: node:8

README.md

Lines changed: 97 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,45 +56,129 @@ or use this single command:
5656
docker exec -it backend bash -c 'cd notebooks && ../manage.py shell_plus --notebook'
5757
```
5858

59-
# Current Issues
59+
# Running tests
6060

61-
Currently Cypress tests are passing locally, but some of the test are failing in GitLab CI.
61+
This project uses Pytest, Jest and Cypress for testing. This section describes the different ways to run tests locally.
6262

63-
To run Cypress locally you can either run Cypress directly on your computer against the containerized application (for active development), or you can run Cypress in a container against the containerized application (this should be the same environment in GitLab CI using docker-compose with dind).
63+
To run Pytest and Jest, you can use `docker-compose exec`, or you can shell into the container.
6464

65-
To setup Cypress locally, run:
65+
Using `docker-compose exec`:
6666

6767
```
68-
npm install cypress --save
68+
docker-compose exec backend pytest
69+
```
70+
71+
```
72+
docker exec -it backend bash
73+
root@b24c4206002e:/code# pytest
74+
```
75+
76+
To run Jest tests, you can run:
77+
78+
```
79+
docker-compose exec frontend npm run test
80+
```
81+
82+
## Integration tests
83+
84+
Cypress can be used in an interactive mode with a UI, or it can be used in a headless way (such as in GitLab CI).
85+
86+
## Running Cypress Interactively
87+
88+
To run Cypress tests interactively, install Cypress in the root of the project:
89+
90+
```
91+
npm install cypress
6992
```
7093

7194
Then open Cypress with:
7295

7396
```
74-
$(npm bin)/cypress open
97+
$(npm bin)/cypress open --config baseUrl=http://localhost
98+
```
99+
100+
Click on the button "Run all specs", and the tests will start running in a new browser window with a log of Cypress actions and test statements displayed on the left side.
101+
102+
## Run Cypress in headless mode
103+
104+
There are two ways to run Cypress in headless mode. You can run Cypress against the `docker-compose` file in `compose/test.yml`, or you can run the Cypress test using `gitlab-runner`.
105+
106+
### Using `compose/test.yml`
107+
108+
To run the test locally against the production image, run the following:
109+
110+
```
111+
docker-compose -f compose/test.yml up --build
112+
```
113+
114+
This will build a special environment that resembles the environment used in GitLab CI. It brings up three containers: redis, postgres and backend. The backend serves several purposes: it runs the Django webserver, it runs the ASGI server used by Django Channels, and it runs celery tasks synchronously, and it also serves the Vue application through Django templates and static files. See the Dockerfile located at `backend/scripts/prod/Dockerfile` for details on how this works.
115+
116+
Make sure that Cypress is properly installed with:
117+
118+
```
119+
$(npm bin)/cypress verify
120+
```
121+
122+
Then start the tests with:
123+
124+
```
125+
$(npm bin)/cypress run --config baseUrl=http://localhost:9000
126+
```
127+
128+
You could also run these tests in the interactive mode using `compose/test.yml` with the following command:
129+
130+
```
131+
$(npm bin)/cypress open --config baseUrl=http://localhost:9000
132+
```
133+
134+
Note that this is similar to the previous command, but we are using the `open` command instead of the `run` command.
135+
136+
### Using `gitlab-runner`
137+
138+
It can be useful to debug your `.gitlab-ci.yml` jobs before pushing changes to GitLab. This gives us a faster feedback loop, and it doesn't use any of the CI minutes on your free (2000 minutes/month) or paid GitLab plans.
139+
140+
There is a little bit of setup needed to run Cypress tests with `gitlab-runner`.
141+
142+
First, you need to install `gitlab-runner` on your machine.
143+
144+
Next, you need to start a local registry on you r computer. Run the following command ([taken from docker documentation](https://docs.docker.com/registry/deploying/)):
145+
146+
```
147+
docker run -d -p 5000:5000 --restart=always --name registry registry:2
75148
```
76149

77-
Run cypress tests locally by running the following commands. First build the application stack and cypress container:
150+
Next, you need to build the production image that you will use in the test. To do this, run the following command:
78151

79152
```
80-
docker-compose -f docker-compose.ci.yml -f cypress.yml build
153+
docker-compose -f compose/test.yml build backend
81154
```
82155

83-
Then start the application:
156+
Then tag the image with the following command:
84157

85158
```
86-
docker-compose -f docker-compose.ci.yml up -d
159+
docker tag compose_backend:latest localhost:5000/backend:latest
87160
```
88161

89-
Then run cypress tests:
162+
Then push the tagged image to the local registry:
90163

91164
```
92-
docker-compose -f docker-compose.ci.yml -f cypress.yml up
165+
docker push localhost:5000/backend:latest
93166
```
94167

168+
Now that we have pushed the production image to our local registry, we can run the `e2e-local` job with `gitlab-runner`.
169+
170+
To do this, we need to make sure that the `e2e-local` job defined in `.gitlab-ci.yml` is not commented. To do this, remove the `.` in front of the job name (change `.e2e-local` to `e2e-local`).
171+
172+
Then, commit your changes in git. Gitlab runner requires that you commit changes before running tests. Run the GitLab CI job with the following command:
173+
174+
```
175+
gitlab-runner exec docker e2e-local
176+
```
177+
178+
Before you push your changes to GitLab, make sure that you uncomment the `e2e-local` job by adding `.` in front of it (`.e2e-local`).
179+
95180
# ToDo
96181

97-
- Fix Cypress testing in GitLab CI
98182
- Add diagram of local development
99183
- Put django apps in apps folder
100184
- Redeploy django app to check settings files

backend/accounts/tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_create_user(self):
2626
pass
2727
with self.assertRaises(TypeError):
2828
User.objects.create_user()
29-
with self.assertRaises(TypeError):
29+
with self.assertRaises(ValueError):
3030
User.objects.create_user(email='')
3131
with self.assertRaises(ValueError):
3232
User.objects.create_user(email='', password="foo")

backend/backend/settings/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
TEMPLATES = [
117117
{
118118
'BACKEND': 'django.template.backends.django.DjangoTemplates',
119-
'DIRS': [],
119+
'DIRS': [os.path.join(BASE_DIR, 'templates')],
120120
'APP_DIRS': True,
121121
'OPTIONS': {
122122
'context_processors': [

backend/backend/settings/gitlab-ci.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,21 @@
1919
},
2020
}
2121

22-
STATIC_URL = '/static/'
22+
MIDDLEWARE = [
23+
'corsheaders.middleware.CorsMiddleware',
24+
'django.middleware.security.SecurityMiddleware',
25+
'django.contrib.sessions.middleware.SessionMiddleware',
26+
'social_django.middleware.SocialAuthExceptionMiddleware',
27+
'django.middleware.common.CommonMiddleware',
28+
# disabled to simplify testing
29+
# 'django.middleware.csrf.CsrfViewMiddleware',
30+
'django.contrib.auth.middleware.AuthenticationMiddleware',
31+
'django.contrib.messages.middleware.MessageMiddleware',
32+
'django.middleware.clickjacking.XFrameOptionsMiddleware',
33+
'core.middleware.SubdomainMiddleware',
34+
]
35+
36+
37+
STATIC_URL = '/'
2338

2439
STATIC_ROOT = '/static/'

backend/backend/urls.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
1515
"""
1616
from django.conf import settings
17+
from django.conf.urls.static import static
1718
from django.contrib import admin
18-
from django.urls import include, path
19+
from django.urls import include, path, re_path
20+
21+
from core.views import index_view
1922

2023
urlpatterns = [
21-
path('', include('core.urls',)),
2224
path('admin/', admin.site.urls),
2325
path('api/', include('accounts.urls')),
2426
path('api/', include('core.urls'))
@@ -27,6 +29,10 @@
2729

2830
if settings.DEBUG:
2931
import debug_toolbar # noqa
30-
urlpatterns = [
32+
urlpatterns = urlpatterns + [
33+
path('', index_view, name='index'),
3134
path('admin/__debug__/', include(debug_toolbar.urls)),
32-
] + urlpatterns
35+
# catch all rule so that we can navigate to
36+
# routes in vue app other than "/"
37+
re_path(r'^(?!js)(?!css)(?!statics)(?!fonts)(?!service\-worker\.js)(?!manifest\.json)(?!precache).*', index_view, name='index') # noqa
38+
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

backend/core/views.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
from core.tasks import debug_task, send_test_email_task
88

9+
10+
from django.views.generic import TemplateView
11+
from django.views.decorators.cache import never_cache
12+
13+
# Serve Vue Application via template for GitLab CI
14+
index_view = never_cache(TemplateView.as_view(template_name='index.html'))
15+
916
r = settings.REDIS
1017

1118

backend/scripts/dev/start_asgi.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@
1212
# sleep 2
1313
# done
1414

15+
# cd backend
16+
17+
if $CI_PIPELINE_TRIGGERED ; then cd backend ; fi
1518

1619
daphne backend.asgi:application --bind 0.0.0.0 --port 9000

backend/scripts/dev/start_ci.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
python3 manage.py collectstatic --no-input
3+
# python3 manage.py collectstatic --no-input
44
python3 manage.py makemigrations
55
python3 manage.py migrate --no-input
66
python3 manage.py create_default_user

0 commit comments

Comments
 (0)