Pex: How to obtain all Path Conditions (PC)? - pex

In possible to force Pex/Intellitest to look for any possible path condition? I need pex shows me those PC. In pexfonfun/visualstudio 2015, i can see only few PC. For example, infeasible PC aren't shown.
In the next example i get 3 PC:
1) i != 12 && i != 15;
2) i == 15;
3) i == 12;
public static int foo(int i){
int a = 1;
if(i == 12)
a = 1;
if(i == 15)
a = 2;
return a;
}
Why i dont get "i != 12 && i == 15"?
Thanks! :)

>> Why i dont get "i != 12 && i == 15"?
IntelliTest tries to generate a compact test suite with high coverage.
For your example, notice that those 3 PC’s are enough to cover all blocks in your code. And therefore, IntelliTest decides that it can stop now.
Here are some relevant sections from the IntelliTest Reference Manual that explain this further:
To see how IntelliTest generates the data, please see here: https://www.visualstudio.com/en-us/docs/test/developer-testing/intellitest-manual/input-generation
To see when IntelliTest decides to emit a test case, please see here: https://www.visualstudio.com/en-us/docs/test/developer-testing/intellitest-manual/test-generation
Please let me know how we can improve this manual as well.
OK, now having said that, you can get IntelliTest to generate all PCs as well (although it is not going to exercise any new code paths).
Here is how to do that:
Do a "Run IntelliTest" on your method.
Select all the tests from the Exploration Results window, and hit the save button. Note that a new test project gets created.
Locate the PUT in this test project – it will be the method with the PexMethod attribute.
Condition IntelliTest to generate more PCs and emit tests by updating the PexMethod attribute as follows:
[PexMethod(TestEmissionFilter = Microsoft.Pex.Framework.Settings.PexTestEmissionFilter.All)]
Now do a "Run IntelliTest" again either on the PUT or on the product method, and you should see additional PCs (with "duplicate path" as the summary message). Experiment with EmissionFilter settings as you prefer.

Related

Enum wrong value

I'm new to solidity and I'm working through a course and I've set myself a project but I can't work out what I'm doing wrong as the data I'm logging is showing me the values are what's expected based on the enum positions.
I'm using compiler version ^0.6.6
I first set up my enum
enum VOTE_STATUS {CLOSED,OPEN}
VOTE_STATUS public voting_status = VOTE_STATUS.CLOSED;
I then have a voting function which I'm calling require in.
function addVote(uint _vote) public{
// Make sure voting is open
require(voting_status == VOTE_STATUS.CLOSED,"Voting hasn't opened yet");
}
In remix when I click the voting_status button on the left-hand side it returns the correct option, 0 = CLOSED, 1 = OPEN.
The issue is when I run the require statement above it seems to think the enum is always set to OPEN when the logging and solidity say differently.
I've confirmed this by setting the require statement to check for OPEN when the status is closed and this gives me the result I'm looking for
voting_status = VOTE_STATUS.CLOSED;
require(voting_status == VOTE_STATUS.OPEN,"Voting hasn't opened yet");
Any help with this would be massively appreciated
Thanks
I think that you may have a conceptual misunderstanding. A require statement works as follows:
require('condition', 'error msg');
What the require statement does is to check if the condition is met. If the condition is NOT met, it reverts the transaction and returns the error msg. So what you want to do is a require, which checks the voting_status to be OPEN, and if it is not, then it will throw the error "Voting hasn't opened yet".
So just to be clearer, your current require statement:
require(voting_status == VOTE_STATUS.CLOSED,"Voting hasn't opened yet");
Is actually checking if the voting_status is set to CLOSED. And if it is not, then it throws the msg error "Voting hasn't opened yet".
So maybe what you are looking for is:
require(voting_status == VOTE_STATUS.OPEN,"Voting hasn't opened yet");
Hope you find this information useful :)

QAF | How to fail a custom step?

I have created a custom step in which I'm doing some calculations. I need to pass or fail the step according to the outcome of the calculations. Presently step always shows pass in the report even when the calculation fails. Also, I would like to know how to pass the fail note to the report as I can see it is implemented in common steps.
I'm using QAF version 3.0.1
Below is a sample example:
#QAFTestStep(description = "I check quantity")
public static void iCheckQuantity() {
String product = getBundle().getString("prj.product");
Int availableStock = getBundle().getString("prj.aStock");
Int minStock = getBundle().getString("prj.minStock");
if (availableStock < minStock) {
// I want to fail the step here telling - minimum stock required to run the test for "product" is "minStock" but presenlty available is "availableStock"
}
}
I was able to figure out the answer.
import com.qmetry.qaf.automation.util.Validator.*;
assertFalse(true, "FAIL message here", "SUCCESS message here");
The below links were useful to understand more on verifications and also on different types of verifications/assertions available in QAF.
Refer:
https://qmetry.github.io/qaf/latest/assertion_verification.html
https://qmetry.github.io/qaf/latest/javadoc/com/qmetry/qaf/automation/util/Validator.html

Unpredictable behaviour with Selenium and jUnit

