Note:I used
WSO2 Governance Registry as the example to describe.
1. If you really need to test the product don't think about the time needed to run the test unless the time is the most critical resource.
2. Reduce the dependency between functions (low coupling) as the
failure of a function should not affect to other functions.
e.g. if you add a collection in a function and if another function is going to use it. My advice is you should check the availability of the collection in the second function.
Your code should be able to handle that
3. Before writing a common function analyse the functionality what you are covering from that function and then code it.
Never write a common function without understanding the possible error messages those can occur during the execution.
Analyse all the error messages. Because you can't assure that there won't be any error message during the execution. So give the power to your function to handle it. My advice is to handle it in the common function.
Don't implement it in the test suite unless you are testing for that particular error message.
Write the common function return type as Boolean or Integer ..
I'll tell you the advantage. Have a look at this function
public boolean deleteResource(String path, String name) throws InterruptedException {
gotoBrowsePage(); // this will delete the registered prfile specially or if u want u can
// delete other folders also. eg path ="/system/users/" name ="admin"
Thread.sleep(1000);
int index = 0;
int a, b;
int id = 1;
String path1 = path;
if (!path.equals("/"))
path = path.concat("/");
do {
a = path.indexOf("/", index);
b = path.indexOf("/", a + 1);
if (a == -1 || b == -1)
break;
// System.out.println(path.substring(a+1,b));
id = getId(path.substring(a + 1, b));
if (id == -1)
return false;
else {
Thread.sleep(1000);
selenium.click("resourceView" + id);
Thread.sleep(4000);
}
index = b;
} while (a != -1 && b != -1);
id = getId(name);
if (id == -1)
return false;
Thread.sleep(5000);
selenium.click("actionLink" + id);
Thread.sleep(3000);
if (id == 1) {
selenium.click("link=Delete");
}
else {
selenium.click("//a[@onclick=\"hideOthers(" + id + ",'del');deleteResource('" + path + name + "', '" + path1 + "')\"]");
}
if (selenium.isTextPresent("Are you sure you want to delete ")) {
selenium.click("//button[@type='button']");
}
if (selenium.isTextPresent("Successfully deleted "))
selenium.click("//button[@type='button']");
return true;
}
If the user delete is success it will return true. Otherwise it will return false.
so if u need to verify that the user is deleted, use "assertTrue(deleUser(""))". And if u just need to delete this user, use "deleteUser("")"
3.1 Write a function even for a simple task.. eg. Click on the registry browser root icon.
You may need it anywhere else and if the developer team change the link name you will need to change only a single line. (Krishantha tought me this)
and when you writing a test try to identify the common functions which are available now and use them as much as possible.
Because those common functions are already tested.
4. Rather than using the Thread.sleep() use in built block "wait for". It will wait until the particular string, element is available.
It increases the dynamic of the function. But this has a draw back too.
Default wait time is 60 sec, that mean if there is an error occurred while executing this block, it will wait for 60 sec to say its an error.
eg; in GReg WSDL import function is fully depending one the Internet connection speed.
so some times it will take 10 s , some times it will take 1 min too.
5. Computer is a foolish servant but I will say selenium is a blind servant of that foolish servant
because sometimes though the link is there selenium wont identify it.
eg.
public void gotoSearchPage() throws InterruptedException {
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (selenium.isElementPresent("link=Search")) break; } catch (Exception e) {}
Thread.sleep(1000);
}
selenium.click("link=Search");
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if ("Search".equals(selenium.getText("//div[@id='middle']/h2"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
}
You can consider this function as a fully dynamic function.
selenium will exit the first wait for block if the element present "link=Search". But some times it will say it no element called "link=Search". Because the element is there , but selenium may unable to use it
so put a simple thread sleep before the " selenium.click"
Thread.sleep(1000);
selenium.click("link=Search");
6. If can run the test suite at a lower speed, it may take more time. But it will reduce the number of errors and failures.
7. Running the whole test frame work at least once a day is a good habit because more and more you run, you can see the failures.
8. There is method in selenium selenium.setSpeed(String) from which you may reduce the time
public int countNotifications() throws InterruptedException {
int i = 1;
gotoNotificationPage();
Thread.sleep(1000);
if (selenium.isTextPresent("There are no subscriptions created at present"))
return 0;
while (selenium.isElementPresent("//table[@id='subscriptionsTable']/tbody/tr[" + i + "]/td[1]"))
i++;
return i - 1;
}
I can increase the execution speed when it executes inside the while loop, because it's Java part. For that you can change the code as follow
public int countNotifications() throws InterruptedException {
int i = 1;
String NewSpeed="20";
String CurrentSpeed="";
CurrentSpeed =selenium.getSpeed();
gotoNotificationPage();
Thread.sleep(1000);
if (selenium.isTextPresent("There are no subscriptions created at present"))
return 0;
selenium.setSpeed(NewSpeed);
while (selenium.isElementPresent("//table[@id='subscriptionsTable']/tbody/tr[" + i + "]/td[1]"))
i++;
selenium.setSpeed(Curspeed);
return i - 1;
}
This is something dangerous because if there is an error occurred while processing the "while" loop, your previous speed won't be restored. So the remaining tests will run at the speed "20".
This is some thing like using "goto" statement in a program. I am still working on this issue and I still cant find a good solution except one.
9. Before exit from the function/test class delete all the files you added and undo all the changes you made as much as you can.
But you can't undo rating a collection, filling the default profile.