Reputation: 668
I'm trying to set up a test stage in Gitlab's CI/CD. Locally, running the unit tests goes fine and as expected. In Gitlab's CI/CD, though, when running the script coverage run manage.py test -v 2 && coverage report
the unit tests are executing before the migrations are completed in the test database, which is unexpected, and will always fail. Migrations on the test database need to run prior to unit tests executing.
Any idea why this behavior might happen?
When running python manage.py test
these are the steps that happen by default:
Creation of test databases.
Database migration.
Run system checks.
Running tests.
Report on the number of tests and success / failure.
Removing test databases.
In the local test run output below, you can see those exact steps, in that sequence happening. The problem is that in Gitlab's CI/CD pipeline, step 2 and 4 are switched for some mysterious reason to me.
python manage.py test
Result: same errorMy actual output is much bigger. But here's the relevant parts:
$ echo $TEST_SECRETS | base64 -d > config/settings/local.py
$ echo RUNNING UNIT TESTS
RUNNING UNIT TESTS
$ coverage run manage.py test -v 2 && coverage report
Creating test database for alias 'default' ('test_mia')...
test_dataconnector_category_creation_delete (apps.core.tests.test_models.DataConnectorCategoryTestCase)
Verify data connector category creation ... ok
test_compare_airbytesetting (apps.services.tests.test_model_airbytesetting.AirbyteSettingModel_TestClass)
Compare object from self.airbytesetting to ensure data is in proper format. ... ok
test_fieldconstraints_airbytesetting (apps.services.tests.test_model_airbytesetting.AirbyteSettingModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytesetting (apps.services.tests.test_model_airbytesetting.AirbyteSettingModel_TestClass)
Test updating values in self.airbytesetting and saving that to the test database. ... ok
test_compare_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Compare object from self.airbytesource to ensure data is in proper format. ... ok
test_delete_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Test Deleting self.airbytesource object from database ... ok
test_fieldconstraints_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Test updating values in self.airbytesource and saving that to the test database. ... ok
test_compare_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Compare object from self.airbytestream to ensure data is in proper format. ... ok
test_delete_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Test Deleting self.airbytestream object from database ... ok
test_fieldconstraints_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Test updating values in self.airbytestream and saving that to the test database. ... ok
test_compare_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Compare object from self.airbytesynccatalog to ensure data is in proper format. ... ok
test_delete_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Test Deleting self.airbytesynccatalog object from database ... ok
test_fieldconstraints_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Test updating values in self.airbytesynccatalog and saving that to the test database. ... ok
test_compare_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Compare object from self.tableausetting to ensure data is in proper format. ... ok
test_createrandom_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Test Creating a New (Second) TableauSetting Model Object with Random Values. ... ok
test_delete_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Test Deleting self.tableausetting object from database ... ok
test_fieldconstraints_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Test updating values in self.tableausetting and saving that to the test database. ... ok
test_get_namespace_custom_format (apps.services.tests.test_scripts_airbyte.ServicesTestCase)
TO-DO: this method should live in AirByte class ... ok
test_retrieve_me_user (apps.user.tests.test_views.UserViewTest) ... ok
test_retrieve_user (apps.user.tests.test_views.UserViewTest) ... ok
apps.user.tests.test_models (unittest.loader._FailedTest) ... ERROR
======================================================================
ERROR: apps.user.tests.test_models (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: apps.user.tests.test_models
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedTable: relation "user_user" does not exist
LINE 1: INSERT INTO "user_user" ("password", "last_login", "is_super...
^
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
module = self._get_module_from_name(name)
File "/usr/local/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
__import__(name)
File "/builds/americommerce/mia/mia-ms-main/apps/user/tests/test_models.py", line 3, in <module>
from apps.user.tests.factories import UserFactory, CompanyFactory, SignUpTokenFactory
File "/builds/americommerce/mia/mia-ms-main/apps/user/tests/factories.py", line 23, in <module>
class SignUpTokenFactory(factory.django.DjangoModelFactory):
File "/builds/americommerce/mia/mia-ms-main/apps/user/tests/factories.py", line 28, in SignUpTokenFactory
user = UserFactory()
File "/usr/local/lib/python3.8/site-packages/factory/base.py", line 40, in __call__
return cls.create(**kwargs)
File "/usr/local/lib/python3.8/site-packages/factory/base.py", line 528, in create
return cls._generate(enums.CREATE_STRATEGY, kwargs)
File "/usr/local/lib/python3.8/site-packages/factory/django.py", line 117, in _generate
return super()._generate(strategy, params)
File "/usr/local/lib/python3.8/site-packages/factory/base.py", line 465, in _generate
return step.build()
File "/usr/local/lib/python3.8/site-packages/factory/builder.py", line 262, in build
instance = self.factory_meta.instantiate(
File "/usr/local/lib/python3.8/site-packages/factory/base.py", line 317, in instantiate
return self.factory._create(model, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/factory/django.py", line 166, in _create
return manager.create(*args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 447, in create
obj.save(force_insert=True, using=self.db)
File "/usr/local/lib/python3.8/site-packages/django/contrib/auth/base_user.py", line 67, in save
super().save(*args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save
self.save_base(using=using, force_insert=force_insert,
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base
updated = self._save_table(
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 895, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert
return manager._insert(
File "/usr/local/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 1254, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.8/site-packages/sentry_sdk/integrations/django/__init__.py", line 508, in execute
return real_execute(self, sql, params)
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "user_user" does not exist
LINE 1: INSERT INTO "user_user" ("password", "last_login", "is_super...
^
----------------------------------------------------------------------
Ran 25 tests in 0.648s
FAILED (errors=1)
Destroying test database for alias 'default' ('test_mia')...
Operations to perform:
Synchronize unmigrated apps: corsheaders, debug_toolbar, delete_migrations, django_filters, generic_relations, messages, mptt, rest_framework, rest_framework_jwt, rest_framework_swagger, staticfiles
Apply all migrations: admin, auth, contenttypes, core, dashboard, reports, services, sessions, store, user
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying contenttypes.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0001_initial... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying user.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying store.0001_initial... OK
Applying dashboard.0001_initial... OK
Applying core.0001_initial... OK
Applying reports.0001_initial... OK
Applying reports.0002_emailreport_store... OK
Applying reports.0003_initial... OK
Applying reports.0004_remove_emailreport_segments... OK
Applying core.0002_dataconnectorcategory... OK
Applying core.0003_auto_20220331_1610... OK
Applying core.0004_delete_segment... OK
Applying dashboard.0002_auto_20220331_1804... OK
Applying dashboard.0003_flag_tableauview_widget_widgetsection... OK
Applying reports.0005_emailreport_segments... OK
Applying services.0001_initial... OK
Applying services.0002_auto_20220325_0426... OK
Applying services.0003_auto_20220331_1610... OK
Applying sessions.0001_initial... OK
Applying store.0002_initial... OK
Applying store.0003_storefrontdataconnector... OK
Applying user.0002_auto_20220325_0426... OK
Applying user.0003_auto_20220331_1610... OK
Applying user.0004_auto_20220331_1804... OK
Applying user.0005_user_flags... OK
System check identified no issues (0 silenced).
Cleaning up project directory and file based variables
00:01
ERROR: Job failed: exit code 1
Creating test database for alias 'default' ('test_mia')...
Operations to perform:
Synchronize unmigrated apps: corsheaders, debug_toolbar, delete_migrations, django_filters, generic_relations, messages, mptt, rest_framework, rest_framework_jwt, rest_framework_swagger, staticfiles
Apply all migrations: admin, auth, contenttypes, core, dashboard, reports, services, sessions, store, user
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying contenttypes.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0001_initial... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying user.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying store.0001_initial... OK
Applying dashboard.0001_initial... OK
Applying core.0001_initial... OK
Applying reports.0001_initial... OK
Applying reports.0002_emailreport_store... OK
Applying reports.0003_initial... OK
Applying reports.0004_remove_emailreport_segments... OK
Applying core.0002_dataconnectorcategory... OK
Applying core.0003_auto_20220331_1610... OK
Applying core.0004_delete_segment... OK
Applying dashboard.0002_auto_20220331_1804... OK
Applying dashboard.0003_flag_tableauview_widget_widgetsection... OK
Applying reports.0005_emailreport_segments... OK
Applying services.0001_initial... OK
Applying services.0002_auto_20220325_0426... OK
Applying services.0003_auto_20220331_1610... OK
Applying sessions.0001_initial... OK
Applying store.0002_initial... OK
Applying store.0003_storefrontdataconnector... OK
Applying user.0002_auto_20220325_0426... OK
Applying user.0003_auto_20220331_1610... OK
Applying user.0004_auto_20220331_1804... OK
Applying user.0005_user_flags... OK
System check identified no issues (0 silenced).
test_dataconnector_category_creation_delete (apps.core.tests.test_models.DataConnectorCategoryTestCase)
Verify data connector category creation ... ok
test_compare_airbytesetting (apps.services.tests.test_model_airbytesetting.AirbyteSettingModel_TestClass)
Compare object from self.airbytesetting to ensure data is in proper format. ... ok
test_fieldconstraints_airbytesetting (apps.services.tests.test_model_airbytesetting.AirbyteSettingModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytesetting (apps.services.tests.test_model_airbytesetting.AirbyteSettingModel_TestClass)
Test updating values in self.airbytesetting and saving that to the test database. ... ok
test_compare_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Compare object from self.airbytesource to ensure data is in proper format. ... ok
test_delete_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Test Deleting self.airbytesource object from database ... ok
test_fieldconstraints_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytesource (apps.services.tests.test_model_airbytesource.AirbyteSourceModel_TestClass)
Test updating values in self.airbytesource and saving that to the test database. ... ok
test_compare_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Compare object from self.airbytestream to ensure data is in proper format. ... ok
test_delete_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Test Deleting self.airbytestream object from database ... ok
test_fieldconstraints_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytestream (apps.services.tests.test_model_airbytestream.AirbyteStreamModel_TestClass)
Test updating values in self.airbytestream and saving that to the test database. ... ok
test_compare_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Compare object from self.airbytesynccatalog to ensure data is in proper format. ... ok
test_delete_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Test Deleting self.airbytesynccatalog object from database ... ok
test_fieldconstraints_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_airbytesynccatalog (apps.services.tests.test_model_airbytesynccatalog.AirbyteSyncCatalogModel_TestClass)
Test updating values in self.airbytesynccatalog and saving that to the test database. ... ok
test_compare_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Compare object from self.tableausetting to ensure data is in proper format. ... ok
test_createrandom_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Test Creating a New (Second) TableauSetting Model Object with Random Values. ... ok
test_delete_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Test Deleting self.tableausetting object from database ... ok
test_fieldconstraints_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Compares Field Constraint Values for Accuracy ... ok
test_update_tableausetting (apps.services.tests.test_model_tableausetting.TableauSettingModel_TestClass)
Test updating values in self.tableausetting and saving that to the test database. ... ok
test_get_namespace_custom_format (apps.services.tests.test_scripts_airbyte.ServicesTestCase)
TO-DO: this method should live in AirByte class ... ok
test_company_creation (apps.user.tests.test_models.UserTestCase)
Verify Company creation ... ok
test_signup_token_creation (apps.user.tests.test_models.UserTestCase)
Verify token creation ... ok
test_user_creation (apps.user.tests.test_models.UserTestCase)
Verify User creation ... ok
test_user_creation_with_company (apps.user.tests.test_models.UserTestCase)
Verify User can be assigned company ... ok
test_user_creation_with_signup_token (apps.user.tests.test_models.UserTestCase)
Verify User can be assigned token ... ok
test_retrieve_me_user (apps.user.tests.test_views.UserViewTest) ... ok
test_retrieve_user (apps.user.tests.test_views.UserViewTest) ... ok
----------------------------------------------------------------------
Ran 29 tests in 0.521s
OK
Destroying test database for alias 'default' ('test_mia')...
Name Stmts Miss Cover
---------------------------------------------------------------------
apps/core/admin.py 5 0 100%
apps/core/exceptions.py 22 3 86%
apps/core/mixins.py 10 3 70%
apps/core/models.py 8 1 88%
apps/core/serializers.py 18 0 100%
apps/core/urls.py 5 0 100%
apps/core/utils.py 69 33 52%
apps/core/views.py 42 26 38%
apps/dashboard/admin.py 15 0 100%
apps/dashboard/models.py 34 7 79%
apps/dashboard/urls.py 6 0 100%
apps/dashboard/views.py 27 16 41%
apps/delete_migrations/admin.py 1 0 100%
apps/delete_migrations/models.py 1 0 100%
apps/reports/admin.py 14 0 100%
apps/reports/mixins.py 16 9 44%
apps/reports/models/alert.py 47 3 94%
apps/reports/models/email_report.py 31 1 97%
apps/reports/serializers/alert.py 49 14 71%
apps/reports/serializers/email_report.py 49 22 55%
apps/reports/tasks.py 71 43 39%
apps/reports/urls.py 9 0 100%
apps/reports/utils.py 12 9 25%
apps/reports/views/alerts.py 40 23 42%
apps/reports/views/reports.py 55 26 53%
apps/services/admin.py 23 6 74%
apps/services/models/airbyte.py 37 0 100%
apps/services/models/tableau.py 9 0 100%
apps/services/scripts/airbyte.py 157 126 20%
apps/services/scripts/tableau.py 69 50 28%
apps/services/urls.py 3 0 100%
apps/services/views.py 15 8 47%
apps/store/admin.py 41 0 100%
apps/store/mixins.py 12 7 42%
apps/store/models/amazon_ads.py 18 2 89%
apps/store/models/amazon_seller_partner.py 21 2 90%
apps/store/models/data_connector_base.py 28 5 82%
apps/store/models/data_connector_settings.py 18 3 83%
apps/store/models/facebook.py 17 2 88%
apps/store/models/google_ads.py 20 2 90%
apps/store/models/google_analytics.py 18 2 89%
apps/store/models/google_search_console.py 18 2 89%
apps/store/models/hubspot.py 14 2 86%
apps/store/models/klaviyo.py 12 1 92%
apps/store/models/mailchimp.py 14 2 86%
apps/store/models/shopify.py 17 2 88%
apps/store/models/store.py 13 3 77%
apps/store/models/storefront.py 19 8 58%
apps/store/serializers/amazon_ads.py 22 11 50%
apps/store/serializers/amazon_seller_partner.py 26 14 46%
apps/store/serializers/base.py 8 0 100%
apps/store/serializers/credentials.py 3 0 100%
apps/store/serializers/facebook.py 15 7 53%
apps/store/serializers/google_ads.py 23 12 48%
apps/store/serializers/google_analytics.py 22 11 50%
apps/store/serializers/google_search_console.py 22 11 50%
apps/store/serializers/hubspot.py 6 0 100%
apps/store/serializers/klaviyo.py 6 0 100%
apps/store/serializers/list_data_connectors.py 24 0 100%
apps/store/serializers/mailchimp.py 6 0 100%
apps/store/serializers/shopify.py 21 10 52%
apps/store/serializers/store.py 30 3 90%
apps/store/serializers/storefront.py 6 0 100%
apps/store/tasks.py 104 80 23%
apps/store/urls.py 26 0 100%
apps/store/utils.py 89 66 26%
apps/store/views/check_data_connector_store.py 21 13 38%
apps/store/views/credentials.py 13 3 77%
apps/store/views/delete_data_connector.py 19 10 47%
apps/store/views/detail_data_connectors.py 42 0 100%
apps/store/views/list_data_connectors.py 50 32 36%
apps/store/views/reset_data_connector.py 18 9 50%
apps/store/views/store.py 15 8 47%
apps/store/views/sync_data_connector.py 18 9 50%
apps/user/admin.py 29 7 76%
apps/user/apps.py 5 0 100%
apps/user/forms.py 14 1 93%
apps/user/models.py 72 13 82%
apps/user/serializers.py 88 31 65%
apps/user/signals.py 11 4 64%
apps/user/tasks.py 15 6 60%
apps/user/urls.py 7 0 100%
apps/user/utils.py 4 0 100%
apps/user/validators.py 7 2 71%
apps/user/views.py 61 26 57%
manage.py 13 6 54%
---------------------------------------------------------------------
TOTAL 2250 879 61%
My actual file is much bigger. But here's the relevant parts:
services:
- docker:20.10.7-dind
- postgres:latest
stages:
- test
variables:
POSTGRES_DB: test_mia
POSTGRES_USER: mia_dev
POSTGRES_PASSWORD: test123
build_test_db:
image: postgres
script:
- export PGPASSWORD=$POSTGRES_PASSWORD
- psql -h "postgres" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT 'OK' AS status;"
test:
image: python:3.8-slim-buster
stage: test
before_script:
- |
apt-get update && apt-get install -y --no-install-recommends \
gcc \
musl-dev \
python3-dev \
libpq-dev \
libgnutls28-dev \
git \
&& rm -rf /var/lib/apt/lists/*
- python -m pip install --upgrade pip
- pip install uwsgi
- pip install -r requirements.txt
- echo $TEST_SECRETS | base64 -d > config/settings/local.py
script:
- echo RUNNING UNIT TESTS
- coverage run manage.py test -v 2 && coverage report
needs:
- ["build_test_db"]
environment: test
# only:
# - develop
Upvotes: 5
Views: 5130
Reputation: 2355
Add a python manage.py migrate
line before coverage run manage.py test ...
in the scripts section of your gitlab-ci.yml
.
Upvotes: 3