Skip to content

Commit

Permalink
Merge pull request #1372 from matthewhegarty/test-coverage-update
Browse files Browse the repository at this point in the history
improve test coverage (#1372)
  • Loading branch information
matthewhegarty committed Dec 29, 2021
2 parents 520624a + 0bbdba8 commit 5b3b250
Show file tree
Hide file tree
Showing 23 changed files with 324 additions and 314 deletions.
114 changes: 41 additions & 73 deletions .github/workflows/django-import-export-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,112 +7,80 @@ on:
pull_request:
branches:
- main
# this is a temporary addition - can be removed after 3.0 release
- release-3-x

jobs:
test:
runs-on: ubuntu-latest
env:
USERNAME: testuser
PASSWD: ${{ secrets.TEST_PASSWD }}
DB_NAME: import_export
IMPORT_EXPORT_POSTGRESQL_USER: postgres
IMPORT_EXPORT_POSTGRESQL_PASSWORD: somepass
IMPORT_EXPORT_MYSQL_USER: root
IMPORT_EXPORT_MYSQL_PASSWORD: root
strategy:
max-parallel: 4
matrix:
db: [ sqlite, postgres, mysql ]
python-version: [ 3.7, 3.8, 3.9, "3.10" ]
django-version: [ 3.2, 4.0, main ]
include:
- db: postgres
db_port: 5432
- db: mysql
db_port: 3306
exclude:
- django-version: main
python-version: 3.7
- django-version: 4.0
python-version: 3.7
- django-version: 3.2
python-version: "3.10"
python-version:
- '3.7'
- '3.8'
- '3.9'
- '3.10'
services:
mysql:
image: mysql:8.0
env:
IMPORT_EXPORT_TEST_TYPE: mysql-innodb
IMPORT_EXPORT_MYSQL_USER: ${{ env.TESTUSER }}
IMPORT_EXPORT_MYSQL_PASSWORD: ${{ env.PASSWD }}
MYSQL_USER: ${{ env.TESTUSER }}
MYSQL_PASSWORD: ${{ env.IMPORT_EXPORT_MYSQL_PASSWORD }}
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: import_export
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
postgres:
image: postgres
env:
IMPORT_EXPORT_TEST_TYPE: postgres
IMPORT_EXPORT_POSTGRESQL_USER: postgres
IMPORT_EXPORT_POSTGRESQL_PASSWORD: ${{ env.PASSWD }}
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: import_export
POSTGRES_USER: ${{ env.IMPORT_EXPORT_POSTGRESQL_USER }}
POSTGRES_PASSWORD: ${{ env.IMPORT_EXPORT_POSTGRESQL_PASSWORD }}
POSTGRES_DB: ${{ env.DB_NAME }}
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Set up MySQL
run: >
sudo /etc/init.d/mysql start
mysql -e 'CREATE DATABASE ${{ env.DB_NAME }};'
-u${{ env.IMPORT_EXPORT_MYSQL_USER }}
-p${{ env.IMPORT_EXPORT_MYSQL_PASSWORD }}
- name: Check out repository code
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Run isort checks
uses: jamescurtin/isort-action@master
- uses: actions/cache@v2
with:
sortPaths: "import_export tests"
configuration: "--check-only"
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements/*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements/base.txt
pip install -r requirements/test.txt
- if: matrix.django-version != 'main'
name: Upgrade Django version (release)
run: |
python -m pip install "Django~=${{ matrix.django-version }}.0"
- if: matrix.django-version == 'main'
name: Upgrade Django version (main)
run: |
python -m pip install "https://github.com/django/django/archive/main.tar.gz"
- name: List versions
run: |
echo "Python ${{ matrix.python-version }} -> Django ${{ matrix.django-version }}"
python --version
echo "Django `django-admin --version`"
- name: Run Tests
python -m pip install --upgrade pip
pip install tox tox-py coverage coveralls
- name: Run tox targets for ${{ matrix.python-version }} (sqlite)
run: tox --py current
- name: Run tox targets for ${{ matrix.python-version }} (postgres)
run: tox --py current
env:
IMPORT_EXPORT_TEST_TYPE: postgres
- name: Run tox targets for ${{ matrix.python-version }} (mysql)
run: tox --py current
env:
DB: ${{ matrix.db }}
DB_HOST: 127.0.0.1
DB_PORT: ${{ matrix.db_port }}
DB_PASSWORD: ${{ env.PASSWD }}
run: >-
PYTHONPATH=".:tests:$PYTHONPATH" python
-W error::DeprecationWarning -W error::PendingDeprecationWarning
-m coverage run --omit='setup.py,./tests/*,./import_export/locale/*'
--source=. tests/manage.py test core --settings=
IMPORT_EXPORT_TEST_TYPE: mysql-innodb
- name: Combine test coverage
run: coverage combine
- name: Upload coverage data to coveralls.io
run: coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_FLAG_NAME: ${{ matrix.db }}-${{ matrix.django-version }}-${{ matrix.python-version }}
COVERALLS_FLAG_NAME: ${{ matrix.python-version }}
COVERALLS_PARALLEL: true

coveralls:
Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ accommodate these changes.
the new `*Mixin.resource_classes` accepting subscriptable type (list, tuple, ...) has been added.
- Same applies to all of the `get_resource_class`, `get_import_resource_class` and `get_export_resource_class` methods.

- Deprecated `exceptions.py` - this module will be removed in a future release (#1372)

Enhancements
############

Expand All @@ -34,6 +36,7 @@ Development
###########

- Drop support for python3.6, django 2.2, 3.0, 3.1 (#1366)
- Increased test coverage, refactored CI build to use tox (#1372)

2.7.1 (2021-12-23)
------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

# General information about the project.
project = 'django-import-export'
copyright = '2012–2020, Bojan Mihelac'
copyright = '2012–2022, Bojan Mihelac'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ exporting data with included admin integration.
import_workflow
bulk_import
celery
testing
changelog

.. toctree::
Expand Down
49 changes: 49 additions & 0 deletions docs/testing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Testing
=======

All tests can be run using `tox <https://tox.wiki/en/latest/>`_ simply by running the `tox` command. By default, tests are run against a local sqlite2 instance.

MySql / Postgres tests
######################

By using Docker, you can also run tests against either a MySQL db and/or Postgres.

The ``IMPORT_EXPORT_TEST_TYPE`` must be set according to the type of tests you wish to run. Set to 'postgres' for postgres tests, and 'mysql-innodb' for mysql tests. If this environment variable is blank (or is any other value) then the default sqlite2 db will be used.

This process is scripted in ``runtests.sh``. Assuming that you have docker installed on your system, running ``runtests.sh`` will run tox against sqlite2, mysql and postgres. You can edit this script to customise testing as you wish.

Note that this is the process which is undertaken by CI builds.

Coverage
########

Coverage data is written in parallel mode by default (defined in ``setup.cfg``). After a tox run, you can view coverage data as follows:

.. code-block:: bash
# combine all coverage data generated by tox into one file
coverage combine
# produce an HTML coverage report
coverage html
Check the output of the above commands to locate the coverage HTML file.

Bulk testing
############

There is a helper script available to generate and profile bulk loads. See ``scripts/bulk_import.py``.

You can use this script by configuring environment variables as defined above, and then installing and running the test application. In order to run the helper script, you will need to install ``requirements/test.txt``, and then add `django-extensions` to `settings.py` (`INSTALLED_APPS`).

You can then run the script as follows:

.. code-block:: bash
# run creates, updates, and deletes
./manage.py runscript bulk_import
# pass 'create', 'update' or 'delete' to run the single test
./manage.py runscript bulk_import --script-args create
5 changes: 5 additions & 0 deletions import_export/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import warnings

warnings.warn("the exceptions module is deprecated and will be removed in a future release", DeprecationWarning)


class ImportExportError(Exception):
"""A generic exception for all others to extend."""
pass
Expand Down
15 changes: 5 additions & 10 deletions import_export/formats/base_formats.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from importlib import import_module

import tablib
from tablib.formats import registry


class Format:
Expand Down Expand Up @@ -61,14 +60,10 @@ def get_format(self):
"""
Import and returns tablib module.
"""
try:
# Available since tablib 1.0
from tablib.formats import registry
except ImportError:
return import_module(self.TABLIB_MODULE)
else:
key = self.TABLIB_MODULE.split('.')[-1].replace('_', '')
return registry.get_format(key)
if not self.TABLIB_MODULE:
raise AttributeError("TABLIB_MODULE must be defined")
key = self.TABLIB_MODULE.split('.')[-1].replace('_', '')
return registry.get_format(key)

@classmethod
def is_available(cls):
Expand Down
2 changes: 1 addition & 1 deletion import_export/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ def widget_from_django_field(cls, f, default=widgets.Widget):
Returns the widget that would likely be associated with each
Django type.
Includes mapping of Postgres Array and JSON fields. In the case that
Includes mapping of Postgres Array field. In the case that
psycopg2 is not installed, we consume the error and process the field
regardless.
"""
Expand Down
4 changes: 2 additions & 2 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
isort
psycopg2-binary
mysqlclient
coveralls
chardet
pytz
memory-profiler
django-extensions
django-extensions
coverage
31 changes: 30 additions & 1 deletion runtests.sh
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
PYTHONPATH=".:tests:$PYTHONPATH" django-admin test core --settings=settings
#!/usr/bin/env sh

# run tests against all supported databases
# postgres / mysql run via docker
# sqlite (default) runs against local database file (database.db)

echo "starting local database instances"
docker-compose -f tests/docker-compose.yml up -d

export DJANGO_SETTINGS_MODULE=settings

export IMPORT_EXPORT_POSTGRESQL_USER=pguser
export IMPORT_EXPORT_POSTGRESQL_PASSWORD=pguserpass

export IMPORT_EXPORT_MYSQL_USER=mysqluser
export IMPORT_EXPORT_MYSQL_PASSWORD=mysqluserpass

echo "running tests (sqlite)"
tox

echo "running tests (mysql)"
export IMPORT_EXPORT_TEST_TYPE=mysql-innodb
tox

echo "running tests (postgres)"
export IMPORT_EXPORT_TEST_TYPE=postgres
tox

echo "removing local database instances"
docker-compose -f tests/docker-compose.yml down -v
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ python-file-with-version = import_export/__init__.py

[isort]
profile = black

[coverage:run]
parallel = true
source = import_export

0 comments on commit 5b3b250

Please sign in to comment.