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

Add tests to pysteps modules #32

Open
aperezhortal opened this issue Jan 15, 2019 · 14 comments
Open

Add tests to pysteps modules #32

aperezhortal opened this issue Jan 15, 2019 · 14 comments
Assignees
Labels
enhancement New feature or request
Projects

Comments

@aperezhortal
Copy link
Member

aperezhortal commented Jan 15, 2019

Now, the pySTEPS tests are mostly done by running the examples. It is a good idea to implement scripts that test different functions. A good and simple testing framework is pytest.

By doing so, we can test the library after any change that we want to commit.

One of the best advantages of implementing these tests is that we can set continuous integration service used to build and test projects hosted at GitHub, like Travis-CI. This is used for example in py-art.
Many of the CI servers support integration with github. By doing so, after each commit, the tests can be run under different environments and the results are visible in the commits tab in github (see pyart green checks for example ). Also, the pull request can be automatically tested before merging.

I created a branch with a script to test the interfaces as an example: https://github.com/aperezhortal/pysteps/tree/tests/test

To run this tests, execute pytest in the test folder (pytest package is needed).

The output looks like this:

============================= test session starts ==============================
platform linux -- Python 3.6.7, pytest-4.0.1, py-1.7.0, pluggy-0.8.0

test_interfaces.py . [100%]

=========================== 1 passed in 1.25 seconds ===========================
Process finished with exit code 0

@aperezhortal aperezhortal added the enhancement New feature or request label Jan 15, 2019
@aperezhortal aperezhortal self-assigned this Jan 16, 2019
@aperezhortal aperezhortal changed the title Add tests to pysteps functions Add tests to pysteps modules Jan 16, 2019
@wcwoo
Copy link

wcwoo commented Feb 15, 2019

pytest is a really useful tool to validate codes. While not familiar with Travis-CI, I found GitLab CI + pytest necessary for me to identify issues early.

I just ran pytest but got 2 errors. Is my new installation good for use?

(pysteps) swirls@swirls-VirtualBox:~/pysteps$ pytest --pyargs pysteps
======================================================================================== test session starts =========================================================================================
platform linux -- Python 3.6.7, pytest-4.2.1, py-1.7.0, pluggy-0.8.1
rootdir: /home/swirls/pysteps, inifile:
collected 7 items                                                                                                                                                                                    

tests/test_interfaces.py .F...F.                                                                                                                                                               [100%]

============================================================================================== FAILURES ==============================================================================================
____________________________________________________________________________________ test_extrapolation_interface ____________________________________________________________________________________

    def test_extrapolation_interface():
        """ Test the extrapolation module interface"""
    
        from pysteps import extrapolation
        from pysteps.extrapolation import semilagrangian
    
        method_getter = extrapolation.interface.get_method
    
        valid_names_func_pair = [('semilagrangian', semilagrangian.extrapolate)]
        invalid_names = ['euler', 'LAGRANGIAN']
>       _generic_interface_test(method_getter, valid_names_func_pair, invalid_names)

../.local/lib/python3.6/site-packages/pysteps-0.2-py3.6-linux-x86_64.egg/pysteps/tests/test_interfaces.py:49: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

method_getter = <function get_method at 0x7fce4d9776a8>, valid_names_func_pair = [('semilagrangian', <function extrapolate at 0x7fce4d9e6510>)], invalid_names = ['euler', 'LAGRANGIAN']

    def _generic_interface_test(method_getter,
                                valid_names_func_pair,
                                invalid_names):
        for name, expected_function in valid_names_func_pair:
            error_message = "Error getting '{}' function.".format(name)
>           assert method_getter(name) == expected_function, error_message
E           AssertionError: Error getting 'semilagrangian' function.
E           assert (<function initialize at 0x7fce4d9e6598>, <function extrapolate at 0x7fce4d9e6510>) == <function extrapolate at 0x7fce4d9e6510>
E            +  where (<function initialize at 0x7fce4d9e6598>, <function extrapolate at 0x7fce4d9e6510>) = <function get_method at 0x7fce4d9776a8>('semilagrangian')

../.local/lib/python3.6/site-packages/pysteps-0.2-py3.6-linux-x86_64.egg/pysteps/tests/test_interfaces.py:15: AssertionError
______________________________________________________________________________________ test_nowcasts_interface _______________________________________________________________________________________

    def test_nowcasts_interface():
        """ Test the nowcasts module interface"""
    
        from pysteps.nowcasts import steps
        from pysteps.nowcasts import extrapolation
        method_getter = pysteps.nowcasts.interface.get_method
    
        valid_names_func_pair = [('extrapolation', extrapolation.forecast),
                                 ('steps', steps.forecast)]
    
        invalid_names = ['extrap', 'step']
        _generic_interface_test(method_getter, valid_names_func_pair, invalid_names)
    
        # Test eulerian persistence method
        precip = numpy.random.rand(100, 100)
        velocity = numpy.random.rand(100, 100)
        num_timesteps = 10
        for name in ["eulerian", "EULERIAN"]:
>           forecast = method_getter(name)(precip, velocity, num_timesteps)
E           TypeError: eulerian_persistence() missing 1 required positional argument: 'num_timesteps'

../.local/lib/python3.6/site-packages/pysteps-0.2-py3.6-linux-x86_64.egg/pysteps/tests/test_interfaces.py:186: TypeError
================================================================================= 2 failed, 5 passed in 0.70 seconds =================================================================================

