Skip to content

Commit

Permalink
Switch from nose to pytest (#54)
Browse files Browse the repository at this point in the history
* Use pytest everywhere

* Set pytest as test requirement

* Update outdated build-system information

* Update install docs

* Add pytest config file

* Run CI with pytest

* Switch to codecov

* Update docs section about CI

* Point to correct directory

* Drop plus from doctest flag

* Increase fetch-depth

* Increment version number
  • Loading branch information
sethaxen authored Jan 14, 2021
1 parent c4703c6 commit b556110
Show file tree
Hide file tree
Showing 17 changed files with 192 additions and 262 deletions.
29 changes: 8 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- name: Cache conda packages
uses: actions/cache@v1
env:
Expand Down Expand Up @@ -43,24 +45,9 @@ jobs:
- name: Run tests
shell: bash -l {0}
run: |
conda install -c conda-forge nose mock coverage coveralls
nosetests --with-coverage --with-doctest --doctest-options=+ELLIPSIS e3fp
- name: Upload to coveralls
shell: bash -l {0}
run: |
coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_REPO_TOKEN: hTn1CWmaoGxWHc3Kpnv3f1ctfGLL2S01K
COVERALLS_FLAG_NAME: Python ${{ matrix.python-version }} - ${{ matrix.os }})
COVERALLS_PARALLEL: true
finish:
name: Coveralls Finished
needs: test
runs-on: ubuntu-latest
steps:
- run: |
$CONDA/bin/conda install -c conda-forge coveralls
$CONDA/bin/coveralls --finish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
conda install -c conda-forge pytest pytest-cov mock
pytest --cov=e3fp --cov-report=xml e3fp/test
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: false
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
E3FP: Extended 3-Dimensional FingerPrint
========================================

|Docs Status| |CI Status| |Coveralls Status| |PyPi Version| |Conda Version| |License|
|Docs Status| |CI Status| |Codecov Status| |PyPi Version| |Conda Version| |License|

E3FP [1]_ is a 3D molecular fingerprinting method inspired by Extended
Connectivity FingerPrints (ECFP) [2]_, integrating tightly with the RDKit_.
Expand Down Expand Up @@ -52,8 +52,8 @@ References
.. |Docs Status| image:: http://readthedocs.org/projects/e3fp/badge/?version=latest
:target: http://e3fp.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. |Coveralls Status| image:: https://coveralls.io/repos/github/keiserlab/e3fp/badge.svg?branch=master
:target: https://coveralls.io/github/keiserlab/e3fp?branch=master
.. |Codecov Status| image:: https://codecov.io/github/keiserlab/e3fp/coverage.svg?branch=master
:target: https://codecov.io/github/keiserlab/e3fp?branch=master
:alt: Code Coverage
.. |PyPi Version| image:: https://img.shields.io/pypi/v/e3fp.svg
:target: https://pypi.python.org/pypi/e3fp
Expand Down
10 changes: 5 additions & 5 deletions doc/source/dev/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ produce a specific output. For examples, see the `fingeprinting tests
Continuous Integration
~~~~~~~~~~~~~~~~~~~~~~

E3FP uses `Travis CI`_ for continuous integration. This ensures that each commit
E3FP uses `GitHub Actions`_ for continuous integration. This ensures that each commit
and pull request passes all tests on a variety of a systems and for all
supported versions of Python. Additionally, Travis CI updates code coverage on
Coveralls_ and tests all usage examples in the documentation using `doctest`.
supported versions of Python. Additionally, GitHub Actions updates code coverage on
Codecov_ and tests all usage examples in the documentation using `doctest`.

Documentation
-------------
Expand Down Expand Up @@ -169,7 +169,7 @@ Releasing Code
.. _Sphinx: http://www.sphinx-doc.org/en/stable/index.html
.. _doctest: https://docs.python.org/3/library/doctest.html
.. _pull request: https://help.github.com/articles/creating-a-pull-request/
.. _Travis CI: https://travis-ci.org/keiserlab/e3fp
.. _Coveralls: https://coveralls.io/github/keiserlab/e3fp
.. _GitHub Actions: https://github.com/keiserlab/e3fp/actions
.. _Codecov: https://codecov.io/github/keiserlab/e3fp

.. include:: ../substitutions.rst
6 changes: 3 additions & 3 deletions doc/source/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ Option 3: Clone the Repository
Testing
-------

After installation, it is recommended to run all tests with ``nose``.
After running :code:`pip install nose` or :code:`conda install -c conda-forge nose`, run
After installation, it is recommended to run all tests with ``pytest``.
After running :code:`pip install pytest` or :code:`conda install -c conda-forge pytest`, run

.. code:: bash
$ nosetests e3fp
$ pytest e3fp
.. include:: substitutions.rst
2 changes: 1 addition & 1 deletion e3fp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .util import E3FPWarning, E3FPDeprecationWarning

version_info = (1, 2, 2)
version_info = (1, 2, 3)
version = ".".join(str(c) for c in version_info)
__version__ = version
9 changes: 2 additions & 7 deletions e3fp/test/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@
E-mail: [email protected]
"""
import os
import unittest


class ConfigTestCases(unittest.TestCase):
class TestConfig:
def test_config_file_exists(self):
from e3fp.config.params import DEF_PARAM_FILE

self.assertTrue(os.path.isfile(DEF_PARAM_FILE))


if __name__ == "__main__":
unittest.main()
assert os.path.isfile(DEF_PARAM_FILE)
15 changes: 5 additions & 10 deletions e3fp/test/test_conformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
Author: Seth Axen
E-mail: [email protected]
"""
import unittest


class ConformerTestCases(unittest.TestCase):
class TestConformer:
def test_standardisation(self):
import rdkit.Chem
from e3fp.conformer.util import (
Expand All @@ -16,10 +15,10 @@ def test_standardisation(self):

smiles = "C[N-]c1cccc[n+]1C"
mol = mol_from_smiles(smiles, "tmp")
self.assertEqual(rdkit.Chem.MolToSmiles(mol), smiles)
assert rdkit.Chem.MolToSmiles(mol) == smiles

mol = mol_to_standardised_mol(mol)
self.assertEqual(rdkit.Chem.MolToSmiles(mol), "CN=c1ccccn1C")
assert rdkit.Chem.MolToSmiles(mol) == "CN=c1ccccn1C"

def test_default_is_unseeded(self):
import rdkit.Chem
Expand All @@ -46,7 +45,7 @@ def test_default_is_unseeded(self):
if rms > 1e-2:
fail = False
break
self.assertFalse(fail)
assert not fail

def test_seed_produces_same_conformers(self):
import rdkit.Chem
Expand All @@ -73,8 +72,4 @@ def test_seed_produces_same_conformers(self):
if rms > 1e-2:
fail = True
break
self.assertFalse(fail)


if __name__ == "__main__":
unittest.main()
assert not fail
11 changes: 3 additions & 8 deletions e3fp/test/test_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
Author: Seth Axen
E-mail: [email protected]
"""
import unittest


class RequiredDependenciesTestCase(unittest.TestCase):
class TestRequiredDependencies:
def test_rdkit(self):
import rdkit

Expand All @@ -23,15 +22,15 @@ def test_python_utilities(self):
import python_utilities


class OptionalFeatureDependenciesTestCase(unittest.TestCase):
class TestOptionalFeatureDependencies:
def test_h5py(self):
import h5py

def test_standardiser(self):
import standardiser


class OptionalParallelDependenciesTestCase(unittest.TestCase):
class TestOptionalParallelDependencies:
def test_mpi4py(self):
import mpi4py

Expand All @@ -40,7 +39,3 @@ def test_concurrent(self):

def test_python_utilities(self):
import python_utilities.parallel


if __name__ == "__main__":
unittest.main()
37 changes: 15 additions & 22 deletions e3fp/test/test_fingerprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
Author: Seth Axen
E-mail: [email protected]
"""
import unittest
import pytest


class FingerprintIOTestCases(unittest.TestCase):
class TestFingerprintIO:
def test_fprint_from_indices(self):
from e3fp.fingerprint.fprint import (
Fingerprint,
Expand All @@ -18,7 +17,7 @@ def test_fprint_from_indices(self):
in_indices = [3, 1, 4, 5]
bits = 32
fprint = fp_type.from_indices(in_indices, bits=bits)
self.assertEqual(sorted(in_indices), sorted(fprint.indices))
assert sorted(in_indices) == sorted(fprint.indices)

def test_fprint_from_fprint(self):
from e3fp.fingerprint.fprint import (
Expand All @@ -32,7 +31,7 @@ def test_fprint_from_fprint(self):
bits = 32
fprint1 = fp_type.from_indices(in_indices, bits=bits)
fprint2 = fp_type.from_fingerprint(fprint1)
self.assertEqual(fprint1, fprint2)
assert fprint1 == fprint2

def test_countfprint_from_counts(self):
from e3fp.fingerprint.fprint import CountFingerprint
Expand All @@ -41,7 +40,7 @@ def test_countfprint_from_counts(self):
bits = 32
fprint = CountFingerprint.from_counts(in_counts, bits=bits)
out_counts = fprint.counts
self.assertEqual(in_counts, out_counts)
assert in_counts == out_counts

def test_floatfprint_from_counts(self):
from e3fp.fingerprint.fprint import FloatFingerprint
Expand All @@ -50,7 +49,7 @@ def test_floatfprint_from_counts(self):
bits = 32
fprint = FloatFingerprint.from_counts(in_counts, bits=bits)
out_counts = fprint.counts
self.assertEqual(in_counts, out_counts)
assert in_counts == out_counts

def test_unique_indices(self):
from e3fp.fingerprint.fprint import (
Expand All @@ -63,7 +62,7 @@ def test_unique_indices(self):
in_indices = [3, 1, 4, 5, 1, 5, 9]
bits = 32
fprint = fp_type.from_indices(in_indices, bits=bits)
self.assertEqual(sorted(set(in_indices)), sorted(fprint.indices))
assert sorted(set(in_indices)) == sorted(fprint.indices)

def test_bitstring_io(self):
from e3fp.fingerprint.fprint import (
Expand All @@ -76,7 +75,7 @@ def test_bitstring_io(self):
in_bitstring = "1001001111011000"
fprint = fp_type.from_bitstring(in_bitstring)
out_bitstring = fprint.to_bitstring()
self.assertEqual(in_bitstring, out_bitstring)
assert in_bitstring == out_bitstring

def test_vector_io(self):
from e3fp.fingerprint.fprint import (
Expand Down Expand Up @@ -106,7 +105,7 @@ def test_rdkit_io(self):
rdkit_fprint1 = fprint1.to_rdkit()
fprint2 = fp_type.from_rdkit(rdkit_fprint1)
rdkit_fprint2 = fprint2.to_rdkit()
self.assertEqual(rdkit_fprint1, rdkit_fprint2)
assert rdkit_fprint1 == rdkit_fprint2

def test_basic_properties(self):
from e3fp.fingerprint.fprint import (
Expand All @@ -123,21 +122,15 @@ def test_basic_properties(self):
level = int(np.random.randint(0, 10))
for fp_type in (Fingerprint, CountFingerprint, FloatFingerprint):
fp = fp_type.from_indices(indices, bits=bits, level=level)
self.assertEqual(fp.bits, bits)
self.assertEqual(len(fp), bits)
self.assertEqual(fp.bit_count, unique_inds.size)
self.assertAlmostEqual(
fp.density, float(unique_inds.size) / bits
)
assert fp.bits == bits
assert len(fp) == bits
assert fp.bit_count == unique_inds.size
assert fp.density == pytest.approx(float(unique_inds.size) / bits)


class FingerprintAlgebraTestCases(unittest.TestCase):
class TestFingerprintAlgebra:
pass


class FingerprintComparisonTestCases(unittest.TestCase):
class TestFingerprintComparison:
pass


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit b556110

Please sign in to comment.