Skip to content

Possibility to avoid .coverage generation #374

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

Closed
njourdane opened this issue Dec 16, 2019 · 21 comments
Closed

Possibility to avoid .coverage generation #374

njourdane opened this issue Dec 16, 2019 · 21 comments

Comments

@njourdane
Copy link

With this command:

pytest --cov=app --cov-report=xml --junitxml $PYTEST_XML_PATH

I explicitly want to generate an xml file, but a .coverage file is also generated. It could be nice to have the possibility to don't generate this file, for instance with a --no-cov-file (or similar) option.

@nedbat
Copy link
Collaborator

nedbat commented Dec 16, 2019

Can you explain why you don't want the .coverage file? Or why you can't simply delete the file? pytest-cov should not be a replacement for all of your dev tools coordination.

@nedbat
Copy link
Collaborator

nedbat commented Dec 16, 2019

This is something that should be handled elsewhere. However you are running pytest, add a second command to delete the .coverage file if you don't need it.

@nedbat nedbat closed this as completed Dec 16, 2019
@njourdane
Copy link
Author

Can you explain why you don't want the .coverage file?

when I only want a report, like with the --cov-report=xml option.

Or why you can't simply delete the file?

It's just to make things easier and avoid to type 2 commands instead of one.

@nedbat
Copy link
Collaborator

nedbat commented Jan 17, 2020

@roipoussiere I am very reluctant to add more complexity to a pytest plugin to make it do more things than run tests. Pytest should run tests. If you want to produce coverage reports after running the tests, it seems reasonable to use another command. You can make those two commands more convenient by creating an alias, or writing a shell script, or a Makefile, or using tox, etc, etc.

This plugin is under-maintained and overly complicated. It doesn't make sense to add more to it that can be done elsewhere.

@ionelmc
Copy link
Member

ionelmc commented Jan 17, 2020

@roipoussiere you could implement your own pytest plugin to do this and more, it's not that hard.

@nedbat
Copy link
Collaborator

nedbat commented Jan 17, 2020

@roipoussiere BTW, this has more context: Proposal: pytest-cov should do less

@pohmelie
Copy link

pohmelie commented Apr 9, 2021

Faced with this on read-only filesystem in docker. It is because of root user and fast prototyping and I don't want root files in my source. I need only run tests and report coverage to stdout.

@em92
Copy link

em92 commented Sep 12, 2021

Faced with this on read-only filesystem in docker. It is because of root user and fast prototyping and I don't want root files in my source. I need only run tests and report coverage to stdout.

As workaround, use COVERAGE_FILE environment variable.
Example COVERAGE_FILE=/tmp/junk.coverage. Already tried /dev/null, it didn't work, 'cos pytest-cov tries to delete this file.

@mro-rhansen2
Copy link

I don't see how giving the tool an option that tells it not to leave behind unwanted state is adding responsibilities to the toolkit itself outside of it's currently stated responsibility. There doesn't seem to be very strong logic in the reasoning that the responsibility of pytest-cov is to produce a side effect on your filesystem.

The responsibility seems to be to handle code coverage reporting. To assert that file system side effects are an intrinsic artefact of such a responsibility is a fallacy. That is only true if your stated responsibility is to produce coverage reporting that a person may use at some arbitrary point in the future. If that isn't the case, then it is the side effect itself that represents unnecessary complexity in the grand scheme of things. You're spending cycles to do something that no one is asking you to do, and then asking others to spend cycles to remove the thing that they didn't want in the first place. This isn't at least a code smell to you?

It isn't a matter of dev tool orchestration - it is about employing a toolkit that is natively compatible with modern delivery pipelines where (ideally) everything is automated and people aren't really in the mix. If that isn't where pytest-cov is aiming to sit, then I can understand the reasoning behind the notion that such an option would complicate the tool's responsibility itself. As it stands now, I had to take a few extra, superfluous steps to ensure that this side effect doesn't cause issues throughout various phases of my project's SDLC. If that doesn't convince you that you have a design problem, then I don't really know what will =\

@nedbat
Copy link
Collaborator

nedbat commented May 5, 2022

everything is automated and people aren't really in the mix

I don't understand your situation. Some automated thing is running pytest, yes? We aren't saying that people should delete the .coverage file. We are saying that whatever runs pytest can also delete the unwanted file.

I understand your viewpoint that it seems sloppy to have a file created where none is wanted. I'm sympathetic to that view. But I hope you understand our view that options add complexity, that maintaining a package is real (unpaid) work, and that you have a tool available to you that solves your problem (delete the file).

Is there a technical obstacle to deleting the file? Or is this a philosophical debate?

@admo1
Copy link

admo1 commented Nov 23, 2022

Any update on this issue ? We need a way to run pytest on read-only filesystem.

@nedbat
Copy link
Collaborator

nedbat commented Nov 23, 2022

Any update on this issue ? We need a way to run pytest on read-only filesystem.

Did you try COVERAGE_FILE=/someplace/writable/.coverage?

@brendan-morin
Copy link

brendan-morin commented Jan 14, 2024

Since this seems to be at the top of google for this particular question (any without a repeatable answer - changes to COVERAGE_FILE did not appear to be respected in my case). Setting this in pyproject.toml, however, did the trick:

[tool.coverage.run]
data_file = 'somewhere/.coverage'

versions used (python 3.11):

coverage=7.4.0
pytest=7.4.4
purest-dov=4.1.0

@ModischFabrications
Copy link

Sorry to revive this, but I don't feel like rerouting the export somewhere else is a solution to the initial question. I would argue in favour of reopening this issue, especially with #337 in mind.

I can only agree with @pohmelie and @mro-rhansen2 . I only need the stdout of this plugin to check for coverage and don't want a .coverage file to be generated "as a side effect". I can't even open it without external tools, at which point I would rather export it as a json instead. It feels opiniated to ascend one export type over the others.

Generating only the files that are explicitly requested (similar to --cov-report json) would be perfect, but if that isn't something to agree on I would at least like an option to skip these files with --no-export or anything similar.

@nedbat
Copy link
Collaborator

nedbat commented Mar 30, 2024

The .coverage file is not an export of data. It is the data that is collected while your tests run. Then HTML, text, JSON, or XML reports are generated from that data. So it's not ascended over the other formats, it is central.

I'll re-ask the question:

Is there a technical obstacle to deleting the file? Or is this a philosophical debate?

@Brodan
Copy link

Brodan commented Jul 22, 2024

Just going to bump that I agree with many above that I think there should be a config flag to delete the .coverage file. In my case I only need to display coverage to my terminal. i understand that another command could be run afterwards, but a single command is easier and more convenient

@raulparada
Copy link

Making it more extreme for sake of argument: what if this wasn't one file but 100 spread across your project, would one still argue "it's on the user to do the cleanup (cause it's also possible for them)"?
All my sympathy and gratitude to the maintainers of course, but this argument is bonkers.

@webknjaz
Copy link
Member

webknjaz commented Oct 4, 2024

@raulparada it's just a simple git clean command 🤷‍♂️
You should be gitignoring these files anyway..

@raulparada
Copy link

Anyone can work around it sure, but it shouldn't be needed. Why not have the COVERAGE_FILE default be inside $TMPDIR for instance?

@nedbat
Copy link
Collaborator

nedbat commented Dec 5, 2024

Putting the file in $TMPDIR would mean that multiple projects would collide if running tests at the same time. That's not good.

You aren't going to convince anyone by creating a hypothetical of "imagine there were 100 files" and then suggesting a bad default. How do you manage the __pycache__ directories that are created in your directory?

@Morgan-Sell
Copy link

Morgan-Sell commented Dec 29, 2024

I support the earlier statements about not saving .coverage* file after tests are completed. I'm unable to delete all the .coverage* files after the tests are completed. I've tried using the following hook.

def pytest_sessionfinish(session, exitstatus):
    """
    Ensures .coverage files are removed after all tests are done.
    """
    print("\nCleaning up .coverage files after all tests...")

    try:
        # Remove any lingering .coverage files
        coverage_files = glob.glob(".coverage*")
        time.sleep(3)
        for file in coverage_files:
            if file.endswith(".coveragerc"):
                print(f"Skipping deletion of configuration file: {file}")
                continue
            try:
                os.remove(file)
                print(f"Deleted: {file}")
            except OSError as e:
                print(f"Failed to delete {file}: {e}")
    except Exception as e:
        print(f"pytest_sessionfinish encountered an error: {e}")
        

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

No branches or pull requests