Our daily work is comprised of testing a product and improve its quality. However, here and there, we can come to a state where we find a need to build a tool, that can make our work easierbetter.
I will share from my experience when I found myself in a situation where building a tool was needed.
We will start with a web application that allows you to know when a food delivery you ordered arrives to the office, and then we will focus on a tool that test the performance of an app from the UI side. We will do a live demo for both of them.
40. Test Code
public class SeleniumTest {
@Test
public void test(){
String testName = Thread.currentThread().getStackTrace()[1].getMethodName();
new ThreadExecuter(testName).execute();
new TestExecuter().execute();
}
}
41. Test Code
public class SeleniumTest {
@Test
public void test(){
String testName = Thread.currentThread().getStackTrace()[1].getMethodName();
new ThreadExecuter(testName).execute();
new TestExecuter().execute();
}
}
42. Test Code
public class SeleniumTest {
@Test
public void test(){
String testName = Thread.currentThread().getStackTrace()[1].getMethodName();
new ThreadExecuter(testName).execute();
new TestExecuter().execute();
}
}
43. Test Code
public class SeleniumTest {
@Test
public void test(){
String testName = Thread.currentThread().getStackTrace()[1].getMethodName();
new ThreadExecuter(testName).execute();
new TestExecuter().execute();
}
}
44. Test Code
public class TestExecuter {
public void execute(){
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
boolean stop = false;
while(stop){
try{
driver.get(Constants.GOOGLE);
WebElement searchField = driver.findElement(By.xpath(Constants.SEARCH_FIELD));
searchField.sendKeys(new TextGenerator().getTextToSearch());
WebElement searchButton = driver.findElement(By.xpath(Constants.SEARCH_BUTTON));
searchButton.click();
Thread.sleep(Constants.FIVE_SECONDS);
}
catch(Exception e){}
}
}
}
45. Test Code
public class TestExecuter {
public void execute(){
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
boolean stop = false;
while(stop){
try{
driver.get(Constants.GOOGLE);
WebElement searchField = driver.findElement(By.xpath(Constants.SEARCH_FIELD));
searchField.sendKeys(new TextGenerator().getTextToSearch());
WebElement searchButton = driver.findElement(By.xpath(Constants.SEARCH_BUTTON));
searchButton.click();
Thread.sleep(Constants.FIVE_SECONDS);
}
catch(Exception e){}
}
}
}
46. Process Handler Code
public String getCpuUsageByProcessName(String name) throws IOException {
String[] inputArr = {"ps", "-em", "-o", "%cpu,command"};
String retVal = executeTerminalCommands(inputArr, name);
return returnSubStringAccordingStr(retVal, " /").replace(" ", "");
}
private String executeTerminalCommands(String[] inputArr, String commandPart) throws IOException {
String line;
Process process = Runtime.getRuntime().exec(inputArr);
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
if (line.contains(commandPart))
{
return line;
}
}
return "-1";
}
47. Process Handler Code
public String getCpuUsageByProcessName(String name) throws IOException {
String[] inputArr = {"ps", "-em", "-o", "%cpu,command"};
String retVal = executeTerminalCommands(inputArr, name);
return returnSubStringAccordingStr(retVal, " /").replace(" ", "");
}
private String executeTerminalCommands(String[] inputArr, String commandPart) throws IOException {
String line;
Process process = Runtime.getRuntime().exec(inputArr);
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
if (line.contains(commandPart))
{
return line;
}
}
return "-1";
}
48. Process Handler Code
public String getCpuUsageByProcessName(String name) throws IOException {
String[] inputArr = {"ps", "-em", "-o", "%cpu,command"};
String retVal = executeTerminalCommands(inputArr, name);
return returnSubStringAccordingStr(retVal, " /").replace(" ", "");
}
private String executeTerminalCommands(String[] inputArr, String commandPart) throws IOException {
String line;
Process process = Runtime.getRuntime().exec(inputArr);
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
if (line.contains(commandPart))
{
return line;
}
}
return "-1";
}
49. Process Handler Code
public String getCpuUsageByProcessName(String name) throws IOException {
String[] inputArr = {"ps", "-em", "-o", "%cpu,command"};
String retVal = executeTerminalCommands(inputArr, name);
return returnSubStringAccordingStr(retVal, " /").replace(" ", "");
}
private String executeTerminalCommands(String[] inputArr, String commandPart) throws IOException {
String line;
Process process = Runtime.getRuntime().exec(inputArr);
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
if (line.contains(commandPart))
{
return line;
}
}
return "-1";
}
50. Requests Handler Code
ProcessHandler ph = new ProcessHandler();
RequestHandler requestHandler = new RequestHandler(Constants.FB_URL);
String retKey = requestHandler.postHttp("", new String[]{"Content-Type", "Authorization"}, new String[]{"application/x-
www-form-urlencoded", "key=" + Constants.SECRET}, "{"time":"" + Calendar.getInstance().getTime() + "",
"testName":"" + testName + "", "browser":"Chrome"}");
while (true) {
try {
String cpu = ph.getCpuUsageByProcessName(Constants.PROCESS_NAME);
String mem = ph.getMemoryUsageByProcessName(Constants.PROCESS_NAME);
requestHandler.postHttp(retKey, new String[]{"Content-Type", "Authorization"}, new String[]{"application/x-
www-form-urlencoded", "key=" + Constants.SECRET}, "{"mem":"" + mem + "","cpu":"" + cpu + "", "time":"" +
Calendar.getInstance().getTime() + ""}");
} catch (Exception e) {
System.out.println(e);
}
}
51. Requests Handler Code
ProcessHandler ph = new ProcessHandler();
RequestHandler requestHandler = new RequestHandler(Constants.FB_URL);
String retKey = requestHandler.postHttp("", new String[]{"Content-Type", "Authorization"}, new String[]{"application/x-
www-form-urlencoded", "key=" + Constants.SECRET}, "{"time":"" + Calendar.getInstance().getTime() + "",
"testName":"" + testName + "", "browser":"Chrome"}");
while (true) {
try {
String cpu = ph.getCpuUsageByProcessName(Constants.PROCESS_NAME);
String mem = ph.getMemoryUsageByProcessName(Constants.PROCESS_NAME);
requestHandler.postHttp(retKey, new String[]{"Content-Type", "Authorization"}, new String[]{"application/x-
www-form-urlencoded", "key=" + Constants.SECRET}, "{"mem":"" + mem + "","cpu":"" + cpu + "", "time":"" +
Calendar.getInstance().getTime() + ""}");
} catch (Exception e) {
System.out.println(e);
}
}
52. Requests Handler Code
ProcessHandler ph = new ProcessHandler();
RequestHandler requestHandler = new RequestHandler(Constants.FB_URL);
String retKey = requestHandler.postHttp("", new String[]{"Content-Type", "Authorization"}, new String[]{"application/x-
www-form-urlencoded", "key=" + Constants.SECRET}, "{"time":"" + Calendar.getInstance().getTime() + "",
"testName":"" + testName + "", "browser":"Chrome"}");
while (true) {
try {
String cpu = ph.getCpuUsageByProcessName(Constants.PROCESS_NAME);
String mem = ph.getMemoryUsageByProcessName(Constants.PROCESS_NAME);
requestHandler.postHttp(retKey, new String[]{"Content-Type", "Authorization"}, new String[]{"application/x-
www-form-urlencoded", "key=" + Constants.SECRET}, "{"mem":"" + mem + "","cpu":"" + cpu + "", "time":"" +
Calendar.getInstance().getTime() + ""}");
} catch (Exception e) {
System.out.println(e);
}
}
53. Html Code
<div class="container">
<div class="jumbotron">
<div class="panel-heading"></div>
<div ng-controller="MyController">
<div class="text-center">
<select ng-options="testName as testName for testName in testsNames" ng-model="selectedTest"></select>
<select ng-options="testTime as testTime for testTime in testsTime" ng-model="timeSelected"></select>
<select ng-options="measurement as measurement for measurement in measurements" ng-
model="measurementSelected"></select>
<button type="button" class="btn btn-primary my-2" ng-click="createGraph(selectedTest, timeSelected,
measurementSelected)">Execute</button>
</div>
<div class="text-left" style="margin-top:30px">
54. Html Code
<div class="container">
<div class="jumbotron">
<div class="panel-heading"></div>
<div ng-controller="MyController">
<div class="text-center">
<select ng-options="testName as testName for testName in testsNames" ng-model="selectedTest"></select>
<select ng-options="testTime as testTime for testTime in testsTime" ng-model="timeSelected"></select>
<select ng-options="measurement as measurement for measurement in measurements" ng-
model="measurementSelected"></select>
<button type="button" class="btn btn-primary my-2" ng-click="createGraph(selectedTest, timeSelected,
measurementSelected)">Execute</button>
</div>
<div class="text-left" style="margin-top:30px">
55. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
56. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
57. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
58. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
59. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
60. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
61. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
62. Angular Code
$scope.createGraph = function (selectedTest, timeSelected, measurementSelected) {
...
angular.forEach(array, function (test) {
if (test.time == timeSelected && test.testName == selectedTest) {
$scope.currentData = new Array();
for (var key in test) {
var specimentRecord = test[key];
if (specimentRecord != null && typeof specimentRecord !== "undefined") {
$scope.currentData.push(specimentRecord);
$scope.currentlabels.push(specimentRecord.time);
}
}
$scope.currentData = $filter('orderBy')($scope.currentData, "time");
$scope.data = new Array();
$scope.labels = new Array();
for (var key in $scope.currentData) {
if (measurementSelected == "cpu" && typeof $scope.currentData[key].cpu !== "undefined")
$scope.data.push($scope.currentData[key].cpu);
if (measurementSelected == "memory" && typeof $scope.currentData[key].mem !== "undefined")
$scope.data.push($scope.currentData[key].mem);
if (typeof $scope.currentData[key].cpu !== "undefined" || typeof $scope.currentData[key].mem !== "undefined")
$scope.labels.push($scope.currentData[key].time);
}
Add logo of the conference and also on the last slide
Add label of the development language
Add label of the development language
Now will see how it all comes together
This is a humeristic image shows a failure of an app.
There is a message of an SSL error that occured in the app,
While the comment describe the shakespeare quote to be a head of his time
There are third party tools such as: JMeter, WebLoad etc.
Pros:
Saves the time needed for development
In cases that it is a paid tool, then most times it includes support.
Cons:
It won’t give us necessarily everything we need.
Limitations support of programming languages\OS\etc.
In house developed tools:
Pros:
Adjusted directly to the needs comes from the product.
Self development.
Cons:
Can take a lot of men hours to develop.
Maintenance time.
Make the font bigger
To add another slide that shows on what parts of the code we will go through
Add label of the development
This is the code the manages the tests layer
To try to do it clearer, animations that show parts of the code and not everything in bulk to add explanation about each line that
We take the test name, we will show later where it is used
We have a thread that manages sending the values of the process that we measure
We have another executer for the tests that test the product
This is the code of the test that work on the UI, in this case we are testing over Chrome browser
In the test we navigate to google site and then searching for different values over the search engine.
This is just an example for a test, since we are not testing a specific product
This is the code for getting the cpu from the a given process,
We have a very similar code for abstracting the values of the memory of different processes
We can see that we get the value using a method called executeTerminalCommands
We will use the smae function for getting the memory,
Since the code is used over mac os, different commands will be needed for different os
Here we get the process that we want to measure
And we are looking for the line that holds the value of the cpu of the specific process that we are measuring.
This is the returned value for us
This code actually sends the the values of the cpu and the memory that we got - to the database.
The data base can be an in house database or a third party database. As before, this is part of the things we consider
Cpu and memory values are obtained
And then sent to the db server that handle the data and insert it to the database
In the html code , we have a button that trigger a createGraph function
This is an angular code with a create graph function
We are searching in all the data for the data the was executed in a specific time
Each specimentRecord at the test has its own key, so we are going over each key
Then we are taking each speciment according to the key.
we are simply taking all the values of the memory and cpu, that we sent during the test
We are ordering it according to the time
Then we are pusing the data
cpu
memory
And the time is also pushed
Now will see how it all comes together
Split the Slide into 2 parts: contacts and links to github. To put it where it is relevant (showing the code)
Split the Slide into 2 parts: contacts and links to github. To put it where it is relevant (showing the code)