Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

QA Fest 2019. Saar Rachamim. Developing Tools, While Testing

14 views

Published on

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.

Published in: Education
  • Be the first to comment

  • Be the first to like this

QA Fest 2019. Saar Rachamim. Developing Tools, While Testing

  1. 1. Develop Tools, While Testing Saar Rachamim, Gett
  2. 2. About Me Saar Rachamim BE Developer @Gett saarr@gett.com
  3. 3. About Me Developing automation tools Innovation
  4. 4. About Me Developing automation tools Innovation
  5. 5. Automate everything def main(): time.sleep(17) conn = telnetlib.Telnet(host=COFFEE_MACHINE_ADDR) conn.open() conn.expect([COFFEE_MACHINE_PROM]) conn.write(COFFEE_MACHINE_PASS) conn.write('sys brew') time.sleep(64) conn.write('sys pour') conn.close()
  6. 6. Automate everything def main(): time.sleep(17) conn = telnetlib.Telnet(host=COFFEE_MACHINE_ADDR) conn.open() conn.expect([COFFEE_MACHINE_PROM]) conn.write(COFFEE_MACHINE_PASS) conn.write('sys brew') time.sleep(64) conn.write('sys pour') conn.close()
  7. 7. Automate everything
  8. 8. Origin Story
  9. 9. Origin Story 23 22 21
  10. 10. Origin Story
  11. 11. Origin Story
  12. 12. Origin Story
  13. 13. Origin Story
  14. 14. Origin Story
  15. 15. Origin Story
  16. 16. Origin Story
  17. 17. Origin Story
  18. 18. Origin Story
  19. 19. Origin Story
  20. 20. Design . . .
  21. 21. Design
  22. 22. Demo
  23. 23. Gett’s Road A product loved for its quality Join the ride
  24. 24. Automation Performance Tool Origin Story
  25. 25. App Stability Problem
  26. 26. App Stability
  27. 27. Solutions
  28. 28. Solutions Manual Automation
  29. 29. Solutions Manual Automation Third party In-house
  30. 30. Selected Solution: Developing in House Tool
  31. 31. Developing your own tool ● Questions in mind ○ What language to choose (JavaC#...)
  32. 32. Developing your own tool ● Questions in mind ○ What language to choose (JavaC#...) ○ What platform - mobile, desktop or web
  33. 33. Developing your own tool ● Questions in mind ○ What language to choose (JavaC#...) ○ What platform - mobile, desktop or web ○ DB: Sql, NoSql
  34. 34. Design
  35. 35. Design
  36. 36. Design
  37. 37. Design
  38. 38. Design
  39. 39. The Tool Code
  40. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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); }
  63. 63. Demo
  64. 64. Code Repository https://github.com/saarRachamim/dev/tree/master/ConferenceTests https://github.com/saarRachamim/dev/tree/master/conference_tool
  65. 65. Summary
  66. 66. Contact Information saarrac@gmail.com https://www.linkedin.com/in/saar-rachamim-14055a27/
  67. 67. Questions?

×