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

Coverage report not generated with custom app? #1841

Closed
oerp-odoo opened this issue Sep 2, 2024 · 4 comments
Closed

Coverage report not generated with custom app? #1841

oerp-odoo opened this issue Sep 2, 2024 · 4 comments
Labels
duplicate This issue or pull request already exists support A support question from a user

Comments

@oerp-odoo
Copy link

I want to run odoo tests to generate coverage report. But .coverage file is never generated.

I am running tests like this: coverage run /opt/odoo/venv/bin/odoo -d odoodb --stop-after-init --test-enable -u my_module -p 8055. I see tests run successfully, but it looks like coverage does not do anything.

odoo runs tests using unittest (standard python module).

Though if I use coverage with pytest for some pure python packages, then it does work, like coverage run /path/to/pytest --import-mode=importlib

I read in odoo forums, and people seemed to run it normally using same approach. But those are some old threads, so not sure if its applicable anymore

P.S. I run i with python 3.12 and inside docker container, Coverage.py, version 7.6.1 with C extension

@oerp-odoo oerp-odoo added the support A support question from a user label Sep 2, 2024
@nedbat
Copy link
Owner

nedbat commented Sep 4, 2024

Can you provide me with a runnable example so I can reproduce the problem?

@nedbat nedbat added the question Further information is requested label Sep 4, 2024
@oerp-odoo
Copy link
Author

@nedbat Hm, I tried this with official odoo images and it looks like it does generate report file. So I guess there is something on my end that conflicts with coverage as I use custom script to run odoo that handles extra things before it is run. So maybe that is the cause of it.

With standard docker images, you can run it like (but I can confirm it works using these images):

docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres:15
docker run -d -p 8069:8069 --name odoo --link db:db -t odoo:17.0
docker exec -it odoo bash
cd ~/
pip install coverage
odoo -d odoodb -i test_http --stop-after-init -p 8055 --db_host=db --db_password=odoo
/var/lib/odoo/.local/bin/coverage run /usr/bin/odoo -d odoodb -u test_http --test-enable --test-tags=test_http:TestHttpGreeting --stop-after-init -p 8055 --db_host=db --db_password=odoo

The way I run odoo, is roughly like this:

def exec_odoo():
    args = sys.argv[1:]
    start_cfg = load_odoo_start_config(DEFAULT_ODOO_START_CFG_PATH)
    # Expects path section to be defined.
    odoo_path = odookit.path.get_odoo_path(odoo_path=start_cfg["path"].get("odoo_path"))
    enterprise_path = odookit.path.get_enterprise_path(
        start_cfg["path"].get("enterprise_path")
    )
    if odookit.cmd.is_odoo_default_cmd(args):
        psql_args = _prepare_psql_check_args(args)
        _wait_for_psql(
            PSQL_TIMEOUT,
            *psql_args,
        )
        init_paths_str = os.environ.get("ODOO_INIT_PATHS", "")
        init_modules_str = os.environ.get("ODOO_INIT_MODULES", "")
        if init_paths_str or init_modules_str:
            paths = utilsx.parsing.split_strip_paths(init_paths_str, sep=",")
            modules = utilsx.parsing.split_strip(init_modules_str, sep=",")
            init_modules = odookit.path.prepare_init_modules(
                paths=paths, modules=set(modules)
            )
            if init_modules:
                args.append(f"--init={','.join(init_modules)}")
        if os.environ.get("ODOO_IGNORE_STANDARD_TESTS"):
            extra_tags = set()
            excluded_skip_tags = set()
            if "test" in start_cfg:
                if start_cfg["test"].get("included_test_tags_not_standard"):
                    extra_tags = set(
                        utilsx.parsing.split_strip(
                            start_cfg["test"].get("included_test_tags_not_standard"),
                            ",",
                        )
                    )
                if start_cfg["test"]["excluded_test_tags"]:
                    excluded_skip_tags = set(
                        utilsx.parsing.split_strip(
                            start_cfg["test"]["excluded_test_tags"], ","
                        )
                    )
            standard_paths = odookit.path.get_standard_addons_paths(
                odoo_path, enterprise_path=enterprise_path
            )
            test_tags_arg = odookit.cmd.prepare_test_tags_arg(
                paths=standard_paths,
                included_tags=extra_tags,
                excluded_tags=excluded_skip_tags,
            )
            if test_tags_arg:
                args.append(f"--test-tags={test_tags_arg}")
    odoo_bin = odookit.path.get_odoo_bin(odoo_path=str(odoo_path))
    os.execvp(odoo_bin, [odoo_bin] + args)  # nosec: B606


if __name__ == "__main__":
    exec_odoo()

Could it be that it is conflicting that script is run using os.execvp? Basically this script should run as normal odoo command, it just it prepares some extra arguments depending on environment variables..

@nedbat
Copy link
Owner

nedbat commented Sep 4, 2024

Yes, execvp is the issue here. You are spawning a subprocess that is not being measured by coverage.py. This is a long-standing issue: #43. You could adjust your script to include coverage in the command to execvp.

@oerp-odoo
Copy link
Author

@nedbat thanks, will try that.

@nedbat nedbat closed this as not planned Won't fix, can't repro, duplicate, stale Sep 5, 2024
@nedbat nedbat added duplicate This issue or pull request already exists and removed question Further information is requested labels Sep 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists support A support question from a user
Projects
None yet
Development

No branches or pull requests

2 participants