@aperezhortal
Copy link
Member Author

aperezhortal commented Feb 15, 2019

Hi @wcwoo. Thanks for pointing this out. This is not a problem with the installation itself. It is an issue with the same eulerian_persistence function that is being used in two different interfaces (change made in commit 7e0b82d). It is now solved (commit f8e4d3c).

@cvelascof
Copy link
Member

cvelascof commented Mar 6, 2019

Hi @aperezhortal,

I have started to work in a Travis CI configuration for pysteps.
See https://github.com/cvelascof/pysteps/blob/master/.travis.yml

So far, this configuration
https://travis-ci.org/cvelascof/pysteps/jobs/502472265/config
is able to install conda, all packages for pysteps, and pysteps itself.

However, when I try to import pysteps before to run any tests I got the following error message:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/travis/build/cvelascof/pysteps/pysteps/__init__.py", line 15, in <module>
    from . import motion
  File "/home/travis/build/cvelascof/pysteps/pysteps/motion/__init__.py", line 3, in <module>
    from .interface import get_method
  File "/home/travis/build/cvelascof/pysteps/pysteps/motion/interface.py", line 5, in <module>
    from pysteps.motion.vet import vet
  File "/home/travis/build/cvelascof/pysteps/pysteps/motion/vet.py", line 30, in <module>
    from pysteps.motion._vet import _warp, _cost_function
ModuleNotFoundError: No module named 'pysteps.motion._vet'

https://travis-ci.org/cvelascof/pysteps/jobs/502472265#L1488

I guess that there is something incorrect in the way that cython compiles vet but I cannot find what it is wrong. Any ideas?

@wcwoo
Copy link

wcwoo commented Mar 6, 2019

Maybe you need to make the module searchable from your python by, say, exporting PYTHONPATH=...?

@dnerini
Copy link
Member

dnerini commented Mar 6, 2019

[...]

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/travis/build/cvelascof/pysteps/pysteps/__init__.py", line 15, in <module>
    from . import motion
  File "/home/travis/build/cvelascof/pysteps/pysteps/motion/__init__.py", line 3, in <module>
    from .interface import get_method
  File "/home/travis/build/cvelascof/pysteps/pysteps/motion/interface.py", line 5, in <module>
    from pysteps.motion.vet import vet
  File "/home/travis/build/cvelascof/pysteps/pysteps/motion/vet.py", line 30, in <module>
    from pysteps.motion._vet import _warp, _cost_function
ModuleNotFoundError: No module named 'pysteps.motion._vet'

https://travis-ci.org/cvelascof/pysteps/jobs/502472265#L1488

I guess that there is something incorrect in the way that cython compiles vet but I cannot find what it is wrong. Any ideas?

This seems related to the problem discussed in Issue #40.

@wcwoo
Copy link

wcwoo commented Mar 6, 2019

I forgot that I raised that issue. :)

@cvelascof
Copy link
Member

Yes. Thanks. That did the trick. Running the tests from ~ fixed it.

https://travis-ci.org/cvelascof/pysteps/builds/502524712
Build Status

I will do a merge request soon.

@cvelascof cvelascof mentioned this issue Mar 6, 2019
@dnerini dnerini pinned this issue Apr 7, 2019
@dnerini dnerini added this to the Achieve 50% code coverage milestone Apr 17, 2019
@cvelascof
Copy link
Member

cvelascof commented May 27, 2019

@aperezhortal, @dnerini have you tried to run the test_motion outside of Travis? I mean in your own computer. In my case, test_motion is taking so much time to run. It passes but in comparison with the other tests is sooooo slow.
I recall that it used to be as fast as the other tests.
Any ideas why it change ?

@dnerini
Copy link
Member

dnerini commented May 27, 2019

Yes, I run the tests locally on my computer and it is true that test_motion takes some time, mostly because it has to compute multiple times VET and make sure that it converges to the right solution (by increasing the number of iterations).

But are you sure that is used to be faster?

Perhaps one way to speed up the test could be to reduce the dimension of the domain (e.g. upscaling the reference field).

@aperezhortal
Copy link
Member Author

@cvelascof, that test indeed takes some time. I will test upscaling the reference fields as @dnerini suggested to speed up the tests. Hopefully, it will be straightforward.

@cvelascof
Copy link
Member

@aperezhortal thanks. that would be nice to have.
Checking new uni-tests is taking too long now.

@aperezhortal
Copy link
Member Author

@cvelascof @dnerini, I tried upscaling the domain by 2, but the quality of the VET field was much lower. It converges to a local minimum...
To speed up the tests, I only left only one VET test and commented out the others.

This is a temporary patch, while I look for a way to optimize the _vet module. ( 24e4f8a )

@dnerini
Copy link
Member

dnerini commented Jun 20, 2019

Good news: we have (finally) achieved more than 50% coverage!

@dnerini dnerini removed this from the Achieve 50% code coverage milestone Jun 27, 2019
@dnerini dnerini unpinned this issue Jul 25, 2021
@dnerini
Copy link
Member

dnerini commented Jul 25, 2021

Let's set a 90% coverage goal for pysteps V2.

@dnerini dnerini added this to To do in pysteps-v2 via automation Jul 25, 2021
@dnerini dnerini mentioned this issue Jul 25, 2021
@dnerini dnerini moved this from To do to In progress in pysteps-v2 Jul 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
pysteps-v2
In progress
Development

No branches or pull requests

4 participants