I'm writing UT for this if condition:
if (a != null && a.x != null && a.y != null) {
//do things
}
Sonar says that it needs 6 cases to be covered 100% and my code already covered 4.
I want to now all the test cases here (6) to get 100% coverage
Based on the code that you have given I can see one test case for each of the following conditions -
a==null
a!=null && a.x==null
a!=null && a.y==null
a.x=valid value
a.y=valid value
The '//do things' part may contain logical decisions which may require additional tests. This is where probably the 6th test case is being identified by sonar.
Sonarqube defines "condition coverage" like so...
Condition coverage (branch_coverage): On each line of code containing some boolean expressions, the condition coverage answers the following question: 'Has each boolean expression been evaluated both to true and to false?'. This is the density of possible conditions in flow control structures that have been followed during unit tests execution.
There's two problems.
Condition coverage and branch coverage are different. Your code has just two branches.
You have to test all combinations in a condition.
All they seem to care is that each part has been true and false at least once: a is null, a is not null, a.x is null, a.x is not null, a.y is null, a.y is not null. Maybe that's how they got six?
But that is not condition coverage. You can do it in two passes, everything true, and everything false.
You need to test every combination of a, a.x, and a.y being null and not null. This would be 2^3 or 8.
However, a false will short circuit the && operator so there's no need to go further once you hit a false.
a != null
a.x != null
a.y != null
F
any
any
T
F
any
T
T
F
T
T
T
That's four.
Related
As a follow-up to my previous question (Does overriding the operator == for a class automatically override the operator !=),
is there a scenario, where you would override the == and != operators to not be the negation of each other,
where the negation would be defined as:
(!(a == b)) == (a != b)
or
(a == b) == (!(a != b))
No, in a broad sense. Stepanov would say that if you don’t follow this rule of logic then you get what you deserve. That is why in C++20 they will be by default defined by each other just like he wanted.
In practice, yes, there are at least two scenarios.
NaN (not-a-number) in IEEE floating point numbers. Two NaN are different and not not equal at the same time.
As noted in the comment. The logical inconsistency is not exactly between == and !=, but it is related: you can do a = b; assert( a != b); or have assert( a != a ).
Expression constructs, aka expression templates, aka DSL. == and != create two independent expressions. Logically, they should be still be opposites but not in the sense that they are simple Boolean values. Take a look at Boost.Phoenix or Boost.Spirit. These libraries wouldn’t be possible if the language forces to return bools for these operations and one as the negation of the other.
In both cases you can reinterpret the situation to "restore" the logical rule. For example 1) you can say that once there is a NaN in your system the program is not in a logical state anymore. 2) you can say that the "expression" a != b should be also generated by !(a == b) even if they are not immediately bools.
So, even if the language lets you, you shouldn’t play with the rules of logic.
There is also the myth that supposedly sometimes checking for inequality should be faster than checking for equality or vise versa, as an excuse to implement them separately which can lead to logical inconsistency.
This is nonsense given the short circuiting of logical operations that are fundamental to C++ and should be of any system built on top of C++.
This happens all the time when working with databases, where a NULL value fails every comparison.
So, if you're implementing objects that model data that comes from a database, and you have an object that represents a NULL value, comparing something for equality with the NULL value will be false. Comparing it for inequality with a NULL value will also be false. Every kind of comparison will be false. And, the icing on the cake: comparing a NULL value for equality with another NULL value is also false.
Any scenarios where people decided to use === (triple equal) operator to check for equality indicate that if you assume
(!(a === b)) == (a != b)
then your == is not a negation of !=.
Note that I am not implying that there is a === operator in C++! I am illustrating a scenario, as was asked in the question.
I'm confused when code includes more than one NOT operator like:
if (!x != !0)
;
or similar. I can read it as: if NOT x is NOT equal to NOT zero,
but in my mind I'm totally confused about what it actually means.
Do you have any advice regarding this? I.e. how to understand such code, where to start reading or etc.
Another example:
if(!x == !1)
You can use truth table if you are not sure. For instance
x | 0 | x!=0 | !x | !0 | !x != !0
0 | 0 | 0 | 1 | 1 | 0
1 | 0 | 1 | 0 | 1 | 1
If have problems with many && and ||, use de Morgan's laws
to make things simpler, evaluate the operator! first then read L->R.
Things to remember:
!0 = 1 // true
!1 = 0 // false
so your condition can be simplified to:
if (!x != true) // !0
if (!x == false) // !1
Now, any non-zero value when inverted will be zero.
int x = 10;
!x // zero
Zero when inverted is true.
int x = 0;
!x // one
In C or C++, true is 1 and false is 0
I got troubled as well with simalar syntax when I started developing on PowerBuilder, then I realized I just need to imagine it as a nested if checking false.
For example !x become if(x)=false so it makes more clear that is true when x is false or zero.
In C 0 is false, whatever is not zero is true.
In the same logic !1 is always false and !0 is always true, despite I cannot see the reason to type it in this confusing way, maybe the code you are looking at is coming out from a sort of automatic generator / converter.
First take a look at operator precedence. You will see that logical operators like ! take precedence over relational operators like !=.
Secondly, what is !0 - this suspiciously sounds like there is an implicit conversion from int to bool there - otherwise !0 would make no sense at all.
In your example, you need to evaluate the logical operators first (i.e. !x and !0), then check if they are not equal !=. That said, this kind of code is really bad as it is really hard to read - avoid writing code like this, if possible (and consider refactoring it - while covered by unit tests - if you encounter it in "the wild")
I assume that the question is about C, and therefore I will give the answer in C.
You need to know the precedence rules - the ! binds stronger than the !=. Therefore the expression can be clarified using parentheses as (!x) != (!0). Now, the next thing is to know what ! will do - the result will be 0 if the operand is non-zero, 1 if it is zero. Therefore, !0 can be constant-folded to 1.
Now we have (!x) != 1. Since the !x is 1 iff x is zero, the result of this entire expression will be 1 iff x is non-zero, 0 otherwise.
We can therefore reduce this expression into the more idiomatic double-negation: !!x. However, the if clause in itself tests whether the expression is non-zero, therefore the entire if statement can be changed to if (x) ; (and since the expression does guard only a null-statement, it can be elided altogether)
This kind of code is designed to trick you. Your brain have difficulty to process double-negation or triple negation (and you are not the only one).
You need to know what are the priority rules, and apply it:
(!x == !1) is equal to ((!x) == (!1))
If you see this kind of code during a code review, you should definitely highlight it, and ask for an update.
Please note that in C++ you can also use not instead of !. It can makes things easier to understand:
(!x == !1) is equal to ((not x) == (not 1))
In C and C++, a value of zero is considered "false", and a nonzero value is considered "true". But it can occasionally be confusing, and occasionally causes minor problems, that two different values can both be considered true even though they're, well, different.
For example, suppose you had a function is_rich() that told you whether a person was rich or not. And suppose you wrote code like this:
int harry_is_rich = is_rich("Harry");
int sally_is_rich = is_rich("Sally");
Now the variable harry_is_rich is zero or nonzero according to whether Harry is poor or rich, and sally_is_rich is zero or nonzero according to whether Sally is poor or rich.
Now suppose you're interested in knowing whether Harry and Sally are both rich, or both poor. Your first thought might be
if(harry_is_rich == sally_is_rich)
But wait. Since any nonzero value is considered "true" in C, what if, for some reason, the is_rich() function returned 2 when Harry was rich, and returned 3 when Sally was rich? That wouldn't be a bug, per se -- the is_rich() function perfectly meets its specification of returning nonzero if the person is rich -- but it leads to the situation that you can't write
if(harry_is_rich == sally_is_rich)
(Well, of course you can write it, but like any buggy code, it might not work right.)
So what can you do instead? Well, one possibility is to write
if(!harry_is_rich == !sally_is_rich)
You can read this as "If it's not the case that Harry is rich has the same truth value as not the case that Sally is rich". And, while it's obviously a little contorted, you can kind of convince yourself that it "means" the same thing.
And, although it's a little confusing, it has the advantage of working. It works because of the other confusing aspect of true/false values in C and C++.
Although, as I said, zero is considered false and any nonzero value is considered true, the built-in operators that generate true/false values -- the ones like &&, ||, and ! -- are in fact guaranteed to give you exactly 0 or 1. (That is, the built-in functions are significantly different that functions like is_rich() in this regard. In general, is_rich() might return 2, or 3, or 37 for "true". But &&, ||, and ! are guaranteed to return 1 for true, and 0 for false.)
So when you say !harry_is_rich, you'll get 0 if Harry is rich, and 1 if Harry is not rich. When you say !sally_is_rich, you'll get 0 if Sally is rich, and 1 if Sally is not rich. And if you say
if(!harry_is_rich == !sally_is_rich)
you'll correctly discover whether Harry and Sally are both rich, or both poor, regardless of what values is_rich() chooses to return.
One more thing, though. In all of this I've been considering integers (or other types that might have lots of values). But both C and C++ have bool types, that more succinctly represent true/false values. For a bool type, there are exactly two values, true and false (which are represented as 1 and 0). So for a bool type, you can't have a true value that's anything other than 1. So if the is_rich() function was declared as returning bool, or if you declared your variables as bool, that would be another way of forcing the values to 0/1, and in that case the condition
if(harry_is_rich == sally_is_rich)
would work fine. (Furthermore, when I said that operators like &&, ||, and ! are guaranteed to return exactly 1 or 0, that's basically because these operators don't "return" arbitrary integers, but instead "return" bools.)
See also the C FAQ list, question 9.2.
(Oh, wait. One more thing. The opposite of "rich" isn't necessarily "poor", of course. :-) )
I read some legacy code:
if ( 1 || !Foo() )
Is there any seen reason why not to write:
if ( !Foo() )
The two are not the same. The first will never evaluate Foo() because the 1 short-circuits the ||.
Why it's done - probably someone wanted to force entry in the then branch for debugging purposes and left it there. It could also be that this was written before source control, so they didn't want the code to be lost, rather just bypassed for now.
if (1 || !Foo() ) will be always satisfied. !Foo() will not even be reached because of short-circuits evaluation.
This happens when you want to make sure that the code below the if will be executed, but you don't want to remove the real condition in it, probably for debug purposes.
Additional information that might help you:
if(a && b) - if a is false, b won't be checked.
if(a && b) - if a is true, b will be checked, because if it's false, the expression will be false.
if(a || b) - if a is true, b won't be checked, because this is true anyway.
if(a || b) - if a is false, b will be checked, because if b is true then it'll be true.
It's highly recommended to have a macro for this purpose, say DEBUG_ON 1, that will make it easier to understand what the programmer means, and not to have magic numbers in the code (Thanks #grigeshchauhan).
1 || condition
is always true, regardless whether the condition is true or not. In this case, the condition is never even being evaluated. The following code:
int c = 5;
if (1 || c++){}
printf("%d", c);
outputs 5 since c is never incremented, however if you changed 1 to 0, the c++ would be actually called, making the output 6.
A usual practical usage of this is in the situation when you want to test some piece of code that is being invoked when the condition that evaluates to true only seldom is met:
if (1 || condition ) {
// code I want to test
}
This way condition will never be evaluated and therefore // code I want to test always invoked. However it is definitely not the same as:
if (condition) { ...
which is a statement where condition will actually be evaluated (and in your case Foo will be called)
The question was answered properly - the difference is the right side of the or operation is short-circuited, suggesting this is debug code to force entry into the if block.
But in the interest of best practices, at least my rough stab at a best practice, I'd suggest alternatives, in order of increasing preference (best is last):
note: noticed after I coded examples this was a C++ question, examples are C#. Hopefully you can translate. If anyone needs me to, just post a comment.
In-line comment:
if (1 /*condition*/) //temporary debug
Out-of-line comment:
//if(condition)
if(true) //temporary debug
Name-Indicative Function
//in some general-use container
bool ForceConditionForDebug(bool forcedResult, string IgnoredResult)
{
#if DEBUG
Debug.WriteLine(
string.Format(
"Conditional {0} forced to {1} for debug purposes",
IgnoredResult,
forcedResult));
return forcedResult;
#else
#if ALLOW_DEBUG_CODE_IN_RELEASE
return forcedResult;
#else
throw new ApplicationException("Debug code detected in release mode");
#endif
#endif
}
//Where used
if(ForceConditionForDebug(true, "condition"))...
//Our case
if(ForceConditionForDebug(true, "!Foo()"))...
And if you wanted a really robust solution, you could add a repository rule to source control to reject any checked in code that called ForceConditionForDebug. This code should never have been written that way because it obviously doesn't communicate intent. It never should have been checked in (or have been allowed to be checked in) (source control? peer review?) And it should definitely never be allowed to execute in production in its current form.
I'm weighing the differences between
If[condition1 AND condition2, A, B]
and
If[condition1, If[condition2, A, B], B]
My thinking: the nested IFs will be faster.
My reasoning: By nesting the IFs, condition2 is evaluated only when condition1 is true. In what I'm doing, that means condition2 will be evaluated fewer times than in the first option above.
AND is the usual logical "and" (true if and only if both premises are true). By IF, I mean IF[condition, when condition is true, when condition is false].
I hope my question is not too ill-posed; I'm sure there are examples where the first option will run faster. I was just hoping that something is true in general.
Thank you.
Mathematica will short-circuit the evaluation of And and Or if the result becomes known before evaluating all the conditions.
You can see this by using a condition that (artificially) takes a long time:
Timing[If[False && (Pause[10]; True), True, False]]
Timing[If[False, If[(Pause[10]; True), True, False], False]]
and seeing that both return in a fraction of a second instead of in ten seconds.
Often (but not always), languages will have a feature called short circuited logic whereby the second operand in an AND condition will only be evaluated if the first is true (Also for an OR, the second will only be evaluated if the first is false). That would be dependent on the language, however.
I did some timing on
Nest[Defer#If[True, #] &, True, 300];
vs
If[True && << 298 >> && True, True];
which is total overkill but fun nonetheless. The nested If[] statements were three times slower than the If[] with 300 logical AND's. However, with the first True statement changed to False the tables are turned and the nested If[] statements are three times faster.
Are you asking about a specific language or just in general?
Many, but not all, languages have short circuit AND and ORoperators where they stop evaluation when they know the answer. For AND that means if the left side if false the answer is false and the right side does not need to be evaluated. For OR if the left side is true, then the answer is true and the rights side does not need to be evaluated.
For languages without short circute evaluation, you may get some speed improvement with nested ifs, because less work will have to be done. Whether that improvement is worth making the code harder to follow will depend on the situation.
So i'm here playing with PEX, it seems like a great idea.
However I am having a few problems, such as I have no way to test an equals method using parameter unit tests.
Maybe there is no way, maybe its a technique i haven't figured out yet.
Someone must have a decent idea.
If i was doing this in moq for instance, I would ensure that all the properties on both objects are read and do the comparisons myself to verify them. however I do not see how to use this approach with parametarised tests.
the problem is that I need to verify that method calls are made and properties are set / read in my business logic. I have no idea how to do this in PEX and there isnt really a massive amount of documentation out there.
There are some basic properties you can check that are related to the mathematical definition of equality:
does not crash: a == b never throws an exception
symmetric: (a == b) == (b == a)
reflexive: (a == a) == true
transitivity: (a == b) && (b == c) ==> a == c
given Func f, a == b ==> f(a) == f(b)
All of those are nice but definitely don't guarantee you that the equality works. but some point you will have specify as assertions what equality means for you. For example, that values of Property P should be equal, etc... Ultimately, you will end up with a second specification of the equality as tests.
Things get more interresting when you investiate the relationship with GetHashCode:
a.GetHashCode() !+ b.GetHashCode() ==> a != b
idempotent: a.GetHashCode() == a.GetHashCode()