I am working on a website and trying to test it with Selenium and jUnit. I'm getting race conditions between the test and the site, despite my best efforts.
The front end of the site is HTML and jQuery. The back end (via AJAX) is PHP.
The site
I have two required text input fields (year and age), plus some others that I'm not changing in the tests that give problems. As soon as both text inputs are non-empty, an AJAX call is made to the back end. This will return 0+ results. If 0 results are returned, a results div on the screen gets some text saying that there were no results. If >0 results are returned, a table is written to the results div showing the results.
I don't want the site to wait until e.g. 4 digits' worth of year is entered before doing the AJAX call as it could be looking at ancient history (yes, really). So, as soon as both are non-empty the call should be made. If you type slowly, this means that entering e.g. 2015 will trigger calls for year=2, year=20, year=201 and year=2015. (This is OK.)
The test
I'm using page objects - one for the inputs and one for the output. At the start of the test, I wait for a prompt to be present on the screen (please enter some data) as that is generated by JavaScript that checks the state of the input fields - so I know that the page has loaded and JavaScript has run.
The wait for a prompt is made immediately after the page object is created for the output. This is the relevant method in the page object:
// Wait until the prompt / help text is displayed. Assumes that the prompt text always contains the word "Please"
public void waitForText() {
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("resultContainer"), "Please"));
}
The method for setting the year is
public void setYear(String year){
WebElement yearField = driver.findElement(By.id(yearInputId));
if (yearField == null) {
// This should never happen
Assert.fail("Can't find year input field using id " + yearInputId);
} else {
yearField.sendKeys(new String [] {year});
driver.findElement(By.id(ageInputId)).click(); // click somewhere else
}
}
and there's a corresponding one for age.
I have a series of methods that wait for things to happen, which don't seem to have prevented the problem (below). These do things like wait for the current result values to be different from a previous snapshot of them, wait for a certain number of results to be returned etc.
I create a driver for Chrome as follows:
import org.openqa.selenium.chrome.ChromeDriver;
// ...
case CHROME: {
System.setProperty("webdriver.chrome.driver", "C:\\path\\chromedriver.exe");
result = new ChromeDriver();
break;
}
The problem
Some of the time, things work OK. Some of the time, both inputs are filled in with sensible values by the test, but the "there are 0 results" message is displayed. Some of the time, the test hangs part-way through filling in the inputs. It seems to be fine when I'm testing with Firefox, but Chrome often fails.
The fact that there is unpredictable behaviour suggests that I'm not controlling all the things I need to (and / or my attempts to control things are wrong). I can't see that I'm doing anything particularly weird, so someone must have hit these kinds of issue before.
Is there a browser issue I'm not addressing?
Is there something I'm doing wrong in setting the values?
Is there something I'm doing wrong in my test choreography?
It could be that when you start typing, the script is still loading or that there's a pending Ajax call when you start handling the next field or validation.
You could try to synchronize the calls with a low level script :
const String JS_WAIT_NO_AJAX =
"var callback = arguments[0]; (function fn(){ " +
" if(window.$ && window.$.active == 0) " +
" return callback(); " +
" setTimeout(fn, 60); " +
"})();";
JavascriptExecutor js = (JavascriptExecutor)driver;
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);
js.executeAsyncScript(JS_WAIT_NO_AJAX);
driver.findElement(By.Id("...")).sendKeys("...");
js.executeAsyncScript(JS_WAIT_NO_AJAX);
driver.findElement(By.Id("...")).click();

Condition- assert using Selenium

I want to write a script which can detect this message " System is not responding to your request. Kindly try after sometime." as shown in the screenshot below. When this message comes up then I want verify and send mail to the development team.
Snippet which I wrote for verification purpose but it is not working fine for me, pls suggest some alternative:
String s1 = d1.findElementByXPath(".//*[#id='showSearchResultDiv']").getText();
System.out.println(s1);
Remember to be careful when writing code for automation. If the scenario doesn't always show up, you cannot try and find an XPath, because you can't getText() if the object (based on the XPath) doesn't exist first. You probably need a try/catch around your code, and then put the println inside the try. This scenario will occur quite frequently, so you may want to write your own framework on top of WebDriver to handle these use cases.
If that is not the issue. Put a try/catch around the code that is failing to capture what the exception is.
You should try to wait for your element to appear before examining its text:
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (d1.findElementByXPath(".//*[#id='showSearchResultDiv']").isDisplayed()) break; } catch (Exception e) {}
Thread.sleep(1000);
}
String s1 = d1.findElementByXPath(".//*[#id='showSearchResultDiv']").getText();
System.out.println(s1);
The exact code may be different, depending on the webpage you're testing (e.g. you should remove the 'fail' line if it's OK for the element not to appear every time.

Fail Webdriver test if element is present

I'm new to Webdriver and I'm wondering how do I make my test case fail if an element is present. Using the following code I can send an output that if the element id errorMessages is present an output will be displayed. Is there anyway I can make the test fail also?
if (driver.findElements(By.id("errorMessages")).size() != 0) {
System.out.println("Error..Warning Subscriber already exists ");
}
With TestNG you can simply use Assert.fail("your message"); inside the if block to mark the test as failed. Something like:
if (driver.findElements(By.id("errorMessages")).size() != 0) {
Assert.fail("Error..Warning Subscriber already exists ");
}
See this for overloading
I think you are looking at it in the wrong way. Rather than checking if the size is what you expect and then forcing the test to fail, use the inbuilt assertion methods so it reads much more like a logical statement:
assertTrue(driver.findElements(By.id("errorMessages")).size() == 0, "Error..Warning Subscriber already exists");
Documentation from the TestNG site
The inbuilt assertion methods will then print out that message if that assertion fails.