Skip to content

Commit

Permalink
Merge pull request #48 from yaml2sbml-dev/feature_tests
Browse files Browse the repository at this point in the history
Improve tests (closes #18, #34)
  • Loading branch information
jvanhoefer authored Jan 16, 2021
2 parents 9a23a00 + 7e5b69c commit 1afbc73
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 100 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/ci_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,18 @@ jobs:
.github/workflows/install_deps.sh amici
pip install .
- name: flake8
run: |
./run_flake8.sh
- name: Run tests
timeout-minutes: 5
run: |
python -m pytest --cov=yaml2sbml --cov-report=xml tests -s
python -m pytest --nbmake --cov=yaml2sbml --cov-report=xml tests -s
- name: Test CLI
run: |
./tests/test_CLI.sh
- name: Codecov
uses: codecov/codecov-action@v1
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/install_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ pip install wheel
# required for tests
pip install pytest pytest-cov

pip install flake8
pip install nbmake

# iterate over optional dependencies
for par in "$@"; do
case $par in
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include yaml2sbml/yaml_schema.yaml
5 changes: 5 additions & 0 deletions run_flake8.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

python3 -m flake8 \
--exclude=build,doc,examples,source \
--per-file-ignores='*/__init__.py:F401 test/*:T001,S101'
12 changes: 10 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@
version="0.1.1",
author="Jakob Vanhoefer, Marta R. A. Matos",
author_email="[email protected]",
description="A small package to convert ODEs specified in a yaml file to SBML/PEtab.",
description="A small package to convert ODEs specified in "
"a yaml file to SBML/PEtab.",
url="https://github.com/martamatos/yaml2sbml",
packages=setuptools.find_packages(),
install_requires=["python-libsbml>=5.18.0",
"PyYAML>=5.1",
"pandas>=1.0.1",
"petab>=0.1.4"],
tests_require=["amici>=0.11.10",
"pypesto>=0.2.2"
"numpy>=1.19.4",
"matplotlib>=3.1.0",
"flake8>=3.7.2",
"nbmake>=0.1.0", ],
extras_require={'examples': ["amici>=0.11.10",
"numpy>=1.19.4",
"matplotlib>=3.1.0"]},
Expand All @@ -29,5 +36,6 @@
"License :: OSI Approved :: MIT License",
"Operating System :: Unix",
],
entry_points=ENTRY_POINTS
entry_points=ENTRY_POINTS,
include_package_data=True
)
16 changes: 16 additions & 0 deletions tests/test_CLI.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

mkdir test_output

# test yaml2sbml
yaml2sbml ./test_yaml2sbml/ode_input1.yaml test_output/test_sbml.xml

# test yaml2petab for both versions of the petab yaml flag
yaml2petab ./test_yaml2sbml/ode_input2.yaml test_output petab_test_sbml.xml -y test_yaml.yml
yaml2petab ./test_yaml2sbml/ode_input2.yaml test_output petab_test_sbml.xml --petab_yaml test_yaml.yml

# test validator
yaml2sbml_validate ./test_yaml2sbml/ode_input1.yaml

rm -r test_output

34 changes: 19 additions & 15 deletions tests/test_yaml2petab.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,32 @@

class TestYaml2PEtab(unittest.TestCase):
"""
TestCase class for testing ODE import from a generic yaml file and conversion to SBML.
TestCase class for testing ODE import from a generic yaml file
and conversion to PEtab.
"""

def setUp(self):
this_dir, _ = os.path.split(__file__)
self.test_folder = os.path.join(this_dir, 'test_yaml2sbml')

def test_petab_export(self):
"""
Test PEtab export
"""
ode_file = os.path.join(self.test_folder, 'ode_input2.yaml')

yaml2PEtab.yaml2petab(ode_file,
self.test_folder,
'sbml_test.xml')

yaml2PEtab.validate_petab_tables(os.path.join(self.test_folder, 'sbml_test.xml'),
self.test_folder)

for file in ['observable_table.tsv', 'parameter_table.tsv', 'condition_table.tsv', 'sbml_test.xml']:
os.remove(os.path.join(self.test_folder, file))
"""
Test PEtab export
"""
ode_file = os.path.join(self.test_folder, 'ode_input2.yaml')

yaml2PEtab.yaml2petab(ode_file,
self.test_folder,
'sbml_test.xml')

yaml2PEtab.validate_petab_tables(
os.path.join(self.test_folder, 'sbml_test.xml'), self.test_folder)

for f in ['observable_table.tsv',
'parameter_table.tsv',
'condition_table.tsv',
'sbml_test.xml']:
os.remove(os.path.join(self.test_folder, f))


