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 new command modules test #1526

Merged
merged 25 commits into from
May 2, 2022
Merged

add new command modules test #1526

merged 25 commits into from
May 2, 2022

Conversation

mirpedrol
Copy link
Member

@mirpedrol mirpedrol commented Apr 25, 2022

Closes #1276

Add a new command nf-core modules test to run module tests locally.

PR checklist

  • This comment contains a description of changes (with reason)
  • CHANGELOG.md is updated
  • If you've fixed a bug or added code that should be tested, add tests!
  • Documentation in docs is updated

Copy link
Contributor

@fabianegli fabianegli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Júlia, it is great that you are working on an easy CLI for running tests! I made some comments and hope they help. Some are a bit out of scope for this PR (especially the comment about the path handling), but maybe they are still useful to you. Cheers and happy programming :-)

nf_core/modules/module_test.py Show resolved Hide resolved
nf_core/modules/module_test.py Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
nf_core/modules/module_test.py Show resolved Hide resolved
nf_core/modules/module_test.py Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
Comment on lines 51 to 52
self.module_dir = os.path.join("modules", *self.module_name.split("/"))
self.module_test_main = os.path.join("tests", "modules", *self.module_name.split("/"), "main.nf")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this kind of module structure/path handling could be done as part of ModulesRepo or in an util function. I think I saw a lot of such path handling in too many places.

@mirpedrol mirpedrol marked this pull request as ready for review April 28, 2022 08:02
@codecov
Copy link

codecov bot commented Apr 28, 2022

Codecov Report

Merging #1526 (aca376d) into dev (6052563) will decrease coverage by 0.33%.
The diff coverage is 49.29%.

@@            Coverage Diff             @@
##              dev    #1526      +/-   ##
==========================================
- Coverage   64.94%   64.61%   -0.34%     
==========================================
  Files          53       54       +1     
  Lines        6105     6178      +73     
