Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pytest upgrade 3.7.1 -> 6.2.5 #11759

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@

## Reviewer checklist

- Automated test coverage is satisfactory
- PR is fully functional
- PR has been tested for [accessibility regressions](http://kolibri-dev.readthedocs.io/en/develop/manual_testing.html#accessibility-a11y-testing)
- External dependency files were updated if necessary (`yarn` and `pip`)
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/c_extensions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ jobs:
make staticdeps-cext
pip install .
# Start and stop kolibri
coverage run -p kolibri start --port=8081
coverage run -p kolibri stop
kolibri start --port=8081
kolibri stop
# Run just tests in test/
py.test --cov=kolibri --cov-report= --cov-append --color=no test/
py.test --color=no test/
no_c_ext:
name: No C Extensions
needs: pre_job
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
make staticdeps
pip install .
# Start and stop kolibri
coverage run -p kolibri start --port=8081
coverage run -p kolibri stop
kolibri start --port=8081
kolibri stop
# Run just tests in test/
py.test --cov=kolibri --cov-report= --cov-append --color=no test/
py.test --color=no test/
1 change: 0 additions & 1 deletion docs/stack.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,4 @@ We use a number of mechanisms to help encourage code quality and consistency. Mo
- `pytest <http://pytest.org/latest/>`__ runs our Python unit tests. We also leverage the `Django test framework <https://docs.djangoproject.com/en/1.11/topics/testing/>`__.
- In addition to building client assets, `webpack <https://webpack.github.io/>`__ runs linters on client-side code: `ESLint <http://eslint.org/>`__ for ES6 JavaScript, `Stylelint <https://stylelint.io/>`__ for SCSS, and `HTMLHint <http://htmlhint.com/>`__ for HTML and Vue.js components.
- Client-side code is tested using `Jest <https://facebook.github.io/jest/>`__
- `codecov <https://codecov.io/>`__ reports on the test coverage
- We have `Sentry <https://docs.sentry.io/>`__ clients integrated (off by default) for automated error reporting
4 changes: 2 additions & 2 deletions kolibri/core/analytics/test/test_ping.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import mock
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test import TransactionTestCase
from django.test import TestCase
from requests.models import Response

from .test_utils import BaseDeviceSetupMixin
Expand Down Expand Up @@ -36,7 +36,7 @@ def json(self):
return mocked_requests_post


class PingCommandTestCase(BaseDeviceSetupMixin, TransactionTestCase):
class PingCommandTestCase(BaseDeviceSetupMixin, TestCase):
@mock.patch(
"kolibri.core.analytics.utils.requests.post",
side_effect=mocked_requests_post_wrapper({"id": 17}, 200),
Expand Down
96 changes: 49 additions & 47 deletions kolibri/core/analytics/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import random
import uuid

from django.test import TransactionTestCase
from django.test import TestCase
from le_utils.constants import content_kinds

from kolibri.core.analytics.constants.nutrition_endpoints import PINGBACK
Expand Down Expand Up @@ -57,8 +57,9 @@ class BaseDeviceSetupMixin(object):
min_timestamp = datetime.datetime(2018, 10, 11)
max_timestamp = datetime.datetime(2019, 10, 11)

def setUp(self):
super(BaseDeviceSetupMixin, self).setUp()
@classmethod
def setUpTestData(cls):
super(BaseDeviceSetupMixin, cls).setUpTestData()
clear_process_cache()
# create dummy channel
channel_id = uuid.uuid4().hex
Expand All @@ -68,8 +69,8 @@ def setUp(self):
channel_id=channel_id,
content_id=uuid.uuid4().hex,
)
self.channel = ChannelMetadata.objects.create(
id=channel_id, name="channel", last_updated=self.min_timestamp, root=root
cls.channel = ChannelMetadata.objects.create(
id=channel_id, name="channel", last_updated=cls.min_timestamp, root=root
)
lf = LocalFile.objects.create(
id=uuid.uuid4().hex, available=True, file_size=1048576 # 1 MB
Expand All @@ -81,23 +82,23 @@ def setUp(self):
with io.open(data_path, mode="r", encoding="utf-8") as f:
users = [data for data in csv.DictReader(f)]

self.facilities = user_data.get_or_create_facilities(
n_facilities=self.n_facilities
cls.facilities = user_data.get_or_create_facilities(
n_facilities=cls.n_facilities
)
self.users = []
cls.users = []

for facility in self.facilities:
for facility in cls.facilities:
dataset = facility.dataset
# create superuser and login session
for i in range(self.n_superusers):
for i in range(cls.n_superusers):
superuser = create_superuser(
facility=facility, username="superuser{}".format(i)
)
facility.add_role(superuser, role_kinds.ADMIN)
UserSessionLog.objects.create(
user=superuser,
start_timestamp=self.min_timestamp,
last_interaction_timestamp=self.max_timestamp,
start_timestamp=cls.min_timestamp,
last_interaction_timestamp=cls.max_timestamp,
)
# create lesson and exam for facility
Lesson.objects.create(
Expand All @@ -114,87 +115,87 @@ def setUp(self):
exam_id = uuid.uuid4().hex

classrooms = user_data.get_or_create_classrooms(
n_classes=self.n_classes, facility=facility
n_classes=cls.n_classes, facility=facility
)

# Get all the user data at once so that it is distinct across classrooms
facility_user_data = random.sample(users, self.n_classes * self.n_users)
facility_user_data = random.sample(users, cls.n_classes * cls.n_users)

# create random content id for the session logs
self.content_id = uuid.uuid4().hex
cls.content_id = uuid.uuid4().hex
for i, classroom in enumerate(classrooms):
classroom_user_data = facility_user_data[
i * self.n_users : (i + 1) * self.n_users
i * cls.n_users : (i + 1) * cls.n_users
]
users = user_data.get_or_create_classroom_users(
n_users=self.n_users,
n_users=cls.n_users,
classroom=classroom,
user_data=classroom_user_data,
facility=facility,
)
self.users.extend(users)
cls.users.extend(users)
# create 1 of each type of log per user
for user in users:
for _ in range(1):
sessionlog = ContentSessionLog.objects.create(
user=user,
start_timestamp=self.min_timestamp,
end_timestamp=self.max_timestamp,
content_id=self.content_id,
channel_id=self.channel.id,
start_timestamp=cls.min_timestamp,
end_timestamp=cls.max_timestamp,
content_id=cls.content_id,
channel_id=cls.channel.id,
time_spent=60, # 1 minute
kind=content_kinds.EXERCISE,
)
AttemptLog.objects.create(
item="item",
start_timestamp=self.min_timestamp,
end_timestamp=self.max_timestamp,
completion_timestamp=self.max_timestamp,
start_timestamp=cls.min_timestamp,
end_timestamp=cls.max_timestamp,
completion_timestamp=cls.max_timestamp,
correct=1,
sessionlog=sessionlog,
)
# create 1 anon log per user session log
ContentSessionLog.objects.create(
dataset=dataset,
user=None,
start_timestamp=self.min_timestamp,
end_timestamp=self.max_timestamp,
content_id=self.content_id,
channel_id=self.channel.id,
start_timestamp=cls.min_timestamp,
end_timestamp=cls.max_timestamp,
content_id=cls.content_id,
channel_id=cls.channel.id,
time_spent=60, # 1 minute,
kind=content_kinds.VIDEO,
)
for _ in range(1):
UserSessionLog.objects.create(
user=user,
start_timestamp=self.min_timestamp,
last_interaction_timestamp=self.max_timestamp,
start_timestamp=cls.min_timestamp,
last_interaction_timestamp=cls.max_timestamp,
device_info="Android,9/Chrome Mobile,86",
)
for _ in range(1):
ContentSummaryLog.objects.create(
user=user,
start_timestamp=self.min_timestamp,
end_timestamp=self.max_timestamp,
completion_timestamp=self.max_timestamp,
start_timestamp=cls.min_timestamp,
end_timestamp=cls.max_timestamp,
completion_timestamp=cls.max_timestamp,
content_id=uuid.uuid4().hex,
channel_id=self.channel.id,
channel_id=cls.channel.id,
)
for _ in range(1):
sl = ContentSessionLog.objects.create(
user=user,
start_timestamp=self.min_timestamp,
end_timestamp=self.max_timestamp,
start_timestamp=cls.min_timestamp,
end_timestamp=cls.max_timestamp,
content_id=exam_id,
channel_id=None,
time_spent=60, # 1 minute
kind=content_kinds.QUIZ,
)
summarylog = ContentSummaryLog.objects.create(
user=user,
start_timestamp=self.min_timestamp,
end_timestamp=self.max_timestamp,
completion_timestamp=self.max_timestamp,
start_timestamp=cls.min_timestamp,
end_timestamp=cls.max_timestamp,
completion_timestamp=cls.max_timestamp,
content_id=exam_id,
channel_id=None,
kind=content_kinds.QUIZ,
Expand All @@ -209,9 +210,9 @@ def setUp(self):
AttemptLog.objects.create(
masterylog=masterylog,
sessionlog=sl,
start_timestamp=self.min_timestamp,
end_timestamp=self.max_timestamp,
completion_timestamp=self.max_timestamp,
start_timestamp=cls.min_timestamp,
end_timestamp=cls.max_timestamp,
completion_timestamp=cls.max_timestamp,
correct=1,
item="test:test",
)
Expand All @@ -221,7 +222,7 @@ def tearDown(self):
DeviceSettings.objects.delete()


class FacilityStatisticsTestCase(BaseDeviceSetupMixin, TransactionTestCase):
class FacilityStatisticsTestCase(BaseDeviceSetupMixin, TestCase):
def test_extract_facility_statistics(self):
provision_device(allow_guest_access=True)
facility = self.facilities[0]
Expand Down Expand Up @@ -323,7 +324,7 @@ def test_regression_4606_no_contentsessions_or_usersessions(self):
assert actual["l"] is None


class SoudFacilityStatisticsTestCase(BaseDeviceSetupMixin, TransactionTestCase):
class SoudFacilityStatisticsTestCase(BaseDeviceSetupMixin, TestCase):
n_facilities = 1
n_superusers = 0
n_users = 2
Expand All @@ -340,7 +341,7 @@ def test_extract_facility_statistics__soud_hash(self):
self.assertEqual(expected_soud_hash, actual.pop("sh"))


class ChannelStatisticsTestCase(BaseDeviceSetupMixin, TransactionTestCase):
class ChannelStatisticsTestCase(BaseDeviceSetupMixin, TestCase):
def test_extract_channel_statistics(self):
actual = extract_channel_statistics(self.channel)
birth_year_list_learners = [
Expand Down Expand Up @@ -388,7 +389,7 @@ def test_extract_channel_statistics(self):
assert actual == expected


class CreateUpdateNotificationsTestCase(TransactionTestCase):
class CreateUpdateNotificationsTestCase(TestCase):
def setUp(self):
self.msg = {
"i18n": {},
Expand All @@ -406,6 +407,7 @@ def setUp(self):
"version_range": "<1.0.0",
"source": PINGBACK,
}

PingbackNotification.objects.create(**self.data)

def test_no_messages_still_updates(self):
Expand Down
2 changes: 2 additions & 0 deletions kolibri/core/auth/test/test_morango_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def test_partition_and_id_values(self):
self.assertTrue(partition.startswith(dataset_id))


# This needs to be a TransactionTestCase for Postgres, due to transaction
# isolation requirements - but works fine otherwise in SQLite.
class DateTimeTZFieldTestCase(TransactionTestCase):
def setUp(self):
self.controller = MorangoProfileController(PROFILE_FACILITY_DATA)
Expand Down
4 changes: 2 additions & 2 deletions kolibri/core/content/test/test_content_sync_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from kolibri.core.auth.sync_operations import KolibriSyncOperations
from kolibri.core.content.kolibri_plugin import ContentSyncHook
from kolibri.core.content.test.utils.test_content_request import (
IncompleteDownloadsQuerysetTestCase,
BaseIncompleteDownloadsQuerysetTestCase,
)
from kolibri.core.device.models import DeviceStatus


class KolibriContentSyncHookTestCase(IncompleteDownloadsQuerysetTestCase):
class KolibriContentSyncHookTestCase(BaseIncompleteDownloadsQuerysetTestCase):
def setUp(self):
super(KolibriContentSyncHookTestCase, self).setUp()
self.operation = KolibriSyncOperations()
Expand Down
8 changes: 2 additions & 6 deletions kolibri/core/content/test/test_delete_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import uuid

from django.core.management import call_command
from django.test import TestCase
from django.test import TransactionTestCase
from le_utils.constants import content_kinds
from le_utils.constants import file_formats
Expand All @@ -23,8 +24,7 @@ def get_engine(connection_string):
test_channel_id = "6199dde695db4ee4ab392222d5af1e5c"


@patch("kolibri.core.content.utils.sqlalchemybridge.get_engine", new=get_engine)
class UnavailableContentDeletion(TransactionTestCase):
class UnavailableContentDeletion(TestCase):
databases = "__all__"

def setUp(self):
Expand Down Expand Up @@ -101,10 +101,6 @@ def test_dont_delete_used_stored_files(self):
deleted = self.delete_content()
self.assertEqual(deleted, 0)

def tearDown(self):
call_command("flush", interactive=False)
super(UnavailableContentDeletion, self).tearDown()


@patch("kolibri.core.content.utils.sqlalchemybridge.get_engine", new=get_engine)
class DeleteContentTestCase(TransactionTestCase):
Expand Down
6 changes: 4 additions & 2 deletions kolibri/core/content/test/utils/test_content_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,16 +414,18 @@ def _create_resources(self, node_id, available=False):
return (parent, node)


class IncompleteDownloadsQuerysetTestCase(BaseQuerysetTestCase):
class BaseIncompleteDownloadsQuerysetTestCase(BaseQuerysetTestCase):
def setUp(self):
super(IncompleteDownloadsQuerysetTestCase, self).setUp()
super(BaseIncompleteDownloadsQuerysetTestCase, self).setUp()
self.admin_request = ContentDownloadRequest.build_for_user(self.admin)
self.admin_request.contentnode_id = uuid.uuid4().hex
self.admin_request.save()
self.learner_request = ContentDownloadRequest.build_for_user(self.learner)
self.learner_request.contentnode_id = uuid.uuid4().hex
self.learner_request.save()


class IncompleteDownloadsQuerysetTestCase(BaseIncompleteDownloadsQuerysetTestCase):
@mock.patch(_module + "get_device_setting", return_value=False)
def test_learner_downloads_disabled(self, mock_get_device_setting):
qs = incomplete_downloads_queryset()
Expand Down
2 changes: 1 addition & 1 deletion kolibri/core/deviceadmin/tests/test_dbbackup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def test_active_kolibri():
gs.assert_called_once()


@pytest.mark.django_db
@pytest.mark.django_db(transaction=True)
def test_inactive_kolibri():
"""
Tests that if kolibri is inactive, a dump is created
Expand Down
Loading
Loading