Test Coverage for ENUM, Properties - Differences with default value, no values, and getters/setters
Maybe I am remembering wrong but I think things have changed and I missed the document. Back to basics with this question
For a class that has no methods and is just ENUMS:
public class muENUMS{ //does not even show up in test coverage not even as 0/0 lines
public enum anExample{
TryMe,
YetAgain
}
}
Salesforce says there are 0 lines to cover (in fact it never even appears in list of classes that can be covered) and during tests nothing is ever covered despite the enums being used.
Another example without enums:
public class coverageExample{ //Shows as 1 of 2 lines covered just by instantiation
public String thisLineNotCountedOrCovered;
public String thisLineCountedAndCovered = 'A String';
public String thisLineCountedAndNOTCovered {get; set;}
}
So my questions in the context of just instantiating the class):
- Has this always been the case?
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
In the other class it counts as 1 of 2 lines covered. The first property is not counted nor covered. The one with the getter / setter is counted and not covered.
- If it has not always been the case, can someone point me to the document that outlines the change? Google failed me.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered. If a line is just a property declaration without a getter / setter it is not even considered for coverage. If it is declared with a getter / setter it is counted and if not accessed it is not covered
I believe it is important to understand this as it really impacts the access the developer gives code. Many are used to just adding getters / setters even if they are not needed. In the above that decision creates unnecessary coverage requirements.
apex code-coverage
add a comment |
Maybe I am remembering wrong but I think things have changed and I missed the document. Back to basics with this question
For a class that has no methods and is just ENUMS:
public class muENUMS{ //does not even show up in test coverage not even as 0/0 lines
public enum anExample{
TryMe,
YetAgain
}
}
Salesforce says there are 0 lines to cover (in fact it never even appears in list of classes that can be covered) and during tests nothing is ever covered despite the enums being used.
Another example without enums:
public class coverageExample{ //Shows as 1 of 2 lines covered just by instantiation
public String thisLineNotCountedOrCovered;
public String thisLineCountedAndCovered = 'A String';
public String thisLineCountedAndNOTCovered {get; set;}
}
So my questions in the context of just instantiating the class):
- Has this always been the case?
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
In the other class it counts as 1 of 2 lines covered. The first property is not counted nor covered. The one with the getter / setter is counted and not covered.
- If it has not always been the case, can someone point me to the document that outlines the change? Google failed me.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered. If a line is just a property declaration without a getter / setter it is not even considered for coverage. If it is declared with a getter / setter it is counted and if not accessed it is not covered
I believe it is important to understand this as it really impacts the access the developer gives code. Many are used to just adding getters / setters even if they are not needed. In the above that decision creates unnecessary coverage requirements.
apex code-coverage
add a comment |
Maybe I am remembering wrong but I think things have changed and I missed the document. Back to basics with this question
For a class that has no methods and is just ENUMS:
public class muENUMS{ //does not even show up in test coverage not even as 0/0 lines
public enum anExample{
TryMe,
YetAgain
}
}
Salesforce says there are 0 lines to cover (in fact it never even appears in list of classes that can be covered) and during tests nothing is ever covered despite the enums being used.
Another example without enums:
public class coverageExample{ //Shows as 1 of 2 lines covered just by instantiation
public String thisLineNotCountedOrCovered;
public String thisLineCountedAndCovered = 'A String';
public String thisLineCountedAndNOTCovered {get; set;}
}
So my questions in the context of just instantiating the class):
- Has this always been the case?
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
In the other class it counts as 1 of 2 lines covered. The first property is not counted nor covered. The one with the getter / setter is counted and not covered.
- If it has not always been the case, can someone point me to the document that outlines the change? Google failed me.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered. If a line is just a property declaration without a getter / setter it is not even considered for coverage. If it is declared with a getter / setter it is counted and if not accessed it is not covered
I believe it is important to understand this as it really impacts the access the developer gives code. Many are used to just adding getters / setters even if they are not needed. In the above that decision creates unnecessary coverage requirements.
apex code-coverage
Maybe I am remembering wrong but I think things have changed and I missed the document. Back to basics with this question
For a class that has no methods and is just ENUMS:
public class muENUMS{ //does not even show up in test coverage not even as 0/0 lines
public enum anExample{
TryMe,
YetAgain
}
}
Salesforce says there are 0 lines to cover (in fact it never even appears in list of classes that can be covered) and during tests nothing is ever covered despite the enums being used.
Another example without enums:
public class coverageExample{ //Shows as 1 of 2 lines covered just by instantiation
public String thisLineNotCountedOrCovered;
public String thisLineCountedAndCovered = 'A String';
public String thisLineCountedAndNOTCovered {get; set;}
}
So my questions in the context of just instantiating the class):
- Has this always been the case?
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
In the other class it counts as 1 of 2 lines covered. The first property is not counted nor covered. The one with the getter / setter is counted and not covered.
- If it has not always been the case, can someone point me to the document that outlines the change? Google failed me.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered. If a line is just a property declaration without a getter / setter it is not even considered for coverage. If it is declared with a getter / setter it is counted and if not accessed it is not covered
I believe it is important to understand this as it really impacts the access the developer gives code. Many are used to just adding getters / setters even if they are not needed. In the above that decision creates unnecessary coverage requirements.
apex code-coverage
apex code-coverage
asked Nov 10 at 18:00
Eric
44.6k749115
44.6k749115
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Enums, interfaces, abstract methods, class-level declaration statements, class definitions, and debug statements never count for code coverage. Everything else does, including getters and setters, non-abstract methods (including the method signature), class-level assignments, and every non-debug line of code within a method always count for coverage.
Has this always been the case?
Yes, it's been this way since the inception of Apex, as far as I can remember.
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
Yes, it is a "class-level declaration statement," and thus has no coverage.
The first property is not counted nor covered.
It is a class-level declaration statement, and thus has no coverage, either.
The one with the getter / setter is counted and not covered.
This transforms the line from a class-level declaration statement to a method signature statement, thus requiring coverage.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered.
Yes, any time you use the =
operator, it is no longer just a declaration, it is an executable statement; you're assigning a value to a variable.
Yes, there are plenty of ways to make more work for oneself, and one of them is to unnecessarily declare default getters and setters. They are strictly only necessary for Visualforce attributes, and should not be used otherwise without a reason.
I think more to the point, it is up to each developer to learn all of the particular tools in which they use (in this case, the various parts of the Apex language) to write the most optimal code possible. Unfortunately, we have a lot of poorly written resources out there that newer developers prefer to read than to check the official documentation, which further perpetuates the cycle.
This problem is further exacerbated by the fact that the documentation team, despite doing a pretty good job at what they do, presume that the readers have a decent history in Java, C#, or another related language. The "obvious parts", like why { get; set; }
causes code coverage, isn't in the documentation. It's presumed that the reader knows that these are really methods, and all methods require code coverage.
Thank you for the time you took to answer this basic question. Believe it or not it was the first time I have had to do a class of enums.....
– Eric
Nov 10 at 22:12
add a comment |
I do not know the answer to (1).
Regarding (2), though, the rather terse summary from Salesforce is simply this:
Code coverage percentage is a calculation of the number of covered lines divided by the sum of the number of covered lines and uncovered lines. Only executable lines of code are included.
(Emphasis mine).
Declarations of variables, classes, enums, and interfaces are considered not to be executable as such.
However, both static initialization code and instance initialization statements are executable, as are getter and setting methods, even when synthesized by the compiler. (I agree that in the case of synthesized getters and setters this makes no sense).
Here's another example illustrating this:
public class TestQ238944 {
public enum myEnum {
OneValue,
Another
}
public myEnum initializedEnum = myEnum.OneValue;
public String testString = 'Test';
public Integer noValue;
public static Integer staticVar;
public static Integer staticWithValue = 100;
public Integer syntheticGetSet { get; set; }
public Integer explicitGet {
get { return 12; }
}
static {
staticVar = 200;
}
}
Starting out, we obtain no coverage at all, but note that Salesforce considers all of the initialization code (static and instance) coverable, as well as the property declarations. None of it has been executed.
Should we touch some static property of the class, we can cause all of the static initialization code to run:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
System.debug(TestQ238944.staticWithValue);
}
}
The debug shows 100
, as expected. The inline static initializer and the static initialization block are both run. The contrast with the first coverage snapshot shows that there is a meaningful "run" versus "not run" state for these lines. There's no difference in how inline static initialization is treated relative to static initializer blocks vis-a-vis code coverage.
As a further note on the executable nature of these lines, we can establish that they're in fact executed in a specific order: inline statics are run first, and static initializer blocks are run second. Changing the declarations like this
public static Integer staticVar;
public static Integer staticWithValue = staticVar * 2;
static {
staticVar = 200;
}
results in a NullPointerException
, but
public static Integer staticVar;
public static Integer staticWithValue = 100;
static {
staticVar = staticWithValue * 2;
}
works fine and yields the expected result.
Next, running the following test class to actually create an instance:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
TestQ238944 q = new TestQ238944();
}
}
results in this coverage:
Note that the static initialization code and the instance variable initializers are shown as covered.
I think the analogy with static initialization code might be helpful here - inline instance variable assignments are to the constructor as inline static assignments are to the static block. Constructors, like static blocks, are executed after inline instance variable assignments, and both are executed after all static code completes, e.g.,
public TestQ238944() {
noValue = staticVar * 2;
}
This is a long-winded way of saying, in essence, that these lines are coverable because they're executable, and they're executable because the Apex runtime does in fact run them just like they'd be run in some arbitrary other C/Java family language, rather than simply applying compiler magic to default variable values.
Thank you for the time you took to answer this basic question. Very helpful information.
– Eric
Nov 10 at 22:13
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "459"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f238944%2ftest-coverage-for-enum-properties-differences-with-default-value-no-values%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Enums, interfaces, abstract methods, class-level declaration statements, class definitions, and debug statements never count for code coverage. Everything else does, including getters and setters, non-abstract methods (including the method signature), class-level assignments, and every non-debug line of code within a method always count for coverage.
Has this always been the case?
Yes, it's been this way since the inception of Apex, as far as I can remember.
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
Yes, it is a "class-level declaration statement," and thus has no coverage.
The first property is not counted nor covered.
It is a class-level declaration statement, and thus has no coverage, either.
The one with the getter / setter is counted and not covered.
This transforms the line from a class-level declaration statement to a method signature statement, thus requiring coverage.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered.
Yes, any time you use the =
operator, it is no longer just a declaration, it is an executable statement; you're assigning a value to a variable.
Yes, there are plenty of ways to make more work for oneself, and one of them is to unnecessarily declare default getters and setters. They are strictly only necessary for Visualforce attributes, and should not be used otherwise without a reason.
I think more to the point, it is up to each developer to learn all of the particular tools in which they use (in this case, the various parts of the Apex language) to write the most optimal code possible. Unfortunately, we have a lot of poorly written resources out there that newer developers prefer to read than to check the official documentation, which further perpetuates the cycle.
This problem is further exacerbated by the fact that the documentation team, despite doing a pretty good job at what they do, presume that the readers have a decent history in Java, C#, or another related language. The "obvious parts", like why { get; set; }
causes code coverage, isn't in the documentation. It's presumed that the reader knows that these are really methods, and all methods require code coverage.
Thank you for the time you took to answer this basic question. Believe it or not it was the first time I have had to do a class of enums.....
– Eric
Nov 10 at 22:12
add a comment |
Enums, interfaces, abstract methods, class-level declaration statements, class definitions, and debug statements never count for code coverage. Everything else does, including getters and setters, non-abstract methods (including the method signature), class-level assignments, and every non-debug line of code within a method always count for coverage.
Has this always been the case?
Yes, it's been this way since the inception of Apex, as far as I can remember.
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
Yes, it is a "class-level declaration statement," and thus has no coverage.
The first property is not counted nor covered.
It is a class-level declaration statement, and thus has no coverage, either.
The one with the getter / setter is counted and not covered.
This transforms the line from a class-level declaration statement to a method signature statement, thus requiring coverage.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered.
Yes, any time you use the =
operator, it is no longer just a declaration, it is an executable statement; you're assigning a value to a variable.
Yes, there are plenty of ways to make more work for oneself, and one of them is to unnecessarily declare default getters and setters. They are strictly only necessary for Visualforce attributes, and should not be used otherwise without a reason.
I think more to the point, it is up to each developer to learn all of the particular tools in which they use (in this case, the various parts of the Apex language) to write the most optimal code possible. Unfortunately, we have a lot of poorly written resources out there that newer developers prefer to read than to check the official documentation, which further perpetuates the cycle.
This problem is further exacerbated by the fact that the documentation team, despite doing a pretty good job at what they do, presume that the readers have a decent history in Java, C#, or another related language. The "obvious parts", like why { get; set; }
causes code coverage, isn't in the documentation. It's presumed that the reader knows that these are really methods, and all methods require code coverage.
Thank you for the time you took to answer this basic question. Believe it or not it was the first time I have had to do a class of enums.....
– Eric
Nov 10 at 22:12
add a comment |
Enums, interfaces, abstract methods, class-level declaration statements, class definitions, and debug statements never count for code coverage. Everything else does, including getters and setters, non-abstract methods (including the method signature), class-level assignments, and every non-debug line of code within a method always count for coverage.
Has this always been the case?
Yes, it's been this way since the inception of Apex, as far as I can remember.
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
Yes, it is a "class-level declaration statement," and thus has no coverage.
The first property is not counted nor covered.
It is a class-level declaration statement, and thus has no coverage, either.
The one with the getter / setter is counted and not covered.
This transforms the line from a class-level declaration statement to a method signature statement, thus requiring coverage.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered.
Yes, any time you use the =
operator, it is no longer just a declaration, it is an executable statement; you're assigning a value to a variable.
Yes, there are plenty of ways to make more work for oneself, and one of them is to unnecessarily declare default getters and setters. They are strictly only necessary for Visualforce attributes, and should not be used otherwise without a reason.
I think more to the point, it is up to each developer to learn all of the particular tools in which they use (in this case, the various parts of the Apex language) to write the most optimal code possible. Unfortunately, we have a lot of poorly written resources out there that newer developers prefer to read than to check the official documentation, which further perpetuates the cycle.
This problem is further exacerbated by the fact that the documentation team, despite doing a pretty good job at what they do, presume that the readers have a decent history in Java, C#, or another related language. The "obvious parts", like why { get; set; }
causes code coverage, isn't in the documentation. It's presumed that the reader knows that these are really methods, and all methods require code coverage.
Enums, interfaces, abstract methods, class-level declaration statements, class definitions, and debug statements never count for code coverage. Everything else does, including getters and setters, non-abstract methods (including the method signature), class-level assignments, and every non-debug line of code within a method always count for coverage.
Has this always been the case?
Yes, it's been this way since the inception of Apex, as far as I can remember.
In the enum class no coverage data is calculated and the lines do not count toward to total lines to cover
Yes, it is a "class-level declaration statement," and thus has no coverage.
The first property is not counted nor covered.
It is a class-level declaration statement, and thus has no coverage, either.
The one with the getter / setter is counted and not covered.
This transforms the line from a class-level declaration statement to a method signature statement, thus requiring coverage.
It seems if a property is defaulted to a value it counts as a line of code to cover and gets covered.
Yes, any time you use the =
operator, it is no longer just a declaration, it is an executable statement; you're assigning a value to a variable.
Yes, there are plenty of ways to make more work for oneself, and one of them is to unnecessarily declare default getters and setters. They are strictly only necessary for Visualforce attributes, and should not be used otherwise without a reason.
I think more to the point, it is up to each developer to learn all of the particular tools in which they use (in this case, the various parts of the Apex language) to write the most optimal code possible. Unfortunately, we have a lot of poorly written resources out there that newer developers prefer to read than to check the official documentation, which further perpetuates the cycle.
This problem is further exacerbated by the fact that the documentation team, despite doing a pretty good job at what they do, presume that the readers have a decent history in Java, C#, or another related language. The "obvious parts", like why { get; set; }
causes code coverage, isn't in the documentation. It's presumed that the reader knows that these are really methods, and all methods require code coverage.
answered Nov 10 at 18:39
sfdcfox
246k11186423
246k11186423
Thank you for the time you took to answer this basic question. Believe it or not it was the first time I have had to do a class of enums.....
– Eric
Nov 10 at 22:12
add a comment |
Thank you for the time you took to answer this basic question. Believe it or not it was the first time I have had to do a class of enums.....
– Eric
Nov 10 at 22:12
Thank you for the time you took to answer this basic question. Believe it or not it was the first time I have had to do a class of enums.....
– Eric
Nov 10 at 22:12
Thank you for the time you took to answer this basic question. Believe it or not it was the first time I have had to do a class of enums.....
– Eric
Nov 10 at 22:12
add a comment |
I do not know the answer to (1).
Regarding (2), though, the rather terse summary from Salesforce is simply this:
Code coverage percentage is a calculation of the number of covered lines divided by the sum of the number of covered lines and uncovered lines. Only executable lines of code are included.
(Emphasis mine).
Declarations of variables, classes, enums, and interfaces are considered not to be executable as such.
However, both static initialization code and instance initialization statements are executable, as are getter and setting methods, even when synthesized by the compiler. (I agree that in the case of synthesized getters and setters this makes no sense).
Here's another example illustrating this:
public class TestQ238944 {
public enum myEnum {
OneValue,
Another
}
public myEnum initializedEnum = myEnum.OneValue;
public String testString = 'Test';
public Integer noValue;
public static Integer staticVar;
public static Integer staticWithValue = 100;
public Integer syntheticGetSet { get; set; }
public Integer explicitGet {
get { return 12; }
}
static {
staticVar = 200;
}
}
Starting out, we obtain no coverage at all, but note that Salesforce considers all of the initialization code (static and instance) coverable, as well as the property declarations. None of it has been executed.
Should we touch some static property of the class, we can cause all of the static initialization code to run:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
System.debug(TestQ238944.staticWithValue);
}
}
The debug shows 100
, as expected. The inline static initializer and the static initialization block are both run. The contrast with the first coverage snapshot shows that there is a meaningful "run" versus "not run" state for these lines. There's no difference in how inline static initialization is treated relative to static initializer blocks vis-a-vis code coverage.
As a further note on the executable nature of these lines, we can establish that they're in fact executed in a specific order: inline statics are run first, and static initializer blocks are run second. Changing the declarations like this
public static Integer staticVar;
public static Integer staticWithValue = staticVar * 2;
static {
staticVar = 200;
}
results in a NullPointerException
, but
public static Integer staticVar;
public static Integer staticWithValue = 100;
static {
staticVar = staticWithValue * 2;
}
works fine and yields the expected result.
Next, running the following test class to actually create an instance:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
TestQ238944 q = new TestQ238944();
}
}
results in this coverage:
Note that the static initialization code and the instance variable initializers are shown as covered.
I think the analogy with static initialization code might be helpful here - inline instance variable assignments are to the constructor as inline static assignments are to the static block. Constructors, like static blocks, are executed after inline instance variable assignments, and both are executed after all static code completes, e.g.,
public TestQ238944() {
noValue = staticVar * 2;
}
This is a long-winded way of saying, in essence, that these lines are coverable because they're executable, and they're executable because the Apex runtime does in fact run them just like they'd be run in some arbitrary other C/Java family language, rather than simply applying compiler magic to default variable values.
Thank you for the time you took to answer this basic question. Very helpful information.
– Eric
Nov 10 at 22:13
add a comment |
I do not know the answer to (1).
Regarding (2), though, the rather terse summary from Salesforce is simply this:
Code coverage percentage is a calculation of the number of covered lines divided by the sum of the number of covered lines and uncovered lines. Only executable lines of code are included.
(Emphasis mine).
Declarations of variables, classes, enums, and interfaces are considered not to be executable as such.
However, both static initialization code and instance initialization statements are executable, as are getter and setting methods, even when synthesized by the compiler. (I agree that in the case of synthesized getters and setters this makes no sense).
Here's another example illustrating this:
public class TestQ238944 {
public enum myEnum {
OneValue,
Another
}
public myEnum initializedEnum = myEnum.OneValue;
public String testString = 'Test';
public Integer noValue;
public static Integer staticVar;
public static Integer staticWithValue = 100;
public Integer syntheticGetSet { get; set; }
public Integer explicitGet {
get { return 12; }
}
static {
staticVar = 200;
}
}
Starting out, we obtain no coverage at all, but note that Salesforce considers all of the initialization code (static and instance) coverable, as well as the property declarations. None of it has been executed.
Should we touch some static property of the class, we can cause all of the static initialization code to run:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
System.debug(TestQ238944.staticWithValue);
}
}
The debug shows 100
, as expected. The inline static initializer and the static initialization block are both run. The contrast with the first coverage snapshot shows that there is a meaningful "run" versus "not run" state for these lines. There's no difference in how inline static initialization is treated relative to static initializer blocks vis-a-vis code coverage.
As a further note on the executable nature of these lines, we can establish that they're in fact executed in a specific order: inline statics are run first, and static initializer blocks are run second. Changing the declarations like this
public static Integer staticVar;
public static Integer staticWithValue = staticVar * 2;
static {
staticVar = 200;
}
results in a NullPointerException
, but
public static Integer staticVar;
public static Integer staticWithValue = 100;
static {
staticVar = staticWithValue * 2;
}
works fine and yields the expected result.
Next, running the following test class to actually create an instance:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
TestQ238944 q = new TestQ238944();
}
}
results in this coverage:
Note that the static initialization code and the instance variable initializers are shown as covered.
I think the analogy with static initialization code might be helpful here - inline instance variable assignments are to the constructor as inline static assignments are to the static block. Constructors, like static blocks, are executed after inline instance variable assignments, and both are executed after all static code completes, e.g.,
public TestQ238944() {
noValue = staticVar * 2;
}
This is a long-winded way of saying, in essence, that these lines are coverable because they're executable, and they're executable because the Apex runtime does in fact run them just like they'd be run in some arbitrary other C/Java family language, rather than simply applying compiler magic to default variable values.
Thank you for the time you took to answer this basic question. Very helpful information.
– Eric
Nov 10 at 22:13
add a comment |
I do not know the answer to (1).
Regarding (2), though, the rather terse summary from Salesforce is simply this:
Code coverage percentage is a calculation of the number of covered lines divided by the sum of the number of covered lines and uncovered lines. Only executable lines of code are included.
(Emphasis mine).
Declarations of variables, classes, enums, and interfaces are considered not to be executable as such.
However, both static initialization code and instance initialization statements are executable, as are getter and setting methods, even when synthesized by the compiler. (I agree that in the case of synthesized getters and setters this makes no sense).
Here's another example illustrating this:
public class TestQ238944 {
public enum myEnum {
OneValue,
Another
}
public myEnum initializedEnum = myEnum.OneValue;
public String testString = 'Test';
public Integer noValue;
public static Integer staticVar;
public static Integer staticWithValue = 100;
public Integer syntheticGetSet { get; set; }
public Integer explicitGet {
get { return 12; }
}
static {
staticVar = 200;
}
}
Starting out, we obtain no coverage at all, but note that Salesforce considers all of the initialization code (static and instance) coverable, as well as the property declarations. None of it has been executed.
Should we touch some static property of the class, we can cause all of the static initialization code to run:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
System.debug(TestQ238944.staticWithValue);
}
}
The debug shows 100
, as expected. The inline static initializer and the static initialization block are both run. The contrast with the first coverage snapshot shows that there is a meaningful "run" versus "not run" state for these lines. There's no difference in how inline static initialization is treated relative to static initializer blocks vis-a-vis code coverage.
As a further note on the executable nature of these lines, we can establish that they're in fact executed in a specific order: inline statics are run first, and static initializer blocks are run second. Changing the declarations like this
public static Integer staticVar;
public static Integer staticWithValue = staticVar * 2;
static {
staticVar = 200;
}
results in a NullPointerException
, but
public static Integer staticVar;
public static Integer staticWithValue = 100;
static {
staticVar = staticWithValue * 2;
}
works fine and yields the expected result.
Next, running the following test class to actually create an instance:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
TestQ238944 q = new TestQ238944();
}
}
results in this coverage:
Note that the static initialization code and the instance variable initializers are shown as covered.
I think the analogy with static initialization code might be helpful here - inline instance variable assignments are to the constructor as inline static assignments are to the static block. Constructors, like static blocks, are executed after inline instance variable assignments, and both are executed after all static code completes, e.g.,
public TestQ238944() {
noValue = staticVar * 2;
}
This is a long-winded way of saying, in essence, that these lines are coverable because they're executable, and they're executable because the Apex runtime does in fact run them just like they'd be run in some arbitrary other C/Java family language, rather than simply applying compiler magic to default variable values.
I do not know the answer to (1).
Regarding (2), though, the rather terse summary from Salesforce is simply this:
Code coverage percentage is a calculation of the number of covered lines divided by the sum of the number of covered lines and uncovered lines. Only executable lines of code are included.
(Emphasis mine).
Declarations of variables, classes, enums, and interfaces are considered not to be executable as such.
However, both static initialization code and instance initialization statements are executable, as are getter and setting methods, even when synthesized by the compiler. (I agree that in the case of synthesized getters and setters this makes no sense).
Here's another example illustrating this:
public class TestQ238944 {
public enum myEnum {
OneValue,
Another
}
public myEnum initializedEnum = myEnum.OneValue;
public String testString = 'Test';
public Integer noValue;
public static Integer staticVar;
public static Integer staticWithValue = 100;
public Integer syntheticGetSet { get; set; }
public Integer explicitGet {
get { return 12; }
}
static {
staticVar = 200;
}
}
Starting out, we obtain no coverage at all, but note that Salesforce considers all of the initialization code (static and instance) coverable, as well as the property declarations. None of it has been executed.
Should we touch some static property of the class, we can cause all of the static initialization code to run:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
System.debug(TestQ238944.staticWithValue);
}
}
The debug shows 100
, as expected. The inline static initializer and the static initialization block are both run. The contrast with the first coverage snapshot shows that there is a meaningful "run" versus "not run" state for these lines. There's no difference in how inline static initialization is treated relative to static initializer blocks vis-a-vis code coverage.
As a further note on the executable nature of these lines, we can establish that they're in fact executed in a specific order: inline statics are run first, and static initializer blocks are run second. Changing the declarations like this
public static Integer staticVar;
public static Integer staticWithValue = staticVar * 2;
static {
staticVar = 200;
}
results in a NullPointerException
, but
public static Integer staticVar;
public static Integer staticWithValue = 100;
static {
staticVar = staticWithValue * 2;
}
works fine and yields the expected result.
Next, running the following test class to actually create an instance:
@isTest
public class TestQ238944_Test {
@isTest
public static void doNothing() {
TestQ238944 q = new TestQ238944();
}
}
results in this coverage:
Note that the static initialization code and the instance variable initializers are shown as covered.
I think the analogy with static initialization code might be helpful here - inline instance variable assignments are to the constructor as inline static assignments are to the static block. Constructors, like static blocks, are executed after inline instance variable assignments, and both are executed after all static code completes, e.g.,
public TestQ238944() {
noValue = staticVar * 2;
}
This is a long-winded way of saying, in essence, that these lines are coverable because they're executable, and they're executable because the Apex runtime does in fact run them just like they'd be run in some arbitrary other C/Java family language, rather than simply applying compiler magic to default variable values.
answered Nov 10 at 18:38
David Reed
29.3k61746
29.3k61746
Thank you for the time you took to answer this basic question. Very helpful information.
– Eric
Nov 10 at 22:13
add a comment |
Thank you for the time you took to answer this basic question. Very helpful information.
– Eric
Nov 10 at 22:13
Thank you for the time you took to answer this basic question. Very helpful information.
– Eric
Nov 10 at 22:13
Thank you for the time you took to answer this basic question. Very helpful information.
– Eric
Nov 10 at 22:13
add a comment |
Thanks for contributing an answer to Salesforce Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f238944%2ftest-coverage-for-enum-properties-differences-with-default-value-no-values%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown