ref: 0045668fdecf33e793f270f6a251b07224b7ad40
parent: a617bf31cb29614eae92649034696100726ba87d
parent: 74c1fb9a63dfa46c0591816bd2f450c5f2dba751
author: Paul Brossier <piem@piem.org>
date: Wed Dec 19 13:29:13 EST 2018
Merge branch 'feature/pytest' (closes #163)
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -75,4 +75,4 @@
test_script:
- "python python\\demos\\demo_create_test_sounds.py"
- - "nose2 --verbose"
+ - "pytest --verbose"
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -19,16 +19,16 @@
command: |
pip install --user dist/aubio*.whl
-test-nose2: &test-nose2
+test-pytest: &test-pytest
name: Test python wheel
command: |
make create_test_sounds
- PATH=/home/circleci/.local/bin:$PATH nose2 -v
+ PATH=/home/circleci/.local/bin:$PATH pytest -v
-test-nose2-nosounds: &test-nose2-nosounds
+test-pytest-nosounds: &test-pytest-nosounds
name: Test python wheel
command: |
- PATH=/home/circleci/.local/bin:$PATH nose2 -v
+ PATH=/home/circleci/.local/bin:$PATH pytest -v
uninstall-wheel: &uninstall-wheel
name: Uninstall python wheel
@@ -47,7 +47,7 @@
- run: *pip-install
- run: *build-wheel
- run: *install-wheel
- - run: *test-nose2
+ - run: *test-pytest
- run: *uninstall-wheel
- store_artifacts:
path: dist/
@@ -61,7 +61,7 @@
- run: *pip-install
- run: *build-wheel
- run: *install-wheel
- - run: *test-nose2
+ - run: *test-pytest
- run: *uninstall-wheel
- store_artifacts:
path: dist/
@@ -75,7 +75,7 @@
- run: *pip-install
- run: *build-wheel
- run: *install-wheel
- - run: *test-nose2
+ - run: *test-pytest
- run: *uninstall-wheel
- store_artifacts:
path: dist/
@@ -88,7 +88,7 @@
- run: *pip-install
- run: *build-wheel
- run: *install-wheel
- - run: *test-nose2-nosounds
+ - run: *test-pytest-nosounds
- run: *uninstall-wheel
- store_artifacts:
path: dist/
--- a/.travis.yml
+++ b/.travis.yml
@@ -85,6 +85,7 @@
- travis_retry make getwaf expandwaf deps_python
- which pip
- pip --version
+ - pip install coverage
script:
- make create_test_sounds
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -6,16 +6,14 @@
recursive-include waflib *.py
include Makefile wscript */wscript_build
include aubio.pc.in
-include nose2.cfg
include requirements.txt
include src/*.c src/*.h
include src/*/*.c src/*/*.h
include examples/*.c examples/*.h
-include tests/*.h tests/*/*.c tests/*/*/*.c
+recursive-include tests *.h *.c *.py
include python/ext/*.h
recursive-include python *.py
include python/README.md
-include python/tests/run_all_tests
include python/tests/eval_pitch
include python/tests/*.expected
include doc/*.txt doc/*.rst doc/*.cfg doc/Makefile doc/make.bat doc/conf.py
--- a/Makefile
+++ b/Makefile
@@ -35,8 +35,8 @@
DATAROOTDIR?=$(PREFIX)/share
MANDIR?=$(DATAROOTDIR)/man
-# default nose2 command
-NOSE2?=nose2 -N 4 --verbose
+# default python test command
+PYTEST?=pytest --verbose
SOX=sox
@@ -140,9 +140,7 @@
test_python: export PYTHONPATH=$(PYDESTDIR)/$(LIBDIR)
test_python: local_dylib
# run test with installed package
- # ./python/tests/run_all_tests --verbose
- # run with nose2, multiple processes
- $(NOSE2)
+ $(PYTEST)
clean_python:
./setup.py clean
@@ -253,7 +251,7 @@
# build and test python
pip install -v -e .
# run tests, with python coverage
- coverage run `which nose2`
+ coverage run `which pytest`
# capture coverage again
lcov $(LCOVOPTS) --capture --no-external --directory . \
--output-file build/coverage_python.info
--- a/doc/python_module.rst
+++ b/doc/python_module.rst
@@ -89,14 +89,15 @@
Python tests
------------
-A number of Python tests are provided in the `python tests`_. To run them,
-install `nose2`_ and run the script ``python/tests/run_all_tests``:
+A number of Python tests are provided in the `python/tests`_ folder. To run
+them, install `pytest`_ and run it from the aubio source directory:
.. code-block:: console
- $ pip install nose2
- $ ./python/tests/run_all_tests
+ $ pip install pytest
+ $ git clone https://git.aubio.org/aubio/aubio
+ $ cd aubio
+ $ pytest
-.. _demo_filter.py: https://github.com/aubio/aubio/blob/master/python/demos/demo_filter.py
-.. _python tests: https://github.com/aubio/aubio/blob/master/python/tests
-.. _nose2: https://github.com/nose-devs/nose2
+.. _python/tests: https://github.com/aubio/aubio/blob/master/python/tests
+.. _pytest: https://pytest.org
--- a/nose2.cfg
+++ /dev/null
@@ -1,6 +1,0 @@
-[unittest]
-start-dir = python/tests/
-plugins = nose2.plugins.mp
-
-[multiprocess]
-always-on = false
--- a/python/README.md
+++ b/python/README.md
@@ -27,7 +27,7 @@
Demos
-----
-Some examples are available in the [`python/demos`][demos_dir] folder. Each
+Some examples are available in the [`python/demos` folder][demos_dir]. Each
script is a command line program which accepts one ore more argument.
**Notes**: installing additional modules is required to run some of the demos.
--- a/python/tests/__init__.py
+++ /dev/null
@@ -1,1 +1,0 @@
-
--- /dev/null
+++ b/python/tests/_tools.py
@@ -1,0 +1,41 @@
+"""
+This file imports test methods from different testing modules, in this
+order:
+
+ - try importing 'pytest'
+ - if it fails, fallback to 'numpy.testing'
+
+Nose2 support was removed because of lacking assertWarns on py2.7.
+
+"""
+
+import sys
+
+_has_pytest = False
+
+# check if we have pytest
+try:
+ import pytest
+ parametrize = pytest.mark.parametrize
+ assert_raises = pytest.raises
+ assert_warns = pytest.warns
+ skipTest = pytest.skip
+ _has_pytest = True
+ def run_module_suite():
+ import sys, pytest
+ pytest.main(sys.argv)
+except:
+ pass
+
+# otherwise fallback on numpy.testing
+if not _has_pytest:
+ from numpy.testing import dec, assert_raises, assert_warns
+ from numpy.testing import SkipTest
+ parametrize = dec.parametrize
+ def skipTest(msg):
+ raise SkipTest(msg)
+ from numpy.testing import run_module_suite
+
+# always use numpy's assert_equal
+import numpy
+assert_equal = numpy.testing.assert_equal
--- a/python/tests/run_all_tests
+++ /dev/null
@@ -1,5 +1,0 @@
-#! /usr/bin/env python
-
-if __name__ == '__main__':
- import nose2.main
- nose2.discover()
--- a/python/tests/test_aubio.py
+++ b/python/tests/test_aubio.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase
class aubiomodule_test_case(TestCase):
@@ -15,5 +14,5 @@
self.assertEqual('0', aubio.version[0])
if __name__ == '__main__':
+ from unittest import main
main()
-
--- a/python/tests/test_aubio_cmd.py
+++ b/python/tests/test_aubio_cmd.py
@@ -1,8 +1,7 @@
#! /usr/bin/env python
-import aubio.cmd
-from nose2 import main
from numpy.testing import TestCase
+import aubio.cmd
class aubio_cmd(TestCase):
@@ -31,4 +30,5 @@
"3200\t")
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_aubio_cut.py
+++ b/python/tests/test_aubio_cut.py
@@ -1,7 +1,6 @@
#! /usr/bin/env python
import aubio.cut
-from nose2 import main
from numpy.testing import TestCase
class aubio_cut(TestCase):
@@ -13,4 +12,5 @@
assert self.a_parser.parse_args(['-v']).verbose
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_cvec.py
+++ b/python/tests/test_cvec.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
import numpy as np
from numpy.testing import TestCase, assert_equal
from aubio import cvec, fvec, float_type
@@ -141,4 +140,5 @@
a.norm = np.zeros((512//2+1, 2), dtype = float_type)
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_dct.py
+++ b/python/tests/test_dct.py
@@ -66,3 +66,7 @@
aubio.dct(size)
except AssertionError:
self.skipTest('creating aubio.dct with size %d did not fail' % size)
+
+if __name__ == '__main__':
+ from unittest import main
+ main()
--- a/python/tests/test_fft.py
+++ b/python/tests/test_fft.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase
from numpy.testing import assert_equal, assert_almost_equal
import numpy as np
@@ -212,4 +211,5 @@
fft(win_s)
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_filter.py
+++ b/python/tests/test_filter.py
@@ -1,9 +1,8 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase, assert_equal, assert_almost_equal
from aubio import fvec, digital_filter
-from .utils import array_from_text_file
+from utils import array_from_text_file
class aubio_filter_test_case(TestCase):
@@ -94,4 +93,5 @@
digital_filter(-1)
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_filterbank.py
+++ b/python/tests/test_filterbank.py
@@ -4,7 +4,7 @@
from numpy.testing import TestCase, assert_equal, assert_almost_equal
from aubio import cvec, filterbank, float_type
-from .utils import array_from_text_file
+from utils import array_from_text_file
class aubio_filterbank_test_case(TestCase):
@@ -87,5 +87,5 @@
f(cvec(256))
if __name__ == '__main__':
- import nose2
- nose2.main()
+ from unittest import main
+ main()
--- a/python/tests/test_filterbank_mel.py
+++ b/python/tests/test_filterbank_mel.py
@@ -2,12 +2,10 @@
import numpy as np
from numpy.testing import TestCase, assert_equal, assert_almost_equal
+from _tools import assert_warns
from aubio import fvec, cvec, filterbank, float_type
-import warnings
-warnings.filterwarnings('ignore', category=UserWarning, append=True)
-
class aubio_filterbank_mel_test_case(TestCase):
def test_slaney(self):
@@ -75,8 +73,8 @@
samplerate = 22050
freq_list = [0, samplerate//4, samplerate // 2 + 1]
f = filterbank(len(freq_list)-2, 1024)
- # TODO add assert_warns
- f.set_triangle_bands(fvec(freq_list), samplerate)
+ with assert_warns(UserWarning):
+ f.set_triangle_bands(fvec(freq_list), samplerate)
def test_triangle_freqs_with_not_enough_filters(self):
"""make sure set_triangle_bands warns when not enough filters"""
@@ -83,8 +81,8 @@
samplerate = 22050
freq_list = [0, 100, 1000, 4000, 8000, 10000]
f = filterbank(len(freq_list)-3, 1024)
- # TODO add assert_warns
- f.set_triangle_bands(fvec(freq_list), samplerate)
+ with assert_warns(UserWarning):
+ f.set_triangle_bands(fvec(freq_list), samplerate)
def test_triangle_freqs_with_too_many_filters(self):
"""make sure set_triangle_bands warns when too many filters"""
@@ -91,8 +89,8 @@
samplerate = 22050
freq_list = [0, 100, 1000, 4000, 8000, 10000]
f = filterbank(len(freq_list)-1, 1024)
- # TODO add assert_warns
- f.set_triangle_bands(fvec(freq_list), samplerate)
+ with assert_warns(UserWarning):
+ f.set_triangle_bands(fvec(freq_list), samplerate)
def test_triangle_freqs_with_double_value(self):
"""make sure set_triangle_bands works with 2 duplicate freqs"""
@@ -99,8 +97,8 @@
samplerate = 22050
freq_list = [0, 100, 1000, 4000, 4000, 4000, 10000]
f = filterbank(len(freq_list)-2, 1024)
- # TODO add assert_warns
- f.set_triangle_bands(fvec(freq_list), samplerate)
+ with assert_warns(UserWarning):
+ f.set_triangle_bands(fvec(freq_list), samplerate)
def test_triangle_freqs_with_triple(self):
"""make sure set_triangle_bands works with 3 duplicate freqs"""
@@ -107,9 +105,10 @@
samplerate = 22050
freq_list = [0, 100, 1000, 4000, 4000, 4000, 10000]
f = filterbank(len(freq_list)-2, 1024)
- # TODO add assert_warns
- f.set_triangle_bands(fvec(freq_list), samplerate)
+ with assert_warns(UserWarning):
+ f.set_triangle_bands(fvec(freq_list), samplerate)
+
def test_triangle_freqs_without_norm(self):
"""make sure set_triangle_bands works without """
samplerate = 22050
@@ -168,5 +167,5 @@
if __name__ == '__main__':
- import nose2
- nose2.main()
+ from unittest import main
+ main()
--- a/python/tests/test_fvec.py
+++ b/python/tests/test_fvec.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
import numpy as np
from numpy.testing import TestCase, assert_equal, assert_almost_equal
from aubio import fvec, zero_crossing_rate, alpha_norm, min_removal
@@ -148,4 +147,5 @@
del c
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_fvec_shift.py
+++ b/python/tests/test_fvec_shift.py
@@ -30,6 +30,6 @@
def test_can_shift_fvec_odd(self):
self.run_shift_ishift(7)
-from unittest import main
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_hztomel.py
+++ b/python/tests/test_hztomel.py
@@ -3,6 +3,7 @@
from unittest import main
from numpy.testing import TestCase
from numpy.testing import assert_equal, assert_almost_equal
+from _tools import assert_warns
import numpy as np
import aubio
@@ -37,12 +38,12 @@
assert_almost_equal(meltohz(hztomel(f)) - f, 0, decimal=1)
def test_meltohz_negative(self):
- # TODO add assert_warns
- assert_equal(meltohz(-1), 0)
+ with assert_warns(UserWarning):
+ assert_equal(meltohz(-1), 0)
def test_hztomel_negative(self):
- # TODO add assert_warns
- assert_equal(hztomel(-1), 0)
+ with assert_warns(UserWarning):
+ assert_equal(hztomel(-1), 0)
class aubio_hztomel_htk_test_case(TestCase):
@@ -57,14 +58,16 @@
assert_almost_equal(hztomel(6300, htk=True), 2595., decimal=1)
def test_meltohz_negative(self):
- # TODO add assert_warns
- assert_equal(meltohz(-1, htk=True), 0)
+ with assert_warns(UserWarning):
+ assert_equal(meltohz(-1, htk=True), 0)
assert_almost_equal(meltohz(2000, htk=True), 3428.7, decimal=1)
assert_almost_equal(meltohz(1000, htk=True), 1000., decimal=1)
def test_hztomel_negative(self):
- # TODO add assert_warns
- assert_equal(hztomel(-1, htk=True), 0)
+ with assert_warns(UserWarning):
+ assert_equal(meltohz(-1, htk=True), 0)
+ with assert_warns(UserWarning):
+ assert_equal(hztomel(-1, htk=True), 0)
assert_almost_equal(hztomel(1000, htk=True), 1000., decimal=1)
def test_hztomel_htk(self):
--- a/python/tests/test_mathutils.py
+++ b/python/tests/test_mathutils.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase, assert_equal
from numpy import array, arange, isnan, isinf
from aubio import bintomidi, miditobin, freqtobin, bintofreq, freqtomidi, miditofreq
@@ -101,4 +100,5 @@
assert_equal ( array(b) < 0, False )
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_mfcc.py
+++ b/python/tests/test_mfcc.py
@@ -1,7 +1,6 @@
#! /usr/bin/env python
-from nose2 import main
-from nose2.tools import params
+from _tools import parametrize, assert_raises
from numpy import random, count_nonzero
from numpy.testing import TestCase
from aubio import mfcc, cvec, float_type
@@ -15,28 +14,21 @@
new_params = ['buf_size', 'n_filters', 'n_coeffs', 'samplerate']
new_deflts = [1024, 40, 13, 44100]
-class aubio_mfcc(TestCase):
+class Test_aubio_mfcc(object):
- def setUp(self):
- self.o = mfcc()
+ members_args = 'name'
- def test_default_creation(self):
- pass
-
- def test_delete(self):
- del self.o
-
- @params(*new_params)
+ @parametrize(members_args, new_params)
def test_read_only_member(self, name):
- o = self.o
- with self.assertRaises((TypeError, AttributeError)):
+ o = mfcc()
+ with assert_raises((TypeError, AttributeError)):
setattr(o, name, 0)
- @params(*zip(new_params, new_deflts))
+ @parametrize('name, expected', zip(new_params, new_deflts))
def test_default_param(self, name, expected):
""" test mfcc.{:s} = {:d} """.format(name, expected)
- o = self.o
- self.assertEqual( getattr(o, name), expected)
+ o = mfcc()
+ assert getattr(o, name) == expected
class aubio_mfcc_wrong_params(TestCase):
@@ -82,9 +74,9 @@
#print coeffs
-class aubio_mfcc_all_parameters(TestCase):
+class Test_aubio_mfcc_all_parameters(object):
- @params(
+ run_values = [
(2048, 40, 13, 44100),
(1024, 40, 13, 44100),
(512, 40, 13, 44100),
@@ -100,7 +92,10 @@
#(1024, 30, 20, 44100),
(1024, 40, 40, 44100),
(1024, 40, 3, 44100),
- )
+ ]
+ run_args = ['buf_size', 'n_filters', 'n_coeffs', 'samplerate']
+
+ @parametrize(run_args, run_values)
def test_run_with_params(self, buf_size, n_filters, n_coeffs, samplerate):
" check mfcc can run with reasonable parameters "
o = mfcc(buf_size, n_filters, n_coeffs, samplerate)
@@ -148,4 +143,5 @@
assert m.get_scale() == 1
if __name__ == '__main__':
- main()
+ from _tools import run_module_suite
+ run_module_suite()
--- a/python/tests/test_midi2note.py
+++ b/python/tests/test_midi2note.py
@@ -2,8 +2,7 @@
# -*- coding: utf-8 -*-
from aubio import midi2note
-from nose2.tools import params
-import unittest
+from _tools import parametrize, assert_raises
list_of_known_midis = (
( 0, 'C-1' ),
@@ -15,31 +14,31 @@
( 127, 'G9' ),
)
-class midi2note_good_values(unittest.TestCase):
+class Test_midi2note_good_values(object):
- @params(*list_of_known_midis)
+ @parametrize('midi, note', list_of_known_midis)
def test_midi2note_known_values(self, midi, note):
" known values are correctly converted "
- self.assertEqual ( midi2note(midi), note )
+ assert midi2note(midi) == (note)
-class midi2note_wrong_values(unittest.TestCase):
+class Test_midi2note_wrong_values(object):
def test_midi2note_negative_value(self):
" fails when passed a negative value "
- self.assertRaises(ValueError, midi2note, -2)
+ assert_raises(ValueError, midi2note, -2)
def test_midi2note_large(self):
" fails when passed a value greater than 127 "
- self.assertRaises(ValueError, midi2note, 128)
+ assert_raises(ValueError, midi2note, 128)
def test_midi2note_floating_value(self):
" fails when passed a floating point "
- self.assertRaises(TypeError, midi2note, 69.2)
+ assert_raises(TypeError, midi2note, 69.2)
def test_midi2note_character_value(self):
" fails when passed a value that can not be transformed to integer "
- self.assertRaises(TypeError, midi2note, "a")
+ assert_raises(TypeError, midi2note, "a")
if __name__ == '__main__':
- import nose2
- nose2.main()
+ from _tools import run_module_suite
+ run_module_suite()
--- a/python/tests/test_musicutils.py
+++ b/python/tests/test_musicutils.py
@@ -1,9 +1,8 @@
#! /usr/bin/env python
-from unittest import main
import numpy as np
from numpy.testing import TestCase
-from numpy.testing.utils import assert_equal, assert_almost_equal
+from numpy.testing import assert_equal, assert_almost_equal
from aubio import window, level_lin, db_spl, silence_detection, level_detection
from aubio import fvec, float_type
@@ -85,4 +84,5 @@
assert level_detection(ones(1024, dtype = float_type), -70) == 0
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_note2midi.py
+++ b/python/tests/test_note2midi.py
@@ -4,8 +4,8 @@
from __future__ import unicode_literals
from aubio import note2midi, freq2note, note2freq, float_type
-from nose2.tools import params
-import unittest
+from numpy.testing import TestCase
+from _tools import parametrize, assert_raises, skipTest
list_of_known_notes = (
( 'C-1', 0 ),
@@ -44,29 +44,32 @@
( '2' ),
)
-class note2midi_good_values(unittest.TestCase):
+class Test_note2midi_good_values(object):
- @params(*list_of_known_notes)
+ @parametrize('note, midi', list_of_known_notes)
def test_note2midi_known_values(self, note, midi):
" known values are correctly converted "
- self.assertEqual ( note2midi(note), midi )
+ assert note2midi(note) == midi
- @params(*list_of_known_notes_with_unicode_issues)
+ @parametrize('note, midi', list_of_known_notes_with_unicode_issues)
def test_note2midi_known_values_with_unicode_issues(self, note, midi):
- " known values are correctly converted, unless decoding is expected to fail"
+ " difficult values are correctly converted unless expected failure "
try:
- self.assertEqual ( note2midi(note), midi )
+ assert note2midi(note) == midi
except UnicodeEncodeError as e:
+ # platforms with decoding failures include:
+ # - osx: python <= 2.7.10
+ # - win: python <= 2.7.12
import sys
- strfmt = "len(u'\\U0001D12A') != 1, excpected decoding failure | {:s} | {:s} {:s}"
- strres = strfmt.format(e, sys.platform, sys.version)
- # happens with: darwin 2.7.10, windows 2.7.12
+ strmsg = "len(u'\\U0001D12A') != 1, expected decoding failure"
+ strmsg += " | upgrade to Python 3 to fix"
+ strmsg += " | {:s} | {:s} {:s}"
if len('\U0001D12A') != 1 and sys.version[0] == '2':
- self.skipTest(strres + " | upgrade to Python 3 to fix")
+ skipTest(strmsg.format(repr(e), sys.platform, sys.version))
else:
raise
-class note2midi_wrong_values(unittest.TestCase):
+class note2midi_wrong_values(TestCase):
def test_note2midi_missing_octave(self):
" fails when passed only one character"
@@ -104,12 +107,14 @@
" fails when passed a note with a note name longer than expected"
self.assertRaises(ValueError, note2midi, 'CB+-3')
- @params(*list_of_unknown_notes)
+class Test_note2midi_unknown_values(object):
+
+ @parametrize('note', list_of_unknown_notes)
def test_note2midi_unknown_values(self, note):
" unknown values throw out an error "
- self.assertRaises(ValueError, note2midi, note)
+ assert_raises(ValueError, note2midi, note)
-class freq2note_simple_test(unittest.TestCase):
+class freq2note_simple_test(TestCase):
def test_freq2note_above(self):
" make sure freq2note(441) == A4 "
@@ -119,7 +124,7 @@
" make sure freq2note(439) == A4 "
self.assertEqual("A4", freq2note(439))
-class note2freq_simple_test(unittest.TestCase):
+class note2freq_simple_test(TestCase):
def test_note2freq(self):
" make sure note2freq('A3') == 220"
@@ -133,5 +138,5 @@
self.assertLess(abs(note2freq("A4")-440), 1.e-12)
if __name__ == '__main__':
- import nose2
- nose2.main()
+ from _tools import run_module_suite
+ run_module_suite()
--- a/python/tests/test_notes.py
+++ b/python/tests/test_notes.py
@@ -1,9 +1,12 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase, assert_equal, assert_almost_equal
-from aubio import notes
+from aubio import notes, source
+import numpy as np
+from utils import list_all_sounds
+list_of_sounds = list_all_sounds('sounds')
+
AUBIO_DEFAULT_NOTES_SILENCE = -70.
AUBIO_DEFAULT_NOTES_RELEASE_DROP = 10.
AUBIO_DEFAULT_NOTES_MINIOI_MS = 30.
@@ -52,14 +55,9 @@
with self.assertRaises(ValueError):
self.o.set_release_drop(val)
-from .utils import list_all_sounds
-list_of_sounds = list_all_sounds('sounds')
-
class aubio_notes_sinewave(TestCase):
def analyze_file(self, filepath, samplerate=0):
- from aubio import source
- import numpy as np
win_s = 512 # fft size
hop_s = 256 # hop size
@@ -92,4 +90,5 @@
assert_equal (results[0][1], [69, 123, -1])
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_onset.py
+++ b/python/tests/test_onset.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase, assert_equal, assert_almost_equal
from aubio import onset, fvec
@@ -116,4 +115,5 @@
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_phasevoc.py
+++ b/python/tests/test_phasevoc.py
@@ -1,9 +1,8 @@
#! /usr/bin/env python
from numpy.testing import TestCase, assert_equal, assert_array_less
+from _tools import parametrize
from aubio import fvec, cvec, pvoc, float_type
-from nose2 import main
-from nose2.tools import params
import numpy as np
if float_type == 'float32':
@@ -18,7 +17,7 @@
def create_noise(hop_s):
return np.random.rand(hop_s).astype(float_type) * 2. - 1.
-class aubio_pvoc_test_case(TestCase):
+class Test_aubio_pvoc_test_case(object):
""" pvoc object test case """
def test_members_automatic_sizes_default(self):
@@ -65,7 +64,8 @@
r = f.rdo(s)
assert_equal ( t, 0.)
- @params(
+ resynth_noise_args = "hop_s, ratio"
+ resynth_noise_values = [
( 256, 8),
( 256, 4),
( 256, 2),
@@ -87,13 +87,16 @@
(8192, 8),
(8192, 4),
(8192, 2),
- )
+ ]
+
+ @parametrize(resynth_noise_args, resynth_noise_values)
def test_resynth_steps_noise(self, hop_s, ratio):
""" check the resynthesis of a random signal is correct """
sigin = create_noise(hop_s)
self.reconstruction(sigin, hop_s, ratio)
- @params(
+ resynth_sine_args = "samplerate, hop_s, ratio, freq"
+ resynth_sine_values = [
(44100, 256, 8, 441),
(44100, 256, 4, 1203),
(44100, 256, 2, 3045),
@@ -108,7 +111,9 @@
(22050, 256, 8, 445),
(96000, 1024, 8, 47000),
(96000, 1024, 8, 20),
- )
+ ]
+
+ @parametrize(resynth_sine_args, resynth_sine_values)
def test_resynth_steps_sine(self, samplerate, hop_s, ratio, freq):
""" check the resynthesis of a sine is correct """
sigin = create_sine(hop_s, freq, samplerate)
@@ -199,5 +204,5 @@
self.skipTest('creating aubio.pvoc with size %d did not fail' % win_s)
if __name__ == '__main__':
+ from unittest import main
main()
-
--- a/python/tests/test_pitch.py
+++ b/python/tests/test_pitch.py
@@ -1,7 +1,6 @@
#! /usr/bin/env python
-from unittest import TestCase, main
-from numpy.testing import assert_equal
+from numpy.testing import TestCase, assert_equal
from numpy import sin, arange, mean, median, isnan, pi
from aubio import fvec, pitch, freqtomidi, float_type
@@ -116,10 +115,11 @@
for algo in pitch_algorithms:
for mode in signal_modes:
- test_method = create_test (algo, mode)
- test_method.__name__ = 'test_pitch_%s_%d_%d_%dHz_sin_%.0f' % ( algo,
+ _test_method = create_test (algo, mode)
+ _test_method.__name__ = 'test_pitch_%s_%d_%d_%dHz_sin_%.0f' % ( algo,
mode[0], mode[1], mode[2], mode[3] )
- setattr (aubio_pitch_Sinusoid, test_method.__name__, test_method)
+ setattr (aubio_pitch_Sinusoid, _test_method.__name__, _test_method)
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_sink.py
+++ b/python/tests/test_sink.py
@@ -1,14 +1,10 @@
#! /usr/bin/env python
-from nose2 import main
-from nose2.tools import params
from numpy.testing import TestCase
from aubio import fvec, source, sink
-from .utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
+from utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
+from _tools import parametrize, skipTest, assert_raises
-import warnings
-warnings.filterwarnings('ignore', category=UserWarning, append=True)
-
list_of_sounds = list_all_sounds('sounds')
samplerates = [0, 44100, 8000, 32000]
hop_sizes = [512, 1024, 64]
@@ -23,30 +19,26 @@
for samplerate in samplerates:
all_params.append((hop_size, samplerate, soundfile))
-class aubio_sink_test_case(TestCase):
+class Test_aubio_sink(object):
- def setUp(self):
- if not len(list_of_sounds):
- self.skipTest('add some sound files in \'python/tests/sounds\'')
-
def test_wrong_filename(self):
- with self.assertRaises(RuntimeError):
+ with assert_raises(RuntimeError):
sink('')
def test_wrong_samplerate(self):
- with self.assertRaises(RuntimeError):
+ with assert_raises(RuntimeError):
sink(get_tmp_sink_path(), -1)
def test_wrong_samplerate_too_large(self):
- with self.assertRaises(RuntimeError):
+ with assert_raises(RuntimeError):
sink(get_tmp_sink_path(), 1536001, 2)
def test_wrong_channels(self):
- with self.assertRaises(RuntimeError):
+ with assert_raises(RuntimeError):
sink(get_tmp_sink_path(), 44100, -1)
def test_wrong_channels_too_large(self):
- with self.assertRaises(RuntimeError):
+ with assert_raises(RuntimeError):
sink(get_tmp_sink_path(), 44100, 202020)
def test_many_sinks(self):
@@ -66,13 +58,13 @@
g.close()
shutil.rmtree(tmpdir)
- @params(*all_params)
+ @parametrize('hop_size, samplerate, path', all_params)
def test_read_and_write(self, hop_size, samplerate, path):
-
try:
f = source(path, samplerate, hop_size)
except RuntimeError as e:
- self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
+ err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
+ skipTest(err_msg.format(str(e), hop_size, samplerate))
if samplerate == 0: samplerate = f.samplerate
sink_path = get_tmp_sink_path()
g = sink(sink_path, samplerate)
@@ -84,12 +76,13 @@
if read < f.hop_size: break
del_tmp_sink_path(sink_path)
- @params(*all_params)
+ @parametrize('hop_size, samplerate, path', all_params)
def test_read_and_write_multi(self, hop_size, samplerate, path):
try:
f = source(path, samplerate, hop_size)
except RuntimeError as e:
- self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
+ err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
+ skipTest(err_msg.format(str(e), hop_size, samplerate))
if samplerate == 0: samplerate = f.samplerate
sink_path = get_tmp_sink_path()
g = sink(sink_path, samplerate, channels = f.channels)
@@ -125,4 +118,5 @@
g(vec, 128)
if __name__ == '__main__':
- main()
+ from _tools import run_module_suite
+ run_module_suite()
--- a/python/tests/test_slicing.py
+++ b/python/tests/test_slicing.py
@@ -1,10 +1,9 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase, assert_equal
from aubio import slice_source_at_stamps
-from .utils import count_files_in_directory, get_default_test_sound
-from .utils import count_samples_in_directory, count_samples_in_file
+from utils import count_files_in_directory, get_default_test_sound
+from utils import count_samples_in_directory, count_samples_in_file
import tempfile
import shutil
@@ -167,4 +166,5 @@
shutil.rmtree(self.output_dir)
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_source.py
+++ b/python/tests/test_source.py
@@ -1,19 +1,17 @@
#! /usr/bin/env python
-from nose2 import main
-from nose2.tools import params
+
from numpy.testing import TestCase, assert_equal
from aubio import source
-from .utils import list_all_sounds
+from utils import list_all_sounds
+import unittest
+from _tools import parametrize, assert_raises, assert_equal, skipTest
-import warnings
-warnings.filterwarnings('ignore', category=UserWarning, append=True)
-
list_of_sounds = list_all_sounds('sounds')
samplerates = [0, 44100, 8000, 32000]
hop_sizes = [512, 1024, 64]
-path = None
+default_test_sound = len(list_of_sounds) and list_of_sounds[0] or None
all_params = []
for soundfile in list_of_sounds:
@@ -21,17 +19,13 @@
for samplerate in samplerates:
all_params.append((hop_size, samplerate, soundfile))
+no_sounds_msg = "no test sounds, add some in 'python/tests/sounds/'!"
-class aubio_source_test_case_base(TestCase):
+_debug = False
- def setUp(self):
- if not len(list_of_sounds):
- self.skipTest('add some sound files in \'python/tests/sounds\'')
- self.default_test_sound = list_of_sounds[0]
+class Test_aubio_source_test_case(object):
-class aubio_source_test_case(aubio_source_test_case_base):
-
- @params(*list_of_sounds)
+ @parametrize('filename', list_of_sounds)
def test_close_file(self, filename):
samplerate = 0 # use native samplerate
hop_size = 256
@@ -38,7 +32,7 @@
f = source(filename, samplerate, hop_size)
f.close()
- @params(*list_of_sounds)
+ @parametrize('filename', list_of_sounds)
def test_close_file_twice(self, filename):
samplerate = 0 # use native samplerate
hop_size = 256
@@ -46,7 +40,7 @@
f.close()
f.close()
-class aubio_source_read_test_case(aubio_source_test_case_base):
+class Test_aubio_source_read(object):
def read_from_source(self, f):
total_frames = 0
@@ -56,40 +50,44 @@
if read < f.hop_size:
assert_equal(samples[read:], 0)
break
- #result_str = "read {:.2f}s ({:d} frames in {:d} blocks at {:d}Hz) from {:s}"
- #result_params = total_frames / float(f.samplerate), total_frames, total_frames//f.hop_size, f.samplerate, f.uri
- #print (result_str.format(*result_params))
+ if _debug:
+ result_str = "read {:.2f}s ({:d} frames"
+ result_str += " in {:d} blocks at {:d}Hz) from {:s}"
+ result_params = total_frames / float(f.samplerate), total_frames, \
+ total_frames//f.hop_size, f.samplerate, f.uri
+ print (result_str.format(*result_params))
return total_frames
- @params(*all_params)
+ @parametrize('hop_size, samplerate, soundfile', all_params)
def test_samplerate_hopsize(self, hop_size, samplerate, soundfile):
try:
f = source(soundfile, samplerate, hop_size)
except RuntimeError as e:
- self.skipTest('failed opening with hop_s = {:d}, samplerate = {:d} ({:s})'.format(hop_size, samplerate, str(e)))
+ err_msg = 'failed opening with hop_s={:d}, samplerate={:d} ({:s})'
+ skipTest(err_msg.format(hop_size, samplerate, str(e)))
assert f.samplerate != 0
read_frames = self.read_from_source(f)
if 'f_' in soundfile and samplerate == 0:
import re
- f = re.compile('.*_\([0:9]*f\)_.*')
+ f = re.compile(r'.*_\([0:9]*f\)_.*')
match_f = re.findall('([0-9]*)f_', soundfile)
if len(match_f) == 1:
expected_frames = int(match_f[0])
- self.assertEqual(expected_frames, read_frames)
+ assert_equal(expected_frames, read_frames)
- @params(*list_of_sounds)
+ @parametrize('p', list_of_sounds)
def test_samplerate_none(self, p):
f = source(p)
assert f.samplerate != 0
self.read_from_source(f)
- @params(*list_of_sounds)
+ @parametrize('p', list_of_sounds)
def test_samplerate_0(self, p):
f = source(p, 0)
assert f.samplerate != 0
self.read_from_source(f)
- @params(*list_of_sounds)
+ @parametrize('p', list_of_sounds)
def test_zero_hop_size(self, p):
f = source(p, 0, 0)
assert f.samplerate != 0
@@ -96,7 +94,7 @@
assert f.hop_size != 0
self.read_from_source(f)
- @params(*list_of_sounds)
+ @parametrize('p', list_of_sounds)
def test_seek_to_half(self, p):
from random import randint
f = source(p, 0, 0)
@@ -108,7 +106,7 @@
b = self.read_from_source(f)
assert a == b + c
- @params(*list_of_sounds)
+ @parametrize('p', list_of_sounds)
def test_duration(self, p):
total_frames = 0
f = source(p)
@@ -117,43 +115,44 @@
_, read = f()
total_frames += read
if read < f.hop_size: break
- self.assertEqual(duration, total_frames)
+ assert_equal (duration, total_frames)
-class aubio_source_test_wrong_params(TestCase):
+class Test_aubio_source_wrong_params(object):
def test_wrong_file(self):
- with self.assertRaises(RuntimeError):
+ with assert_raises(RuntimeError):
source('path_to/unexisting file.mp3')
-class aubio_source_test_wrong_params_with_file(aubio_source_test_case_base):
+@unittest.skipIf(default_test_sound is None, no_sounds_msg)
+class Test_aubio_source_wrong_params_with_file(TestCase):
def test_wrong_samplerate(self):
- with self.assertRaises(ValueError):
- source(self.default_test_sound, -1)
+ with assert_raises(ValueError):
+ source(default_test_sound, -1)
def test_wrong_hop_size(self):
- with self.assertRaises(ValueError):
- source(self.default_test_sound, 0, -1)
+ with assert_raises(ValueError):
+ source(default_test_sound, 0, -1)
def test_wrong_channels(self):
- with self.assertRaises(ValueError):
- source(self.default_test_sound, 0, 0, -1)
+ with assert_raises(ValueError):
+ source(default_test_sound, 0, 0, -1)
def test_wrong_seek(self):
- f = source(self.default_test_sound)
- with self.assertRaises(ValueError):
+ f = source(default_test_sound)
+ with assert_raises(ValueError):
f.seek(-1)
def test_wrong_seek_too_large(self):
- f = source(self.default_test_sound)
+ f = source(default_test_sound)
try:
- with self.assertRaises(ValueError):
+ with assert_raises(ValueError):
f.seek(f.duration + f.samplerate * 10)
- except AssertionError:
- self.skipTest('seeking after end of stream failed raising ValueError')
+ except:
+ skipTest('seeking after end of stream failed raising ValueError')
-class aubio_source_readmulti_test_case(aubio_source_read_test_case):
+class Test_aubio_source_readmulti(Test_aubio_source_read):
def read_from_source(self, f):
total_frames = 0
@@ -163,15 +162,18 @@
if read < f.hop_size:
assert_equal(samples[:,read:], 0)
break
- #result_str = "read {:.2f}s ({:d} frames in {:d} channels and {:d} blocks at {:d}Hz) from {:s}"
- #result_params = total_frames / float(f.samplerate), total_frames, f.channels, int(total_frames/f.hop_size), f.samplerate, f.uri
- #print (result_str.format(*result_params))
+ if _debug:
+ result_str = "read {:.2f}s ({:d} frames in {:d} channels"
+ result_str += " and {:d} blocks at {:d}Hz) from {:s}"
+ result_params = total_frames / float(f.samplerate), total_frames, \
+ f.channels, int(total_frames/f.hop_size), \
+ f.samplerate, f.uri
+ print (result_str.format(*result_params))
return total_frames
-class aubio_source_with(aubio_source_test_case_base):
+class Test_aubio_source_with(object):
- #@params(*list_of_sounds)
- @params(*list_of_sounds)
+ @parametrize('filename', list_of_sounds)
def test_read_from_mono(self, filename):
total_frames = 0
hop_size = 2048
@@ -185,4 +187,5 @@
assert_equal(total_frames, input_source.duration)
if __name__ == '__main__':
- main()
+ from _tools import run_module_suite
+ run_module_suite()
--- a/python/tests/test_source_channels.py
+++ b/python/tests/test_source_channels.py
@@ -8,7 +8,7 @@
import aubio
import numpy as np
from numpy.testing import assert_equal
-from .utils import get_tmp_sink_path
+from utils import get_tmp_sink_path
class aubio_source_test_case(unittest.TestCase):
--- a/python/tests/test_specdesc.py
+++ b/python/tests/test_specdesc.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase, assert_equal, assert_almost_equal
from numpy import random, arange, log, zeros
from aubio import specdesc, cvec, float_type
@@ -229,4 +228,5 @@
specdesc("unknown", 512)
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/test_zero_crossing_rate.py
+++ b/python/tests/test_zero_crossing_rate.py
@@ -1,6 +1,5 @@
#! /usr/bin/env python
-from unittest import main
from numpy.testing import TestCase
from aubio import fvec, zero_crossing_rate
@@ -43,4 +42,5 @@
self.assertEqual(2./buf_size, zero_crossing_rate(self.vector))
if __name__ == '__main__':
+ from unittest import main
main()
--- a/python/tests/utils.py
+++ b/python/tests/utils.py
@@ -8,11 +8,8 @@
DEFAULT_SOUND = '22050Hz_5s_brownnoise.wav'
def array_from_text_file(filename, dtype = 'float'):
- filename = os.path.join(os.path.dirname(__file__), filename)
- with open(filename) as f:
- lines = f.readlines()
- return np.array([line.split() for line in lines],
- dtype = dtype)
+ realpathname = os.path.join(os.path.dirname(__file__), filename)
+ return np.loadtxt(realpathname, dtype = dtype)
def list_all_sounds(rel_dir):
datadir = os.path.join(os.path.dirname(__file__), rel_dir)
@@ -38,13 +35,10 @@
try:
os.unlink(path)
except WindowsError as e:
- print("deleting {:s} failed ({:s}), reopening".format(path, repr(e)))
- with open(path, 'wb') as f:
- f.close()
- try:
- os.unlink(path)
- except WindowsError as f:
- print("deleting {:s} failed ({:s}), aborting".format(path, repr(e)))
+ # removing the temporary directory sometimes fails on windows
+ import warnings
+ errmsg = "failed deleting temporary file {:s} ({:s})"
+ warnings.warn(UserWarning(errmsg.format(path, repr(e))))
def array_from_yaml_file(filename):
import yaml
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
numpy
-nose2
+pytest
--- a/setup.py
+++ b/setup.py
@@ -95,8 +95,4 @@
'aubiocut = aubio.cut:main',
],
},
- test_suite = 'nose2.collector.collector',
- extras_require = {
- 'tests': ['numpy'],
- },
)