==========================================
+ Hits         3965     3992      +27     
- Misses       2140     2186      +46     
Impacted Files Coverage Δ
nf_core/modules/module_test.py 48.27% <48.27%> (ø)
nf_core/__main__.py 51.36% <50.00%> (-0.04%) ⬇️
nf_core/modules/__init__.py 100.00% <100.00%> (ø)
nf_core/utils.py 79.75% <0.00%> (-3.25%) ⬇️
nf_core/modules/create.py 79.27% <0.00%> (ø)
nf_core/modules/install.py 59.09% <0.00%> (+0.95%) ⬆️
nf_core/modules/lint/main_nf.py 81.76% <0.00%> (+1.76%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6052563...aca376d. Read the comment docs.

Comment on lines 63 to 87
self._check_inputs()
self._set_profile()
self._run_pytests()

def _check_inputs(self):
"""Do more complex checks about supplied flags."""

# Get the tool name if not specified
if self.module_name is None:
if self.no_prompts:
raise UserWarning(
"Tool name not provided and prompts deactivated. Please provide the tool name as TOOL/SUBTOOL or TOOL."
)
modules_repo = ModulesRepo()
modules_repo.get_modules_file_tree()
self.module_name = questionary.autocomplete(
"Tool name:",
choices=modules_repo.modules_avail_module_names,
style=nf_core.utils.nfcore_question_style,
).ask()
module_dir = Path("modules") / self.module_name

# First, sanity check that the module directory exists
if not module_dir.is_dir():
raise UserWarning(f"Cannot find directory '{module_dir}'. Should be TOOL/SUBTOOL or TOOL")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This suggestion makes the code more expressive, merges the two separate User warnings into one, hopefully more useful one, and removes all path handling from this file (the Path import at the top can be removed, too). I am missing all the nice editor sugar here in GitHubs suggestion mode and hope it's still acceptable for black etc.

Suggested change
self._check_inputs()
self._set_profile()
self._run_pytests()
def _check_inputs(self):
"""Do more complex checks about supplied flags."""
# Get the tool name if not specified
if self.module_name is None:
if self.no_prompts:
raise UserWarning(
"Tool name not provided and prompts deactivated. Please provide the tool name as TOOL/SUBTOOL or TOOL."
)
modules_repo = ModulesRepo()
modules_repo.get_modules_file_tree()
self.module_name = questionary.autocomplete(
"Tool name:",
choices=modules_repo.modules_avail_module_names,
style=nf_core.utils.nfcore_question_style,
).ask()
module_dir = Path("modules") / self.module_name
# First, sanity check that the module directory exists
if not module_dir.is_dir():
raise UserWarning(f"Cannot find directory '{module_dir}'. Should be TOOL/SUBTOOL or TOOL")
self._check_module()
self._set_profile()
self._run_pytests()
def _check_module(self):
"""Ensure the module corresponding to the supplied module name is available."""
modules_repo = ModulesRepo()
modules_repo.get_modules_file_tree()
if self.module_name in modules_repo.modules_avail_module_names:
return
if self.no_prompts:
raise UserWarning(
f"The module name '{self.module_name}' is invalid. "
f"Valid module names are {modules_repo.modules_avail_module_names}."
)
self.module_name = questionary.autocomplete(
f"Chose a module:",
choices=modules_repo.modules_avail_module_names,
style=nf_core.utils.nfcore_question_style,
).ask()

@mahesh-panchal
Copy link
Member

I opened this in Gitpod and just ran a test:

$ nf-core modules test

                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 2.4.dev0 - https://nf-co.re


INFO     Press enter to use default values (shown in brackets) or type your own responses                                                                                                                                                                                                            module_test.py:60
? Tool name: fastqc
CRITICAL Cannot find directory 'modules/fastqc'. Should be TOOL/SUBTOOL or TOOL 

but it failed to find fastqc from the root of the directory.

@mirpedrol
Copy link
Member Author

I opened this in Gitpod and just ran a test:

$ nf-core modules test

                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 2.4.dev0 - https://nf-co.re


INFO     Press enter to use default values (shown in brackets) or type your own responses                                                                                                                                                                                                            module_test.py:60
? Tool name: fastqc
CRITICAL Cannot find directory 'modules/fastqc'. Should be TOOL/SUBTOOL or TOOL 

but it failed to find fastqc from the root of the directory.

Could it be because the command needs to be run from nf-core/modules ?
I'm sorry I am not familiar with the use of Gitpod so not sure how to test this command from the modules folder, but it's working for me locally though.

@mahesh-panchal
Copy link
Member

Ah, that was a silly mistake on my part. You're right. I need to clone modules into the repo too...

$ cd ..
$ git clone https://github.com/nf-core/modules.git
Cloning into 'modules'...
remote: Enumerating objects: 31564, done.
remote: Total 31564 (delta 0), reused 0 (delta 0), pack-reused 31564
Receiving objects: 100% (31564/31564), 97.04 MiB | 13.22 MiB/s, done.
Resolving deltas: 100% (16501/16501), done.
$ cd modules
$ nf-core modules test

                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 2.4.dev0 - https://nf-co.re


INFO     Press enter to use default values (shown in brackets) or type your own responses                                                                                                                                                                                                            module_test.py:60
? Tool name: fastqc
? Choose software profile Docker
INFO     Setting environment variable '$PROFILE' to 'docker'                                                                                                                                                                                                                                        module_test.py:111
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
INFO     Running pytest for module 'fastqc'                                                                                                                                                                                                                                                         module_test.py:124
================================================================================================================================================ test session starts =================================================================================================================================================
platform linux -- Python 3.9.7, pytest-7.1.2, pluggy-1.0.0
rootdir: /workspace/modules, configfile: pytest.ini
plugins: datafiles-2.0, cov-3.0.0, workflow-1.6.0
collecting ... 
collected 777 items                                                                                                                                                                                                                                                                                                  

fastqc single-end:
        command:   nextflow run ./tests/modules/fastqc/ -entry test_fastqc_single_end -c ./tests/config/nextflow.config -c ./tests/modules/fastqc/nextflow.config -c ./tests/modules/fastqc/nextflow.config
        directory: /tmp/pytest_workflow_ri5hifnx/fastqc_single-end
        stdout:    /tmp/pytest_workflow_ri5hifnx/fastqc_single-end/log.out
        stderr:    /tmp/pytest_workflow_ri5hifnx/fastqc_single-end/log.err
'fastqc single-end' done.

fastqc paired-end:
        command:   nextflow run ./tests/modules/fastqc/ -entry test_fastqc_paired_end -c ./tests/config/nextflow.config -c ./tests/modules/fastqc/nextflow.config -c ./tests/modules/fastqc/nextflow.config
        directory: /tmp/pytest_workflow_ri5hifnx/fastqc_paired-end
        stdout:    /tmp/pytest_workflow_ri5hifnx/fastqc_paired-end/log.out
        stderr:    /tmp/pytest_workflow_ri5hifnx/fastqc_paired-end/log.err
'fastqc paired-end' done.

tests/test_versions_yml.py sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss..ssssssssss [ 35%]
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 74%]
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss                                                                                                               [ 98%]
tests/modules/fastqc/test.yml ........                                                                                                                                                                                                                                                                         [100%] Keeping temporary directories and logs. Use '--kwd' or '--keep-workflow-wd' to disable this behaviour.


================================================================================================================================================== warnings summary ==================================================================================================================================================
../../opt/conda/lib/python3.9/site-packages/pytest_workflow/plugin.py:122: 489 warnings
  /opt/conda/lib/python3.9/site-packages/pytest_workflow/plugin.py:122: PytestRemovedIn8Warning: The (fspath: py.path.local) argument to YamlFile is deprecated. Please use the (path: pathlib.Path) argument instead.
  See https://docs.pytest.org/en/latest/deprecations.html#fspath-argument-for-node-constructors-replaced-with-pathlib-path
    return YamlFile.from_parent(parent, fspath=path)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=================================================================================================================================== 10 passed, 767 skipped, 489 warnings in 37.74s ===================================================================================================================================

@mahesh-panchal
Copy link
Member

Very well done. These commands are working nicely:

$ nf-core modules test fastqc

                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 2.4.dev0 - https://nf-co.re


INFO     Press enter to use default values (shown in brackets) or type your own responses                                                                                                                                                                                                            module_test.py:60
? Choose software profile Conda
...
nf-core modules test -p fastqc
$ nf-core modules test fastqc

                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 2.4.dev0 - https://nf-co.re


INFO     Press enter to use default values (shown in brackets) or type your own responses                                                                                                                                                                                                            module_test.py:60
? Choose software profile Docker
...
$ nf-core modules test --help

A comment on this one though:

$ nf-core modules test fastqc

                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 2.4.dev0 - https://nf-co.re


INFO     Press enter to use default values (shown in brackets) or type your own responses                                                                                                                                                                                                            module_test.py:60
? Choose software profile Singularity
INFO     Setting environment variable '$PROFILE' to 'singularity'                                                                                                                                                                                                                                   module_test.py:111
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
INFO     Running pytest for module 'fastqc'                                                                                                                                                                                                                                                         module_test.py:124
================================================================================================================================================ test session starts =================================================================================================================================================
platform linux -- Python 3.9.7, pytest-7.1.2, pluggy-1.0.0
rootdir: /workspace/modules, configfile: pytest.ini
plugins: datafiles-2.0, cov-3.0.0, workflow-1.6.0
collecting ... 
collected 777 items                                                                                                                                                                                                                                                                                                  

fastqc single-end:
        command:   nextflow run ./tests/modules/fastqc/ -entry test_fastqc_single_end -c ./tests/config/nextflow.config -c ./tests/modules/fastqc/nextflow.config -c ./tests/modules/fastqc/nextflow.config
        directory: /tmp/pytest_workflow_ihqvoq40/fastqc_single-end
        stdout:    /tmp/pytest_workflow_ihqvoq40/fastqc_single-end/log.out
        stderr:    /tmp/pytest_workflow_ihqvoq40/fastqc_single-end/log.err
'fastqc single-end' done.

fastqc paired-end:
        command:   nextflow run ./tests/modules/fastqc/ -entry test_fastqc_paired_end -c ./tests/config/nextflow.config -c ./tests/modules/fastqc/nextflow.config -c ./tests/modules/fastqc/nextflow.config
        directory: /tmp/pytest_workflow_ihqvoq40/fastqc_paired-end
        stdout:    /tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/log.out
        stderr:    /tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/log.err