if __name__ == '__main__':
Expand Down
27 changes: 19 additions & 8 deletions tests/test_yaml2sbml.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

class TestYaml2SBML(unittest.TestCase):
"""
TestCase class for testing ODE import from a generic yaml file and conversion to SBML.
TestCase class for testing ODE import from a generic yaml file
and conversion to SBML.
"""

def setUp(self):
Expand All @@ -17,36 +18,46 @@ def test_yaml_import(self):
"""
Test yaml import/SBML generation...
"""
ode_file = os.path.join(self.test_folder, 'ode_input2.yaml')
expected_result_file = os.path.join(self.test_folder, 'true_sbml_output.xml')
ode_file = os.path.join(self.test_folder, 'ode_input1.yaml')
expected_result_file = os.path.join(self.test_folder,
'true_sbml_output.xml')

sbml_contents = _parse_yaml(ode_file)

with open(expected_result_file, 'r') as f_in:
expected_sbml_contents = f_in.read()

with open(os.path.join(self.test_folder, 'sbml_test.xml'), 'w') as f_out:
sbml_test_dir = os.path.join(self.test_folder, 'sbml_test.xml')
with open(sbml_test_dir, 'w') as f_out:
f_out.write(sbml_contents)

self.assertEqual(expected_sbml_contents, sbml_contents)

os.remove(os.path.join(self.test_folder, 'sbml_test.xml'))
os.remove(sbml_test_dir)

def test_yaml_import_observables(self):
"""
Test yaml import/export for a model containing observables
(that are not translated).
"""
ode_file = os.path.join(self.test_folder, 'ode_input2.yaml')
expected_result_file = os.path.join(self.test_folder, 'true_sbml_output.xml')

expected_result_file = \
os.path.join(self.test_folder, 'true_sbml_output.xml')

test_sbml_dir = os.path.join(self.test_folder, 'sbml_test.xml')

sbml_contents = _parse_yaml(ode_file)

with open(expected_result_file, 'r') as f_in:
expected_sbml_contents = f_in.read()

with open(os.path.join(self.test_folder, 'sbml_test.xml'), 'w') as f_out:
with open(test_sbml_dir, 'w') as f_out:
f_out.write(sbml_contents)

self.assertEqual(expected_sbml_contents, sbml_contents)

os.remove(os.path.join(self.test_folder, 'sbml_test.xml'))
os.remove(test_sbml_dir)


if __name__ == '__main__':
Expand Down
22 changes: 15 additions & 7 deletions tests/test_yaml_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,46 @@ def setUp(self):
self.test_folder = os.path.join(this_dir, 'test_yaml2sbml')

def test_validate_yaml_valid_1(self):
# Test validation for a valid yaml model.
file_in = os.path.join(self.test_folder, 'ode_input1.yaml')
validate_yaml(file_in)

def test_validate_yaml_valid_2(self):
# Test validation for a second valid yaml model.
file_in = os.path.join(self.test_folder, 'ode_input2.yaml')
validate_yaml(file_in)

# Should throw an error because of typos
def test_validate_yaml_typos(self):
# Test if Error is thrown due to typos.
file_in = os.path.join(self.test_folder, 'ode_input_typos.yaml')
with self.assertRaises(ValidationError):
validate_yaml(file_in)

def test_validate_yaml_typos_required(self):
file_in = os.path.join(self.test_folder, 'ode_input_typos_required.yaml')
# Test if Error is thrown due to typos.
file_in = os.path.join(self.test_folder,
'ode_input_typos_required.yaml')
with self.assertRaises(ValidationError):
validate_yaml(file_in)

def test_validate_yaml_empty_section(self):
file_in = os.path.join(self.test_folder, 'ode_input_empty_section.yaml')
# Test if Error is thrown due to empty observable section.
file_in = os.path.join(self.test_folder,
'ode_input_empty_section.yaml')
with self.assertRaises(ValidationError):
validate_yaml(file_in)

def test_catch_invalid_time_block_missing_variable_key(self):
# time block without kew word "variable"
file_in = os.path.join(self.test_folder, 'ode_input_invalid_time_1.yaml')
# Test time block without kew word "variable".
file_in = os.path.join(self.test_folder,
'ode_input_invalid_time_1.yaml')
with self.assertRaises(ValidationError):
validate_yaml(file_in)

def test_catch_invalid_time_block_as_array(self):
# time block as array instead of single object
file_in = os.path.join(self.test_folder, 'ode_input_invalid_time_2.yaml')
# Test time block as array instead of single object.
file_in = os.path.join(self.test_folder,
'ode_input_invalid_time_2.yaml')
with self.assertRaises(ValidationError):
validate_yaml(file_in)

Expand Down
Loading

0 comments on commit 1afbc73

Please sign in to comment.