I am learning automation through Selenium (using Java programming language), and I am working on a test case. The last step in my case involves checking for the presence of a button an a page, by using findElement.By.xpath, and I have two versions of the step. With either version, my entire test case passes. However, the two versions each generate a different result by themselves. If I use the first version, with the int, I get "Write review button' does not exist" result. If I use the second version with the Boolean, I get "Write review button' exists!"
Since the test case passes, and with the second version generating the 'button exists' result, the problem cannot be with the xpath, so the issue with the second version getting the wrong result must be in the logic, yet I cannot tell what it is.
I tried rerunning the case multiple times to see if the problem is a glitch, but same result. I tried finding similar problems online, but cannot find anything that shows exactly how my problem is wrong.
int i = driver.findElements(By.xpath("//ul[#class='comments_advices']")).size();
if (i > 0) { System.out.println("'Write review button' exists!"); }
else { System.out.println("'Write review button' does not exist :( ");
}
boolean reviewButtonPresent = driver.findElements(By.xpath("//ul[#class='comments_advices']")).size() > 0;
if (reviewButtonPresent = true) { System.out.println("'Write review button' exists!"); }
else { System.out.println("'Write review button' does not exist :( "); }
The two instances of code you have are essentially the same and I see no reason for them to perform differently. My guess is that it's a timing issue. To make it behave more consistently, I would add a wait for the review button to appear. Since the button may not be there at times, it will throw a timeout exception so you will need to catch that to have a clean pass/fail for each run. To do this, I would use the function below that returns a boolean based on whether the element exists or not after waiting.
public static boolean elementExists(By locator, int timeout)
{
try
{
new WebDriverWait(driver, timeout).until(ExpectedConditions.presenceOfElementLocated(locator));
return true;
} catch (Exception e)
{
return false;
}
}
The above method tests for the "presence" of the element which means, does it exist in the DOM? If you want to make sure that it's actually visible (and not just present), you will want to change .presenceOfElementLocated() to .visibilityOfElementLocated().
Since you are new to Selenium, I would also recommend that you use a common library to do your validations like JUnit or TestNG. This will keep you from having to write your own custom code for validations and go through the process of finding bugs in your own custom code. Using JUnit, you would use
Assert.assertTrue("Verify the review button exists", elementExists(By.xpath("//ul[#class='comments_advices']"), 10));
See the JUnit docs.
There are some differences between the two blocks of code.
Apparently your first code block is logically correct which is as follows:
Code:
int i = driver.findElements(By.xpath("//ul[#class='comments_advices']")).size();
if (i > 0)
System.out.println("'Write review button' exists!");
else
System.out.println("'Write review button' does not exist :( ");
Output:
Write review button' does not exist
But it's not perfect, which I will explain later in this discussion.
Your second code block is a bit deceptive as it contains two logical operators in the same line and you have left it to the compiler to decide the Operator Precedence which is a clear deviation from the best practices. Possibly you were lucky as > had more precedence then = as in:
boolean reviewButtonPresent = driver.findElements(By.xpath("//ul[#class='comments_advices']")).size() > 0;
Solution
Ideally you need to:
Induce WebDriverWait for the visibilityOfAllElementsLocatedBy().
Evalute the size() through a if()
Sample Code:
if (new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//ul[#class='comments_advices']"))).size()>0)
System.out.println("'Write review button' exists!");
else
System.out.println("'Write review button' does not exist :( ");
Outro
Operator Precedence:
The operators in the following table are listed according to their precedence order. The closer to the top of the table an operator appears, the higher its precedence. Operators with higher precedence are evaluated before operators with relatively lower precedence. Operators on the same line have equal precedence. When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.
Related
Basically what I am asking is if It's possible to use the same variable in an if statement. Assigning it a new value halfway through the statement so that I don't have to initialize a new variable. I know this is probably horrible practice but I'm just curious if it can be done.
Here is the closest I feel that I have gotten so far:
if(curID + 1 != (curID = myScanner.nextInt())) {
System.out.print(j++);
break;
} else {
j++;
}
Sorry if this is a duplicate but I couldn't seem to find anything on it. More than likely because I forgot the technical terms.
Edit: Forgot to say that when I ran it I think it just used the new variable for both instances because the loop just broke. I could be wrong though.
There is no benefit to writing
if(curID++ != (curID = myScanner.nextInt())) {
versus
if(curID != (curID = myScanner.nextInt())) {
because the value stored back by ++ will be lost by the subsequent assignment. That you're thinking of doing this suggests you're fuzzy on what these things mean.
EDITED: per discussion in comments, you're also confused about the difference between prefix and postfix forms of ++. The postfix form evaluates to the value before the increment occurs.
But in any case, the whole thing is better written without the embedded assignment.
int prevId = curId;
curId = myScanner.nextInt();
if (prevId + 1 != curId) {
...
}
EDITED: added the + 1 to make the code work as discussed in the comments, as distinct from as originally written.
Your concern that you "don't have to initialize a new variable" is misplaced. Adding prevId costs almost nothing.
Writing it per my suggestion means you don't have to wonder about what Java may or may not do (though you can readily determine it from the online Java Language Specification), since it is now obvious. And that's the most important thing in programming.
So the code is rather complicated so ill try to do some neat pseudo code that covers the most important issues. I'm trying to parse a math expression. For example: 1-5*(-2)+3 = 14
The syntax that im using is:
expression = term OR term+expression OR term-expression
term = factor OR factor*term OR factor/term
factor = number OR -factor OR (expression)
I have written a piece of code which checks if an expression follows this syntax and it works well for checking the expressions but not for calculating it.
The pseudo code goes something like:
double readExpression()
number = readTerm()
if token == +
number2 = readExpression()
return number + number2
else if token == -
number2 = readExpression()
return number - number2
else
return number
...
(The code for readTerm() is identical to readExpression() in structure)
...
double readFactor()
if token == number
return number
else if token == -
number = readFactor()
return (-1)*number
else if token == (
number = readExpression()
return number
else raise exception
If I do the above calculation with this code it will give me a tree that looks like this:
So anyway, as you matematicians have figured out byt now, the expression should give 14 and not 8 as the tree suggests. I have noticed the that the problem arises when there are minus-signs in front of expressions since affect the whole right term i this problem whilst they should only affect the middle-term.
Ive been thinking like crazy for weeks and thought about solutions for this and looked at other codes and so on. Please dont toss a bunch of links on me if they are not really really simple and good since ive been browsing alot myself on tree traversals and other relevant topics.
What could i do at this stage? As I said, my program can tell if its right or wrong. So now I only need to parse a correct expression. Should I write another class for the parsing of the correct expression? Is it easier? Anyway I dont see how that code would look different than this.
Yes I would parse the equation, it just looks like you miss a key part of the order of operations/parsing. You need to include an additional check for double negatives.
The key factor here is that: In a situation with two identical operators then the left most operation is always carried out first.
First lets narrow down the issue.
This 1-5*(-2)+3 is equal to 1--10+3.
Now for our purposes lets assign a positive to the first operator because it helps illustrate a point:
1--10+3 is the same as +1--10+3
Now if we where to run +1--10+3 through a correct parser we would know that this -- is equal to + but only when used in the following situation:
+X--Y = X+Y
So now our parser has turned the original expression of 1--10+3 into 1+10+3 and we know that is equal to 14.
So all up: Yes you need a parser, but pay special attention to how +X--Y and X+Y work.
Also take a look at this answer: https://stackoverflow.com/a/26227947/1270000
I have run the PMD plugin in Eclipse against my code and I'm getting a high priority warning for code similar to the one shown below:
if(singleRequest !=null){
// do my work
}else{
// do my other work
}
PMD says `Avoid if (x != y) ..; else ..;
And the description of the error looks like this:
In an "if" expression with an "else" clause, avoid negation in
the test. For example, rephrase:
if (x != y) diff(); else same();
as:
if (x == y) same(); else diff();
Most "if (x != y)" cases without an "else" are often return
but I still can't understand the impact on my code. If someone could guide me with an example, I would appreciate it.
A number of PMD rules are more style opinions than correctness alerts. If you don't agree with this rule or the rule doesn't match your project's coding standards, you could consider suppressing warnings or even configuring PMD to enforce only the rules you like
PMD is a tool. PMD works based on heuristics. Someone decided upon this heuristic; that negative conditionals with else statements are not "good style".
However, in this case, as I have argued in my comments, the code posted is how I would write it. (In particular with x != null, but not exclusively to this construct.)
This is because I don't look at the conditional (excepting as it can be simplified; e.g. removing double-negatives as shown by Jim Kin) but rather I look at the logic of the branches or "flow".
That is, I place the positive branch first. In this case I contend that
if (x != null) {
doValid // positive branch
} else {
doFallback
}
is semantically equivalent to
if (isValid(x)) { // it looks like a "positive conditional" now
doValid // still positive branch
} else {
doFallback
}
and is thus positive branch first.
Of course, not all situations have such a "clear" positive flow, and some expressions might be expressed much easier in a negative manner. In these cases I will "invert" the branches - similar to what PMD is suggesting - usually with a comment stating the action at the top of the block if the positive branch/flow was reversed.
Another factor that may influence the conditional choice used is "immediate scope exiting" branches like:
if (x == null) {
// return, break, or
throw new Exception("oops!");
} else {
// But in this case, the else is silly
// and should be removed for clarity (IMOHO) which,
// if done, avoids the PMD warning entirely
}
This is how I consistently (a few occasional exceptions aside) write my code: if (x != null) { .. }. Use the tools available; and make them work for you. See Steven's answer for how PMD can be configured to a more suitable "taste" here.
It's a readability issue. Consider
if ( x != y )
{
}
else // "if x doesn't not equal y"
{
}
vs.
if ( x == y )
{
}
else // "if x doesn't equal y"
{
}
The latter example is more immediately identifiable. Mind you, I see nothing wrong with using negatives... it can make a lot more sense, consider
if ( x != null )...
The only reason I would avoid using the negative-case is if it resulted in double-negatives, which might be confusing.
e.g.
if (!checkbox.disabled) {
// checkbox is enabled
}
else {
// checkbox is disabled
}
Who reads your code? You do. The compiler does. Or maybe the assistant of the lecturer. A co-worker, who can't make difference between == and != ? Hope not.
I can only think negatives being bad in complex expressions. (Context being: at least for me. I know I've frustrated in debugging in my head while(!expr && !expr2 || expr3) { })
ch=getch(); if (ch!='a') is a pattern that is easily extended to
if (ch!='a' || ch!='b') which is always true, while sounding semantically correct.
From performance standpoint, it's best to sort the probabilities.
if (more_probable) {
....
unconditional_jump_to_end_of_block;
} else {
...
}
This choice should lead to better performance, as the there is no mis-prediction penalty in the more probable branch.
if (p && p->next) evaluated from performance standpoint gives poor results.
You have to avoid having "not equals" in the if condition. This is because when someone else looks at your code, there is a real possibility that the person might ignore the != and might jump to wrong conclusion about the logic of your program.
For your case, you may have to interchange the if logic with else logic and change != to ==
It's a balancing case of code readability vs. code organization. The warning is basically suggesting that it's confusing for people reading the code to navigate the negation of a negative.
My personal rule of thumb is, whatever you expect to be the "normal" case is what you should test for in the if. Consider:
if (x != y) {
// do work here...
} else {
throw new IllegalArgumentException();
}
In this situation I'd say that the important work is being done in the x != y case, so that's what you should test for. This is because I like to organize code so that the important work comes first, followed by handling for exceptional cases.
It's because "good style" says that if possible tests should be "positive", so:
if (singleRequest == null){
// do my other work
} else {
// do my work
}
Is easier to read because the test is "positive" (ie "equals" not "not equals"), and ultimately better readability leads to less bugs.
Edited
This is particularly the case with test like:
if (!str.equals("foo")) {
you can easily miss the ! at the front, but if you make the test positive, it's a lot cleaner.
The only time you should have a negative test is when there's no else block - then a negative test is unavoidable unless you have an empty true block, which itself is considered a style problem.
Not really an answer, but you can minimise the overall complexity and improve readability by returning or failing early and then continuing without indentation:
if (something == null) {
throw new IllegalArgumentException("something must not be null");
}
// continue here
Lets say that I have a lot of nested loops (3-4 levels) in a java method and each of these loops can have some if-else blocks. How can I check if all these things are working properly ? I am looking for a logical way to test this instead of using a brute force approach like substituting illegal values.
EDIT:
Can you also suggest some good testing books for beginners ?
The way I've always been taught basic testing is to handle around edge cases as much as possible.
For example, if you are checking the condition that variable i is between 0 and 10 if(i>0 &&i<10), what I would naturally test is a few values that make the test condition true, preferably near the edges, then a few on the edges that are a combination of true and false, and finally cases that are way out of bounds. With the aforementioned condition, I'd test 1,5 ,9, 0, 10, -1, 11, then finally an extremely large integer, both positive and negative.
This sort of goes against the "not substituting illegal values)", but I feel that you have to do that in order to ensure that your conditions fail properly.
EMMA is a code coverage tool. You run your unittests under EMMA and it will produce an HTML report with colorized source code showing which lines were reached and which were not. Based on that you can add tests to make sure you're testing all the various branches.
Each if/then in your code contains a boolean sub-expression as is the sub-expression used in a loop to decide whether to enter/rerun the loop. Predicate coverage should tell give you a good idea how thorough your tests are.
Wikipedia explains predicate coverage
Condition coverage (or predicate coverage) - Has each boolean sub-expression evaluated both to true and false? This does not necessarily imply decision coverage.
I believe that using debug is easiest way to find the mistake. You can find a full explanation about debug at this link: http://www.ibm.com/developerworks/library/os-ecbug/.
Also you can use this link: http://webster.cs.washington.edu:8080/practiceit/ for practising.
for example find input which will go through each of those loops with some values. then find input which will go through each branch of the if's. Then find input which will go through the loops with large or small or illegal values.
Set some input and output data. Make the calculations yourself.
Create a class to check if the output values match the ones you separately calculated.
Example:
input: Array(3,4,5,6);
output (sum of odd numbers) : 8
class TestClass{
//test case
//here you keep changing the array (extreme values, null etc..
public void test1(){
int[] anArray=new int[4];
anArray[0] = 3;
anArray[1] = 4;
anArray[2] = 5;
anArray[3] = 6;
int s=Calculator.oddSum(x);
if (s==8)
System.out.println("Passed");
else
System.out.println("Failed");
}
public static void main(){
TestClass t=new TestClass();
t.test1();
}
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What's the “condition” in C interview question?
Can something like this be done?
Code:
if(condition) {
printf("Hello")
} else {
printf("World");
}
Result: Hello World
What should be the condition to be used to make that possible ?
Please help. Thanks in advance.
No.
The else statement will only execute if the if didn't.
You can cheat to get this result in C:
#include <stdio.h>
#define else printf(" ");
int main()
{
int condition = 1;
if(condition) {
printf("Hello");
}
else {
printf("World");
}
}
Output:
Hello World
The only idea that comes into my mind is something like
if (printf("Hello") > 0)
printf("");
else
printf(" world");
but it's not the same thing, you can't execute both branches of an if/else: one of two is chosen.
The instructor is expecting you to fill in fork() as the condition. This is not general C code but Unix/POSIX code, and works by splitting the process into a parent process and child process. fork returns the child process id (a nonzero number, thus true) in the parent and 0 (false) in the child.
Another potential way to solve the problem, if you can add code elsewhere, is to write setjmp(jmp_buf) as the condition, and add a longjmp(jmp_buf, 1); after the conditional. However this seems to break the rules of the problem.
if/elses are either/ors. Either the if portion is executed or the else, but never both.
No, the statement is if ... else, not if ... and then also maybe. The condition is evaluated once, and the branch is chosen.
Its insane, but:
int test = 0;
String s = "";
switch (test) {
case 0: s += "Hello";
default: s += "World";
}
System.out.println(s);
Boolean type variables in both languages do not allow what you want to do. The whole point is that they must be one or the other.
To accomplish what you want, you probably need a custom type.
//This type allows for quantum weirdness
public class NotABool{
public boolean isTrue = false;
public boolean isFalse = false;
//Funky setMethod
void set(boolean value){
//...
}
}
NotABool nab = new NotABool();
if (NotABool.isTrue){
//Print "Hello"
}
if (NotABool.isFalse){
//Print "World"
}
Can you clarify what you're trying to accomplish?
The functionality you are describing looks more like the switch structures.
In Java, you can only switch on int and enum types, but in C, you can switch on string as well as int types.
It would look like so:
int i = 0;
switch (i) {
case 0:
System.out.print("Hello ");
case 1:
System.out.print("World!");
break;
}
The resulting output would be "Hello World!"
When i is 0, it matches the first case and executes the code until the next break; statement is found. If i was 1, it would only print out "World!".
In general, no, it's not possible. The way the if/else is translated to Java bytecode (and in either case, to machine code), one process will run exactly one of the two branches of the statement. If we didn't have if/else, we'd end up using goto to synthesize it, and that would look a lot like this:
if (condition) goto if_block;
else_block:
printf("World");
goto after_ifelse;
if_block:
printf("Hello");
after_ifelse:
As you can see, if the condition's true (even if it could somehow also be false!), the process will follow the 'if' branch and skip past the other. There's no way to get around this in a single process; any way would require changing the code of the program, or broken hardware (particularly RAM or CPU), or enough radiation to kill you. And every compiler and environment i know of treats if/else that way, though it's common to have the else case after the if (and invert the condition), which makes the (quite valid) assumption that any boolean condition that's not true is false.
Now with all that said...in C, it's semi possible, but not in the way you're thinking -- and not on every OS. On *nix systems, there's a system call usually called fork(), which allows one process to become two (thereby sidestepping the "one process will run exactly one branch" limitation).
if (fork())
printf("Hello");
else
printf("World");
But (1) this code has an inherent race condition -- both branches are now set to run, but either one could run before the other. You'd need to wait on the child process. And (2) this isn't a "condition", it's a function call. If you're not allowed to add code, then this should not be available as an answer.
Or you could do some evil macro stuff to translate the else into something else entirely. But anyone reading your code later would want to hunt you down and confiscate your keyboard, and that's if they're nice.