'fastqc paired-end' done.

tests/test_versions_yml.py sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssFFssssssssss [ 35%]
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 74%]
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss                                                                                                               [ 98%]
tests/modules/fastqc/test.yml FFFFFFFF                                                                                                                                                                                                                                                                         [100%] Keeping temporary directories and logs. Use '--kwd' or '--keep-workflow-wd' to disable this behaviour.


====================================================================================================================================================== FAILURES ======================================================================================================================================================
__________________________________________________________________________________________________________________________________ test_ensure_valid_version_yml[fastqc single-end] __________________________________________________________________________________________________________________________________

workflow_dir = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_single-end')

    @pytest.mark.workflow(*_get_workflow_names())
    def test_ensure_valid_version_yml(workflow_dir):
        workflow_dir = Path(workflow_dir)
        software_name = workflow_dir.name.split("_")[0].lower()
        try:
            versions_yml_file = workflow_dir / f"output/{software_name}/versions.yml"
>           versions_yml = versions_yml_file.read_text()

tests/test_versions_yml.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/versions.yml'), encoding = None, errors = None

    def read_text(self, encoding=None, errors=None):
        """
        Open the file in text mode, read it, and close the file.
        """
>       with self.open(mode='r', encoding=encoding, errors=errors) as f:

/opt/conda/lib/python3.9/pathlib.py:1266: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/versions.yml'), mode = 'r', buffering = -1, encoding = None, errors = None, newline = None

    def open(self, mode='r', buffering=-1, encoding=None,
             errors=None, newline=None):
        """
        Open the file pointed by this path and return a file object, as
        the built-in open() function does.
        """
>       return io.open(self, mode, buffering, encoding, errors, newline,
                       opener=self._opener)

/opt/conda/lib/python3.9/pathlib.py:1252: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/versions.yml'), name = '/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/versions.yml', flags = 524288, mode = 438

    def _opener(self, name, flags, mode=0o666):
        # A stub for the opener argument to built-in open()
>       return self._accessor.open(self, flags, mode)
E       FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/versions.yml'

/opt/conda/lib/python3.9/pathlib.py:1120: FileNotFoundError

During handling of the above exception, another exception occurred:

workflow_dir = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_single-end')

    @pytest.mark.workflow(*_get_workflow_names())
    def test_ensure_valid_version_yml(workflow_dir):
        workflow_dir = Path(workflow_dir)
        software_name = workflow_dir.name.split("_")[0].lower()
        try:
            versions_yml_file = workflow_dir / f"output/{software_name}/versions.yml"
            versions_yml = versions_yml_file.read_text()
        except FileNotFoundError:
>           raise AssertionError(
                dedent(
                    f"""\
                    `versions.yml` not found in the output directory.
                    Expected path: `{versions_yml_file}`
    
                    This can have multiple reasons:
                    * The test-workflow failed before a `versions.yml` could be generated.
                    * The workflow name in `test.yml` does not start with the tool name.
                    """
                )
            )
E           AssertionError: `versions.yml` not found in the output directory.
E           Expected path: `/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/versions.yml`
E           
E           This can have multiple reasons:
E           * The test-workflow failed before a `versions.yml` could be generated.
E           * The workflow name in `test.yml` does not start with the tool name.

tests/test_versions_yml.py:33: AssertionError
__________________________________________________________________________________________________________________________________ test_ensure_valid_version_yml[fastqc paired-end] __________________________________________________________________________________________________________________________________

workflow_dir = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end')

    @pytest.mark.workflow(*_get_workflow_names())
    def test_ensure_valid_version_yml(workflow_dir):
        workflow_dir = Path(workflow_dir)
        software_name = workflow_dir.name.split("_")[0].lower()
        try:
            versions_yml_file = workflow_dir / f"output/{software_name}/versions.yml"
>           versions_yml = versions_yml_file.read_text()

tests/test_versions_yml.py:31: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/versions.yml'), encoding = None, errors = None

    def read_text(self, encoding=None, errors=None):
        """
        Open the file in text mode, read it, and close the file.
        """
>       with self.open(mode='r', encoding=encoding, errors=errors) as f:

/opt/conda/lib/python3.9/pathlib.py:1266: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/versions.yml'), mode = 'r', buffering = -1, encoding = None, errors = None, newline = None

    def open(self, mode='r', buffering=-1, encoding=None,
             errors=None, newline=None):
        """
        Open the file pointed by this path and return a file object, as
        the built-in open() function does.
        """
>       return io.open(self, mode, buffering, encoding, errors, newline,
                       opener=self._opener)

/opt/conda/lib/python3.9/pathlib.py:1252: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/versions.yml'), name = '/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/versions.yml', flags = 524288, mode = 438

    def _opener(self, name, flags, mode=0o666):
        # A stub for the opener argument to built-in open()
>       return self._accessor.open(self, flags, mode)
E       FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/versions.yml'

/opt/conda/lib/python3.9/pathlib.py:1120: FileNotFoundError

During handling of the above exception, another exception occurred:

workflow_dir = PosixPath('/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end')

    @pytest.mark.workflow(*_get_workflow_names())
    def test_ensure_valid_version_yml(workflow_dir):
        workflow_dir = Path(workflow_dir)
        software_name = workflow_dir.name.split("_")[0].lower()
        try:
            versions_yml_file = workflow_dir / f"output/{software_name}/versions.yml"
            versions_yml = versions_yml_file.read_text()
        except FileNotFoundError:
>           raise AssertionError(
                dedent(
                    f"""\
                    `versions.yml` not found in the output directory.
                    Expected path: `{versions_yml_file}`
    
                    This can have multiple reasons:
                    * The test-workflow failed before a `versions.yml` could be generated.
                    * The workflow name in `test.yml` does not start with the tool name.
                    """
                )
            )
E           AssertionError: `versions.yml` not found in the output directory.
E           Expected path: `/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/versions.yml`
E           
E           This can have multiple reasons:
E           * The test-workflow failed before a `versions.yml` could be generated.
E           * The workflow name in `test.yml` does not start with the tool name.

tests/test_versions_yml.py:33: AssertionError
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/test_fastqc.html' does not exist while it should
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'/tmp/pytest_workflow_ihqvoq40/fastqc_single-end/output/fastqc/test_fastqc.zip' does not exist while it should
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'fastqc single-end' exited with exit code '1' instead of '0'.
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/test_1_fastqc.html' does not exist while it should
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/test_2_fastqc.html' does not exist while it should
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/test_2_fastqc.zip' does not exist while it should
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'/tmp/pytest_workflow_ihqvoq40/fastqc_paired-end/output/fastqc/test_1_fastqc.zip' does not exist while it should
____________________________________________________________________________________________________________________________________________________ test session ____________________________________________________________________________________________________________________________________________________
'fastqc paired-end' exited with exit code '1' instead of '0'.
================================================================================================================================================== warnings summary ==================================================================================================================================================
../../opt/conda/lib/python3.9/site-packages/pytest_workflow/plugin.py:122: 489 warnings
  /opt/conda/lib/python3.9/site-packages/pytest_workflow/plugin.py:122: PytestRemovedIn8Warning: The (fspath: py.path.local) argument to YamlFile is deprecated. Please use the (path: pathlib.Path) argument instead.
  See https://docs.pytest.org/en/latest/deprecations.html#fspath-argument-for-node-constructors-replaced-with-pathlib-path
    return YamlFile.from_parent(parent, fspath=path)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
============================================================================================================================================== short test summary info ===============================================================================================================================================
FAILED tests/test_versions_yml.py::test_ensure_valid_version_yml[fastqc single-end] - AssertionError: `versions.yml` not found in the output directory.
FAILED tests/test_versions_yml.py::test_ensure_valid_version_yml[fastqc paired-end] - AssertionError: `versions.yml` not found in the output directory.
FAILED tests/modules/fastqc/test.yml::fastqc single-end::output/fastqc/test_fastqc.html::should exist
FAILED tests/modules/fastqc/test.yml::fastqc single-end::output/fastqc/test_fastqc.zip::should exist
FAILED tests/modules/fastqc/test.yml::fastqc single-end::exit code should be 0
FAILED tests/modules/fastqc/test.yml::fastqc paired-end::output/fastqc/test_1_fastqc.html::should exist
FAILED tests/modules/fastqc/test.yml::fastqc paired-end::output/fastqc/test_2_fastqc.html::should exist
FAILED tests/modules/fastqc/test.yml::fastqc paired-end::output/fastqc/test_2_fastqc.zip::should exist
FAILED tests/modules/fastqc/test.yml::fastqc paired-end::output/fastqc/test_1_fastqc.zip::should exist
FAILED tests/modules/fastqc/test.yml::fastqc paired-end::exit code should be 0
=================================================================================================================================== 10 failed, 767 skipped, 489 warnings in 14.39s ===================================================================================================================================

