45

I'm running EclEmma, the Emma plugin for Eclipse, and the coverage report shows only partial coverage for an Enum I've defined, even though it shows the only value in the Enum as being covered. I'm assuming that there is a coverage gap for the implied methods that back the Enum, but I'm not quite sure.

For example, with this Enum, EclEmma highlights everything in green, except for the package declaration:

package com.blah;

public enum UserRole {
 HAS_ACCESS
}

If I pull up the coverage details for the class, I see this:

alt text

My question is, what is the best way to get 100% coverage on my Enum classes using EclEmma?

Javid Jamae
  • 8,741
  • 4
  • 47
  • 62
  • Does Emma not give you details about what you missed? That seems kind of odd. – Mark Peters Dec 22 '10 at 18:32
  • My 2 cents as I have been there before and I've seen my developers falling into this trap. Feels like you are more passionate (than desired) on reaching the 100% code coverage . This is just waste of time. Coverage tool reports should just be used to identify code improvement opportunities (or reducing technical dept) and should not be seen as MUST fixes. – Aravind Yarram Dec 22 '10 at 18:31
  • I agree, but if there is a simple way to get the coverage, I'm not going to ignore it. It is noise on a coverage report that I'd rather not have to filter through to get to real issues. I see it like not having any compiler warnings. I don't *have* to fix them all, but I don't want to filter through the less important ones to see that I have a new one that is pretty important. BTW, your answer is a non-answer and would have been better placed as a comment. – Javid Jamae Dec 22 '10 at 18:40
  • Agree...i wish i could move it to a comment now...i didn't think much if this is a comment ;-) – Aravind Yarram Dec 22 '10 at 18:44
  • 1
    I agree but you can only market your code/framework/whatever with the "it has 100% test coverage" sentence if it really has it. Sad but true. +1 – Adam Arold Oct 09 '13 at 18:57

3 Answers3

57

What you're seeing is some hidden bytecode being generated due to an enumeration.

To get rid of this issue, add a call to the values() and valueOf() methods in the enum, as mentioned earlier by Carl Manaster and Peter Lawrey.

deterb
  • 3,994
  • 1
  • 28
  • 33
  • 11
    I found that all I needed to do was make a single call to valueOf and I get 100% coverage. I thought I'd have to do more than that. – Javid Jamae Dec 30 '10 at 18:44
  • I was facing the same issue with `enum` and `classes` . I was able to resolve with case of `enum` . But my code coverage is not covering at `package` name. any suggestion would be helpful – Amol Bais Sep 27 '16 at 06:49
  • @Amolb your best bet is to ask a new question with all the relevant details. This one was explicitly about `enum`s, not `package`s. – deterb Sep 28 '16 at 08:44
  • I posted this solution to the same question: https://stackoverflow.com/a/26019028/1279002 – theINtoy Sep 14 '21 at 16:04
10

I agree with other posters that 100% code coverage can be misguided. But I have to admit to the satisfaction of getting 100% coverage on newly written core code.

Fortunately since all enums extend the same 'class', you can achieve your 100% with a little help from your friend reflection.

Just add the following static method in a class for your testers to call, using [EnumTypeName].class as a parameter.

  public static void superficialEnumCodeCoverage(Class<? extends Enum<?>> enumClass) {
    try {
      for (Object o : (Object[])enumClass.getMethod("values").invoke(null)) {
        enumClass.getMethod("valueOf", String.class).invoke(null, o.toString());
      }
    }
    catch (Throwable e) {
      throw new RuntimeException(e);
    }
  }

Assuming this static function was implemented in a class called "Shared", you would only need to include this line for each enum:

Shared.superficialEnumCodeCoverage(UserRole.class);

The key word is 'superficial'.

Darren
  • 111
  • 1
  • 3
2

We ran into a similar issue where the compiler generated methods on enumerations, like values(), typically were not being called in our test code. We worked around the problem by filtering the numbers of our enum objects out of our final report.

This is why I don't like using code coverage as a measure of completeness. When I think of a better metric, I'll let you know. :)

dhable
  • 2,879
  • 26
  • 35
  • 4
    Riffing off of this: perhaps you could write a generic test method that takes any enumeration and exercises its innate methods, just to get rid of the test report noise. It's a little risky - if you did this with everything, you'd have 100% test coverage and no test value - but I think it might meet your needs. – Carl Manaster Dec 22 '10 at 18:43
  • 3
    You can add a generic enum exerciser which calls values() and valueOf() which you can call with exerciseEnum(MyEnum.class) – Peter Lawrey Dec 22 '10 at 19:33
  • 1
    Thanks for the feedback. You're right about the reason for the coverage gap, but I don't think that ignoring Enums from the coverage report is the right way to go. – Javid Jamae Dec 30 '10 at 17:53
  • 2
    @Carl - You're right about the risk, it might be better to just directly test the methods for each enum, and not write a magic testing algorithm. – Javid Jamae Dec 30 '10 at 17:58