axw/gocov

If a package has no test files, the lines in that package are not added to the total line count.

chao1995 opened this issue · 10 comments

As described in the issue title.

Ideally, when I run gocov test ./... under a certain project folder, I want to see the reported total line numbers be the total lines to be covered in the project, no matter whether there is test file existing for a certain package or not.

However, this is not what gocov does for now, in my experiments. It seems that if there is no test file existing for a certain package, the line numbers in that package are not added to the total line number count. (please let me know if you are not able to replicate this result. :)

Also, in some circumstances, we don't want to add tests for some packages, for example, some packages are solely for testing purposes like mocks, testdata etc. If we do want to count lines no matter whether there is test file existing, we should also add an option to ignore packages. That would make the tool report the total line numbers correctly as I expect.

Thanks!

P.S. gocov is really an awesome and handy tool! It enables and empowers me to do my testing job! :)

axw commented

Ideally, when I run gocov test ./... under a certain project folder, I want to see the reported total line numbers be the total lines to be covered in the project, no matter whether there is test file existing for a certain package or not.

The way "gocov test ./..." is currently handled is a bit dumb/naive: it runs "go test -coverprofile=..." for each package that "./..." matches, independently, and them accumulates the results. Each independent coverage profile includes the data for only that package, because -coverpkg isn't passed to the go test command.

What I think we should do is include the coverage data for (transitively) imported packages too. So if you have

  • package ./A, with tests
  • package ./B, without tests
  • package ./A imports package ./B

then gocov test ./... should run the tests in package A, and that should include the coverage data for both A and the imported package B.

This would be achieved by passing -coverpkg <imported-packages> to each go test command execution. Adding a flag to exclude packages sounds fine to me; that would just have the effect of removing that package from the list passed to -coverpkg.

Would that satisfy you?

(This is what I wanted all along, but I never had the time/inclination to do it myself. I may bite the bullet and do it now, but if you feel up to contributing, I'd be happy for the help.)

P.S. gocov is really an awesome and handy tool! It enables and empowers me to do my testing job! :)

I'm very glad to hear that; thank you for saying so.

@axw Thanks for the quick response!

What I think we should do is include the coverage data for (transitively) imported packages too.

sorry, I think transitively imported packages doesn't 100% satisfy me. lol. I would like something that recursively reports the total lines in all packages (except the ignored ones).

(edit: "recursive" might not be the correct word to use. actually my idea is to line-count every go files except the ignored ones. even for those that are not imported or used in any ways.)

And I'm very much willing to contribute! Perhaps not today though, maybe in this weekend?

axw commented

@axw Thanks for the quick response!

It helps that we're in the same timezone :)

sorry, I think transitively imported packages doesn't 100% satisfy me. lol. I would like something that "recursively" reports the total lines in all packages (except the ignored ones).

I think we mean the same thing. I mean that if A imports B, and B imports C, then running "gocov test A" will show the coverage for A, B, and C.

And I'm very much willing to contribute! Perhaps not today though, maybe in this weekend?

Great. No rush on my side, so whenever you are able. I'll be happy to review and provide pointers as necessary.

Hi!

I think we need something similar, but let me know if this is a separate issue and I'll gladly create it.

Let's say we have 3 separate packages A, B and C, and we want to have the total coverage stats. All packages are independent.

If we only have tests for B and C, the output of gocov test A B C | gocov report will be something like:

?       A       [no test files]
ok      B       0.001s   coverage: 50.0% of statements
ok      C       0.001s   coverage: 100.0% of statements

B   functionX   100.00% (12/12)
B   functionY     0.00% (0/12)
B   ----------   50.00% (12/24)

C   functionZ   100.00% (12/12)
C   ----------  100.00% (12/12)

Total Coverage: 66.67% (24/36)

What we'd like is to see:

?       A       [no test files]
ok      B       0.001s   coverage: 50.0% of statements
ok      C       0.001s   coverage: 100.0% of statements

A   functionF     0.00% (0/12)
A   ----------    0.00% (0/12)

B   functionX   100.00% (12/12)
B   functionY     0.00% (0/12)
B   ----------   50.00% (12/24)

C   functionZ   100.00% (12/12)
C   ----------  100.00% (12/12)

Total Coverage: 50.00% (24/48)

Does that make sense?

axw commented

@jbblanchet yup, makes sense - that would be solved with the proposed change

This is a very old issue, but I would like to add that I resolved this for my project with
gocov test $(go list ./... | grep -v -E '/vendor/') -coverpkg=$(go list ./... | grep -v -E '/vendor/' | tr '\n' ',') | gocov-xml > cobertura.xml
This uses the xml output from the other project, but I suspect it would work for this project's report functionality as well. Note that the output is cluttered during the test running phase, but the generated xml file is correct.

@axw Can you pretty please merge this fix?

axw commented

@BryanLipscy42 this is just an issue, so there's nothing to merge. If you or anyone else would like to propose changes, please go ahead and I would be happy to review them.

@axw Thank you

axw commented

Having said that, the goal can now be achieved through the use of appropriate flags. IIRC, a long time ago it was not possible to run go test -cover ./..., so gocov had some code to work around that. At some point it became possible to run go test -cover with patterns.

Try this (substituting for the -coverpkg patterns): gocov test -coverpkg=a,b,c ./...

This has the same meaning as when running go test -cover directly:

  • Run the tests for all packages in ./...
  • Include the coverage for packages "a", "b", and "c"

I just tested this and confirmed it works, so I'm going to close this issue. Let me know if I missed something.