Is it possible to get nicer output than the stack trace? Something that points to the actual issue instead perhaps (in this case singularity is not installed)?

Can one pass the profile with pytest args? It's not clear.

@mirpedrol
Copy link
Member Author

Is it possible to get nicer output than the stack trace? Something that points to the actual issue instead perhaps (in this case singularity is not installed)?

This is more on the pytest side, but I have added a check to have a nicer error when the profile is not available.

Can one pass the profile with pytest args? It's not clear.

As far as I know, it's not possible to select the profile with arguments, it's selected with the env variable PROFILE.

@mahesh-panchal
Copy link
Member

mahesh-panchal commented Apr 29, 2022

Is it possible to generally suppress the stack trace?
This time I made a syntax error ( reads -> read in the input line ) in the fastqc module and ran it.

nf-core modules test fastqc

It prints out a stack trace that could be distracting.

It may be another issue, but if it's related, then perhaps point the user to look at the logs for the error, rather than displaying the symptom (e.g. FAILED filesX should exist).

@ggabernet
Copy link
Member

Hi @asthara10, I've just tested the command and it worked great for me, also the check for singularity being installed worked great for me now. I was just wondering if the test results could be displayed in a bit nicer summarized way in a similar way as for the nf-core modules lint test results:
Screenshot 2022-04-29 at 15 59 25

Or maybe this is hard here because it runs the pytests?

@mirpedrol
Copy link
Member Author

It is possible to reduce traceback and other reporting info from pytest with some arguments, for example --tb=no, --disable-warnings or --no-summary. I personally wouldn't add them by default, I think it's easier for the user to provide them as extra arguments if the long output is not needed, rather than having to go to the logs.

@mirpedrol
Copy link
Member Author

Regarding the nicer summary, right now it runs the pytest command, so the output comes from pytest. I am not sure if it can be modified afterwards, will have a look. Any ideas on how to do this are welcome :)

Copy link
Member

@mahesh-panchal mahesh-panchal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks awesome to me.
I think generally this quite functional, so 👍🏽 from me.
If it's feasible to have prettier output, then please try.

nf_core/modules/module_test.py Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
mirpedrol and others added 2 commits May 2, 2022 12:42
Co-authored-by: Gisela Gabernet <gisela.gabernet@gmail.com>
Co-authored-by: Fabian Egli <fabianegli@users.noreply.github.com>
Copy link
Contributor

@fabianegli fabianegli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for all your hard work @asthara10 !

Copy link
Member

@ewels ewels left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff! Haven't tried running it but the code reads well. Couple of minor comments but nothing substantial.


...

Attributes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm being picky, these are for the __init__() def really, so you could probably move them there. Unless this is some kind of Pythonic way of documenting stuff that I'm not aware of. Low prio though.

nf_core/modules/module_test.py Show resolved Hide resolved
nf_core/modules/module_test.py Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
nf_core/modules/module_test.py Outdated Show resolved Hide resolved
mirpedrol and others added 2 commits May 2, 2022 13:54
Co-authored-by: Phil Ewels <phil.ewels@scilifelab.se>
@ewels
Copy link
Member

ewels commented May 2, 2022

remove unnecessary libraryes

Would be good to add isort to the CI to handle these, been meaning to for a little while now. Would be a nice mini-PR follow on if you fancy it some time.

@mirpedrol mirpedrol merged commit e76ddeb into nf-core:dev May 2, 2022
@mirpedrol mirpedrol mentioned this pull request May 3, 2022
4 tasks
@mirpedrol mirpedrol deleted the modules_test branch May 17, 2022 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants