Multi checks in a try catch statement - is this okay? - c#

Is there anything wrong with doing something like this? I am basically just trying to assert that these elements exist and if not then return false:
public static bool IsAllDataPresent()
{
try
{
Driver.Instance.FindElement(By.Id("id-a");
Driver.Instance.FindElement(By.Id("id-b");
Driver.Instance.FindElement(By.Id("id-c");
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Is this is wrong then any help would be greatly appreciated. I am new to try catch.

If there is a method that tells you what you need to know without throwing, then call it.
If there is not, then you are in what I call a "vexing exception" situation. The best way out of that situation is to write the method that is missing.
public static bool IsPresent(string id)
{
try
{
Driver.Instance.FindElement(By.Id(id);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
And now your method is sensible:
public static bool IsAllDataPresent() =>
IsPresent("id-a") && IsPresent("id-b") && IsPresent("id-c");
Notice how when you write the correct abstraction, your method bodies get nice and concise.

For your specific question about checking multiple things and using try-catch... there's no problem with that, other than if it does fail, you're throwing away the exception which would tell you which of the things was missing.
In general, if you're expecting to find elements, you should wait for them to exist. If they exist right now, no waiting is done.
Example:
WebDriverWait wait = new WebDriverWait(Driver.Instance, new TimeSpan(0,0,5));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-a")));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-b")));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-c")));
return true;
If you don't wait, there's a risk you'll test the browser for an element which isn't there right now, but will exist in a few milliseconds time, and your script gives a premature, false negative, answer.

As you are trying to assert that these three elements exist and if not then return false you can optimize your code as per the code block below :
public static bool IsAllDataPresent()
{
if(Driver.Instance.FindElement(By.XPath("//*[#id='id-a' or #id='id-b' or #id='id-c']")).size() != 3)
{
Console.WriteLine("All the 3 elements exists")
return true;
}
else
{
Console.WriteLine("All the 3 elements doesn't exists")
return false;
}
}

Related

Assert element not exist without exception

I am trying to make an if statement so I can use my code in multiple situations.
When i try to assert displayed or enable I get in some situations an exception Iwebelement could not be found.
I want to make a statement that if element exist 'x' should happen and when element does not exist 'y' should happen.
As mentioned I tried Displayed, Enabled. I also tried asserFalse but that also didnt gave me the required result.
It was asked for code but I only need a if statement that let something true if element exist otherwise should skip it. When I do
if (element.Displayed)
{
}
But in some cases I get an exception and I dont want the exception
is this in a TestNG or JUnit test?
I would usually handle this in a normal case inside the if statement:
pseudocode:
if(exists(x)){
assertTrue(....);
}
else{
assertFalse(....);
}
Search for multiple elements and even if one exists (>0), then return true, otherwise, non of the elements with a specific By exist.
bool ElementExists()
{
return driver.FindElements(By.Id("your locator")).Count > 0;
}
Then just do
bool ElementExists(By locator)
{
TimeSpan originalWait = driver.Manage().Timeouts().ImplicitWait;
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(0);
bool exists = driver.FindElements(locator).Count > 0;
driver.Manage().Timeouts().ImplicitWait = originalWait;
return exists;
}
if(ElementExists(By.Id("your locator")))
{
//Do Stuff
}
else
{
//Do Stuff when element does not exist
}
Edit: Also reduce your implicit wait to 0 seconds so you don't wait long for your bool to return (the webdriver will wait for the element to appear as long as you told).
Your approach will work only when the element is displayed or exists , if not it will throw the exception and you are not handling that, so the script is failing for you.
You can create a method like below by handling the exception(I have written it in java , please make the required changes).
public static Boolean isElementDisplayed(WebDriver driver, By element) {
try {
driver.findElement(element).isDisplayed();
System.out.println("Element is displayed");
return true;
} catch (NoSuchElementException | ElementNotVisibleException e) {
System.out.println("Element not displayed");
return false;
}
}
And you can use the above method in you test cases 'n' number times like this.
if(isElementDisplayed(driver, By.xpath("locator")){
//do what you have to do if element is exists
}else{
//do what you have to do if element is not exists
}
Hope this will solve your problem

C# If Method Failed (Catch), DoSomething

Imagine, that u have a Method:
public void SometimesIFail(string text)
{
bool everythingOk = true;
try
{
//Anything
}
catch(Exception)
{
//Anything
everythingOk = false
}
}
Now I would like to do something like that:
foreach (String text in texts)
{
if(!SometimesIFail(text)) //If SometimesIFail() Failed (walked into Catch) Do the same for the next TEXT from the List: texts
{
SometimesIFail(text); // The Next Text - Until iterated through all the texts..
//FROM HERE ON, I HAVE A RECURSIVE CALL, THAT MEANS THAT THIS CODE, MUSTNT BE EXECUTED
//Any Code..
}
else
{
//Do Something
}
}
Whats the best way, to solve the problem?
EDIT:
After the test (Checking if it was ok), I want to do something, when it did not was OK:
foreach (String text in texts)
{
if(!SometimesIFail(text))
{
//HERE I will do SometimesIFail(text) for the next text (in foreach)
// And here is a Recursive Call which should be called, after the foreach iterated through all the texts..
}
}
Let the exception bubble up as far as possible. So remove the try/catch from the SometimesIFail method and catch the error closer to the user. Something like this:
try {
SometimesIFail();
// Do stuff
} catch {
// Tell the user an error has occurred.
}
And do consider exceptions for what they are called - they are exceptions and shouldn't be used for flow control. If there is a problem with your code that makes it crash sometimes, fix the problem instead.
I think without try catch if you solved your problem then it would be better option...
At first I thought I knew what you were looking for, then I read the comments in the code snippet, so now I'm not so sure. Here is my answer based on what I think you want. It looks like you want to check the SometimesIFail method for success and if it succeeds execute some code, if it fails you want to continue to the next iteration. Here's what I would do for that scenario:
// Don't use a void here, use a bool
public bool SometimesIFail(string text)
{
try
{
//Anything
return true;
}
catch(Exception)
{
//Anything
return false;
}
}
....
foreach (String text in texts)
{
if(SometimesIFail(text)) // Evaluates to true for success
{
// Do your success matching code
}
// There doesn't need to be an else condition if you're
// only passing to the next iteration
}
Try using this:
public bool SometimesIFail(string text)
{
try
{
//Anything
return false;
}
catch(Exception)
{
//Anything
return true;
}
}
foreach (String text in texts)
{
SometimesIFail(text);
if(SometimesIFail(text))
{
// returned true - exception was thrown
SometimesIFail(text);
}
else
{
//Do Something
}
}

Specifying that a function does not return in C#

Is there any way to tell the C# compiler that a function never returns? I'm running into the following problem. This is a boiled down version for simplicity.
public int myMethod()
{
try
{
return anythingHere();
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
'package.class.myMethod()' not all code paths return a value.
If not, is there a general way to frame this sort of thing other than inserting unreachable code? Having a 'return 0' or somesuch after the Exit just seems ridiculous to me. As far as I know there is no way that a function can return from an Environment.Exit call, so no return value is needed if that branch is taken (if it threw an exception the function still wouldn't need to have returned a value).
EDIT:
Maybe something like this?
public T MyExit<T>()
{
Environment.Exit(1);
return default(T);
}
Still not entirely satisfactory though.
C# does not support this.
In fact, it is impossible to do this in the general case.
Make the method void, and pass in an object that contains the 'anythingHere' type of information you need as an out type, so that it can be set, but the method itself won't actually return anything.
public void myMethod(out anythingObject)
{
try
{
anything = new anythingObject(stuff goes here);
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
I'm not sure if it's what you're looking for, but this would avoid unreachable code:
public int myMethod()
{
int retVal = 0;
try {
retVal = anythingHere();
} catch {
Environment.Exit(1);
}
return retVal;
}
It might be better to throw an exception than to call Environment.Exit. If someone else used your class, and their process suddenly shut down, they'd be pretty surprised. By throwing an exception you can at least explain why the problem happened.
At the top level entry point of your app (i.e., Main) you could then set up a global exception handler (AppDomain.UnhandledException) that handles all exceptions and calls Environment.Exit.
Make it a void, instead of an int.
public void myMethod(out int i)
{
try
{
i = anythingHere();
}
catch
{
Environment.Exit(1);
}
}

Catch and Continue

I want an extension method or generic method where I want code execution to continue even there is some exception and keep recording the exceptions in a list. This is an example what I tried
public void ValidateName()
{
if (_customer.Name.Length < 5)
throw new Exception("shortname");
}
public void ValidateAge()
{
if (_customer.Age < 5)
throw new Exception("short age");
}
internal void Validate()
{
this.CatchAndContinue(delegate()
{
this.ValidateName(); // throws exception and add to list
this.ValidateAge(); // but this should also execute
});
}
public void CatchAndContinue(Action action)
{
try
{
action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
For current class I can pass exceptions to ValidateName and ValidateAge method, but I want if we can do the way I want, with little change in validate() method body. I know semantically it sounds weired but I need lot of places to do this. Or if there is something better to achieve it
EDIT
This validation is simple example, not in all scenerio it will be validator only. By the way in this case I want to provide UI the list of errors and why throw, because when model constructed from DB (due to wrong data in DB) such objects should not be created. These are just examples of concern
Don't use exceptions for control flow.
Instead, your validate method should return a bool, and let the client of the validate method decide what to do. One step beyond that is return a ValidationResult with a ValidationStatus property that indicates success or failure and a Message property that records the reason that validation failed.
Yield / return may be useful to you.
http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx
Does it have to be exceptions?
To clarify:
internal IEnumerable<string> Validate()
{
if( _customer.Age > 5 ) { yield return "Too Old"; }
if( _customer.Name.Length < 3 ) { yield return "Not enough name characters"; }
}
// using it
IEnumerable<string> errors = myCustomer.Validate();
if( errors.Length > 0 ) {
// uh oh, print out the errors!
foreach( string error in errors ) {
MsgBox(error);
}
}
Instead of throwing exceptions in the Validate methods, I would add to the exceptions list and return a bool value indicating success/failure (return part is optional, add it only if you care about the status of validation).
Something like:
public void ValidateName()
{
if (_customer.Name.Length < 5) {
LogValidationFailure("shortName"); // you can add more params if needed
return; // or return false if you need it
}
// do normal business here
}
Not only is this cleaner, it is better performing since try/catch and exception throwing are expensive.

Basic C# question if - else

I was wondering if someone could tell me if this sample is correct please.
Please ignore the if statement i wrote it for demonstration purposes only.
basically what I want to know is, if I need to throw an exception in my else, is it right to have it return false then thrown an exception, like follows:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
else
{
return false;
throw new OutOfMemoryException();
}
}
OR - should I throw exception then return false outside else statement like this:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
else
{
throw new OutOfMemoryException();
}
return false;
}
Either of the following would make sense:
a) return the result of the test, don't throw:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException(j))
{
return true;
}
else
{
return false;
}
}
(Note that this example is overly verbose, and can be rewritten as:)
public bool test(Int j)
{
return !TestOnJThatcanThrowOutOfMemoryException(j)
}
b) throw if the test fails, do nothing otherwise:
public void test(Int j)
{
if(TestOnJThatcanThrowOutOfMemoryException(j))
{
throw new OutOfMemoryException();
}
}
In other words, make up your mind what that method is supposed to do - execute the test and return the result as a boolean value, or execute the test and throw when it fails.
When an exception occurs it does not execute the rest of the code in the method.
When a return statement is used it breaks the execution of the current method.
So you only need to call one of the two
i.e.
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
else
{
throw new OutOfMemoryException();
}
}
If you return false and then throw an exception than the exception will not be thrown. the method exits at the return statement.
if you throw an exception and then return false, then the exception will be thrown and caught in the appropriate catch block and your final return false will not execute.
So, if you want to throw an exception here, then throw the exception. If you want to return false here, return false.
In both cases, as is, only the first of the two will execute. Both return and throw cause execution to leave the function, so neither is technically correct.
In the first case, it will return, and the throw will never be called. In the second, the opposite is true (for the else block).
If you want an exception, throw it. Don't bother putting a return false anywhere.
The first example will never throw the exception as the return false ends the logic flow.
The second example the "return false;" will never be hit as either the return true; statement will be executed or the exception will be thrown.
In both of your examples you are doing something wrong. What do you want to achive?
In the first example throw statement will never be executed and in the second one return false won't be executed.
If you throw, the return statement won't get executed. All you need is:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
throw new OutOfMemoryException();
}
Your second option (just throwing the exception in the else) would be more correct. Note, though, that there is no code path to reach the return false; statement -- either the if is true, in which case true is returned, or its not, in which case an exception in thrown (thus aborting the code to the next-higher-level handler). So you don't really need it.
It appears that your attempt appears testing the value that comes to argument "int j".
The checking should fit in with a try catch,
try
{
// take a object as argument and try parse it to an int here
// or a TryParse will return a true/false if bool can return without exception.
int something = int.Parse(j);
}
catch (TestOnJThatcanThrowOutOfMemoryException e)
{
return true;
}
catch (OutOfMemoryException e)
{
// this will be hit if it isn't a TestOnJ.. exception
return false;
}
catch
{
// and here if not any of above
return false;
}
Though, i'm not sure if I ever would create a method which purpose would be just to force a specific kind of exception. Sorry if missunderstand you completely,
Go for the second option, but remove the "return false" statement at the end. Your method returns a boolean, so in case of an OutOfMemoryException (second if statement in your case), your method will not get a chance to pass a return value of false. But then this wont be an issue, if you handle the return value appropriately in the code which calls your method. A boolean is implicitly initialized to false, so in your calling function check if this method returned a true before you execute the remaining code.

Categories