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.
Upcoming SlideShare
Web Services Testing
Next

2

Share

Structured Functional Automated Web Service Testing

This presentation gives an answer on why you should use a programming language for automating web service tests

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Structured Functional Automated Web Service Testing

  1. 1. Structured Functional Automated WebService TestingRoy de Kleijn
  2. 2. Who am I ?• Technical Test Consultant• Trainer test automation• Involved in R&D activities• Blogs:– http://selenium.polteq.com– http://www.rdekleijn.nl
  3. 3. Agenda1. Web Service introduction2. Whats in it for testers ?3. Testing a Web Service4. Cases
  4. 4. Agenda1. Web Service introduction2. Whats in it for testers ?3. Testing a Web Service4. Cases
  5. 5. What is a Web Service ?A Web service is a software component that can beaccessed by another application (such as a client, aserver or another Web service) through the use ofgenerally available, ubiquitous protocols andtransports, such as Hypertext Transport Protocol(HTTP).[Gartner]
  6. 6. Architecture - conventionalapplicationDB
  7. 7. Web Service Based Architecture• Scalable
  8. 8. Web Service Based Architecture• Scalable• Support for any application type
  9. 9. Web Service Based Architecture• Scalable• Support for any application type• Language independent
  10. 10. Web Service Based Architecture• Scalable• Support for any application type• Language independent• Central business logic
  11. 11. Web Service Based Architecture• Scalable• Support for any application type• Language independent• Central business logic• Standardised integration
  12. 12. Different types• Protocols: WSDL / SOAP / REST
  13. 13. Different types• Protocols: WSDL / SOAP / REST• REST (Representational State Transfer)– Defined by HTTP interface
  14. 14. Different types• Protocols: WSDL / SOAP / REST• REST (Representational State Transfer)– Defined by HTTP interface– Support of basic application methods (CRUD):• POST -> create new resource• GET -> retrieve resources• PUT -> replace existing resource• Delete -> remove a resource
  15. 15. Architecture - SOAapplication
  16. 16. Architecture - SOAapplication DBService1Service2Service3
  17. 17. Architecture - SOADesktopapplicationMobileapplicationThird-partyapplication
  18. 18. Architecture - SOADesktopapplicationMobileapplicationThird-partyapplicationDBService1Service2Service3Service4Third-party
  19. 19. How it works...• Request messages are send to a specific endpoint• Messages are mostly XML or JSON fragments• Client can optionally set headers
  20. 20. Agenda1. Web Service introduction2. Whats in it for testers ?3. Testing a Web Service4. Cases
  21. 21. Benefits for a tester• Less brittle tests– No GUI involved, no browser time-outs
  22. 22. Benefits for a tester• Less brittle tests– No GUI involved, no browser time-outs• Testing can start in an early phase
  23. 23. Benefits for a tester• Less brittle tests– No GUI involved, no browser time-outs• Testing can start in an early phase• No access to the code required (might be benefitialthough)
  24. 24. Testing PyramidUISERVICEUNITDevelopers
  25. 25. Testing PyramidUISERVICEUNITAutomated UI TestsAutomated API TestsAutomated Unit TestsDevelopers
  26. 26. Testing PyramidUISERVICEUNITAutomated UI TestsAutomated API TestsAutomated Unit TestsCompoundIsolationDevelopers
  27. 27. Circle of Impact – changing coreCoreS1S2S3A1A2A3
  28. 28. Circle of Impact – changing coreCoreS1S2S3A1A2A3
  29. 29. Circle of Impact – changing coreCoreS1S2S3A1A2A3
  30. 30. Circle of Impact – changing serviceCoreS1S2S3A1A2A3
  31. 31. Circle of Impact – changing serviceCoreS1S2S3A1A2A3
  32. 32. Circle of Impact – changing serviceCoreS1S2S3A1A2A3
  33. 33. Agenda1. Web Service introduction2. Whats in it for testers ?3. Testing a Web Service4. Cases
  34. 34. Testing a Web Service• Pitfalls• General advice• Tools you can use
  35. 35. Pitfalls• Using performance test tools
  36. 36. Pitfalls• Using performance test tools– Hard to use pre/post conditions
  37. 37. Pitfalls• Using performance test tools– Hard to use pre/post conditions– Hard to create maintainable scripts
  38. 38. Pitfalls• Using performance test tools– Hard to use pre/post conditions– Hard to create maintainable scripts– Hard to combine testtypes
  39. 39. Pitfalls• Using performance test tools– Hard to use pre/post conditions– Hard to create maintainable scripts– Hard to combine testtypes– Hard to make complex assertions
  40. 40. Pitfalls• Using performance test tools– Hard to use pre/post conditions– Hard to create maintainable scripts– Hard to combine testtypes– Hard to make complex assertions– Limited flexibility in creating test suites
  41. 41. General advice• Use a programming language
  42. 42. General advice• Use a programming language– IDE features• Auto-completion, refactoring
  43. 43. General advice• Use a programming language– IDE features• Auto-completion, refactoring– Apply design patterns• Make it maintainable and DRY (don’t repeat yourself)
  44. 44. General advice• Use a programming language– IDE features• Auto-completion, refactoring– Apply design patterns• Make it maintainable and DRY (don’t repeat yourself)– Flexible pre/post conditions
  45. 45. General advice• Use a programming language– IDE features• Auto-completion, refactoring– Apply design patterns• Make it maintainable and DRY (don’t repeat yourself)– Flexible pre/post conditions– Combine your Selenium tests with web service tests
  46. 46. Tools you can use• Jersey– Making REST requests• Jackson– JSON processor• JAXB– XML processor• JsonPath– Extract parts of a JSON document
  47. 47. Tools you can use• TestNG– Java testing framework• XMLUnit– Assertions for XML, validate against XSD schema• Hamcrest– General matcher library
  48. 48. Agenda1. Web Service introduction2. Whats in it for testers ?3. Testing a Web Service4. Cases
  49. 49. Case 1Imagine you work for a Dutch Railway company. Theydecide to create a public API, so developers can embedrailway information into their application.You (as a tester) have to test the service.
  50. 50. Create a GET requestClient client = Client.create();WebResource webResource =client.resource("http://webservices.ns.nl");MultivaluedMap<String, String> params = newMultivaluedMapImpl();params.add("station", "ut");ClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").get(ClientResponse.class);if(response.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());}System.out.println(response.getEntity(String.class));Output: Failed : HTTP error code : 401
  51. 51. Create a GET requestClient client = Client.create();WebResource webResource =client.resource("http://webservices.ns.nl");MultivaluedMap<String, String> params = newMultivaluedMapImpl();params.add("station", "ut");ClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").get(ClientResponse.class);if(response.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());}System.out.println(response.getEntity(String.class));Output: Failed : HTTP error code : 401
  52. 52. Create a GET requestClient client = Client.create();WebResource webResource =client.resource("http://webservices.ns.nl");MultivaluedMap<String, String> params = newMultivaluedMapImpl();params.add("station", "ut");ClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").get(ClientResponse.class);if(response.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());}System.out.println(response.getEntity(String.class));Output: Failed : HTTP error code : 401
  53. 53. Create a GET requestClient client = Client.create();WebResource webResource =client.resource("http://webservices.ns.nl");MultivaluedMap<String, String> params = newMultivaluedMapImpl();params.add("station", "ut");ClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").get(ClientResponse.class);if(response.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());}System.out.println(response.getEntity(String.class));Output: Failed : HTTP error code : 401
  54. 54. Create a GET requestClient client = Client.create();WebResource webResource =client.resource("http://webservices.ns.nl");MultivaluedMap<String, String> params = newMultivaluedMapImpl();params.add("station", "ut");ClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").get(ClientResponse.class);if(response.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());}System.out.println(response.getEntity(String.class));Output: Failed : HTTP error code : 401
  55. 55. Create a GET requestClient client = Client.create();WebResource webResource =client.resource("http://webservices.ns.nl");MultivaluedMap<String, String> params = newMultivaluedMapImpl();params.add("station", "ut");ClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").get(ClientResponse.class);if(response.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());}System.out.println(response.getEntity(String.class));Output: Failed : HTTP error code : 401
  56. 56. Create a GET requestClient client = Client.create();WebResource webResource =client.resource("http://webservices.ns.nl");MultivaluedMap<String, String> params = newMultivaluedMapImpl();params.add("station", "ut");ClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").get(ClientResponse.class);if(response.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+ response.getStatus());}System.out.println(response.getEntity(String.class));Output: Failed : HTTP error code : 401
  57. 57. Set request headersBasic AuthenticationClient client = Client.create();client.addFilter(new HTTPBasicAuthFilter("username","password"));Other headersClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").header("key", "value").get(ClientResponse.class);
  58. 58. Set request headersBasic AuthenticationClient client = Client.create();client.addFilter(new HTTPBasicAuthFilter("username","password"));Other headersClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").header("key", "value").get(ClientResponse.class);
  59. 59. Set request headersBasic AuthenticationClient client = Client.create();client.addFilter(new HTTPBasicAuthFilter("username","password"));Other headersClientResponse response = webResource.path("ns-api-avt").queryParams(params).accept("text/xml").header("key", "value").get(ClientResponse.class);
  60. 60. Case 2Imagine you have to control a relatively difficult XML-string.
  61. 61. XML-response<ActueleVertrekTijden><VertrekkendeTrein><RitNummer>3146</RitNummer><VertrekTijd>2013-06-13T14:28:00+0200</VertrekTijd><EindBestemming>Schiphol</EindBestemming><TreinSoort>Intercity</TreinSoort><RouteTekst>Bijlmer ArenA, Adam Zuid</RouteTekst><Vervoerder>NS</Vervoerder><VertrekSpoor wijziging="true">5</VertrekSpoor></VertrekkendeTrein>........</ActueleVertrekTijden>
  62. 62. XML-response<ActueleVertrekTijden><VertrekkendeTrein><RitNummer>3146</RitNummer><VertrekTijd>2013-06-13T14:28:00+0200</VertrekTijd><EindBestemming>Schiphol</EindBestemming><TreinSoort>Intercity</TreinSoort><RouteTekst>Bijlmer ArenA, Adam Zuid</RouteTekst><Vervoerder>NS</Vervoerder><VertrekSpoor wijziging="true">5</VertrekSpoor></VertrekkendeTrein>........</ActueleVertrekTijden>
  63. 63. XML-response<ActueleVertrekTijden><VertrekkendeTrein><RitNummer>3146</RitNummer><VertrekTijd>2013-06-13T14:28:00+0200</VertrekTijd><EindBestemming>Schiphol</EindBestemming><TreinSoort>Intercity</TreinSoort><RouteTekst>Bijlmer ArenA, Adam Zuid</RouteTekst><Vervoerder>NS</Vervoerder><VertrekSpoor wijziging="true">5</VertrekSpoor></VertrekkendeTrein>........</ActueleVertrekTijden>
  64. 64. XML-response<ActueleVertrekTijden><VertrekkendeTrein><RitNummer>3146</RitNummer><VertrekTijd>2013-06-13T14:28:00+0200</VertrekTijd><EindBestemming>Schiphol</EindBestemming><TreinSoort>Intercity</TreinSoort><RouteTekst>Bijlmer ArenA, Adam Zuid</RouteTekst><Vervoerder>NS</Vervoerder><VertrekSpoor wijziging="true">5</VertrekSpoor></VertrekkendeTrein>........</ActueleVertrekTijden>
  65. 65. Create POJO (1)POJO = Plain Old Java Object (nothing special)- Create a class- Implement fields (corresponding to XML elements)- Generate getters/setters- Map Getters to XML elements- By annotationsIn eclipse:Right-click on the class file -> Source -> Generate Getters/Setters
  66. 66. Create POJO (2)@XmlRootElement(name = "ActueleVertrekTijden")public class ActueleVertrekTijden {private List<VertrekkendeTrein> vertrekkendeTrein;@XmlElement(name = "VertrekkendeTrein")public List<VertrekkendeTrein> getVertrekkendeTrein() {return vertrekkendeTrein;}public void setVertrekkendeTrein(List<VertrekkendeTrein>vertrekkendeTrein) {this.vertrekkendeTrein = vertrekkendeTrein;}}
  67. 67. Create POJO (2)@XmlRootElement(name = "ActueleVertrekTijden")public class ActueleVertrekTijden {private List<VertrekkendeTrein> vertrekkendeTrein;@XmlElement(name = "VertrekkendeTrein")public List<VertrekkendeTrein> getVertrekkendeTrein() {return vertrekkendeTrein;}public void setVertrekkendeTrein(List<VertrekkendeTrein>vertrekkendeTrein) {this.vertrekkendeTrein = vertrekkendeTrein;}}
  68. 68. Create POJO (2)@XmlRootElement(name = "ActueleVertrekTijden")public class ActueleVertrekTijden {private List<VertrekkendeTrein> vertrekkendeTrein;@XmlElement(name = "VertrekkendeTrein")public List<VertrekkendeTrein> getVertrekkendeTrein() {return vertrekkendeTrein;}public void setVertrekkendeTrein(List<VertrekkendeTrein>vertrekkendeTrein) {this.vertrekkendeTrein = vertrekkendeTrein;}}
  69. 69. Create POJO (3)public class VertrekkendeTrein {private int ritNummer;private String vertrekTijd;private String eindBestemming;private String treinSoort;private String routeTekst;private String vervoerder;private String vertrekSpoor;@XmlElement(name = "RitNummer")public int getRitNummer() {return ritNummer;}public void setRitNummer(int ritNummer) {this.ritNummer = ritNummer;}
  70. 70. Create POJO (3)public class VertrekkendeTrein {private int ritNummer;private String vertrekTijd;private String eindBestemming;private String treinSoort;private String routeTekst;private String vervoerder;private String vertrekSpoor;@XmlElement(name = "RitNummer")public int getRitNummer() {return ritNummer;}public void setRitNummer(int ritNummer) {this.ritNummer = ritNummer;}
  71. 71. Create POJO (3)public class VertrekkendeTrein {private int ritNummer;private String vertrekTijd;private String eindBestemming;private String treinSoort;private String routeTekst;private String vervoerder;private String vertrekSpoor;@XmlElement(name = "RitNummer")public int getRitNummer() {return ritNummer;}public void setRitNummer(int ritNummer) {this.ritNummer = ritNummer;}<RitNummer><VertrekTijd><EindBestemming><TreinSoort><RouteTekst><Vervoerder><VertrekSpoor>
  72. 72. Create POJO (3)public class VertrekkendeTrein {private int ritNummer;private String vertrekTijd;private String eindBestemming;private String treinSoort;private String routeTekst;private String vervoerder;private String vertrekSpoor;@XmlElement(name = "RitNummer")public int getRitNummer() {return ritNummer;}public void setRitNummer(int ritNummer) {this.ritNummer = ritNummer;}<RitNummer><VertrekTijd><EindBestemming><TreinSoort><RouteTekst><Vervoerder><VertrekSpoor>
  73. 73. Parse String to POJOOutput = response.getEntity(String.class);Unmarshaller jaxbUnmarshaller =jaxbContext.createUnmarshaller();StringReader reader = new StringReader(output);ActueleVertrekTijden actueleVertrekTijden =(ActueleVertrekTijden) jaxbUnmarshaller.unmarshal(reader);System.out.println(actueleVertrekTijden.getVertrekkendeTrein().get(1).getEindBestemming());
  74. 74. Parse String to POJOOutput = response.getEntity(String.class);Unmarshaller jaxbUnmarshaller =jaxbContext.createUnmarshaller();StringReader reader = new StringReader(output);ActueleVertrekTijden actueleVertrekTijden =(ActueleVertrekTijden) jaxbUnmarshaller.unmarshal(reader);System.out.println(actueleVertrekTijden.getVertrekkendeTrein().get(1).getEindBestemming());
  75. 75. Parse String to POJOOutput = response.getEntity(String.class);Unmarshaller jaxbUnmarshaller =jaxbContext.createUnmarshaller();StringReader reader = new StringReader(output);ActueleVertrekTijden actueleVertrekTijden =(ActueleVertrekTijden) jaxbUnmarshaller.unmarshal(reader);System.out.println(actueleVertrekTijden.getVertrekkendeTrein().get(1).getEindBestemming());
  76. 76. Parse String to POJOOutput = response.getEntity(String.class);Unmarshaller jaxbUnmarshaller =jaxbContext.createUnmarshaller();StringReader reader = new StringReader(output);ActueleVertrekTijden actueleVertrekTijden =(ActueleVertrekTijden) jaxbUnmarshaller.unmarshal(reader);System.out.println(actueleVertrekTijden.getVertrekkendeTrein().get(1).getEindBestemming());
  77. 77. Handle Errors<error><message>No station found for input ecvve</message></error>if(xml.contains("error")){// parse to error object} else if(xml.contains("name")){// parse to different object}
  78. 78. ConclusionIf you want something that is:– Easy to maintain– FlexibleUse a programming language for your automatedtesting.
  79. 79. Questions
  80. 80. Thank you!Source available on GitHub:https://github.com/roydekleijn/webservicetestsBook: https://leanpub.com/LearningSelenium/Twitter: https://twitter.com/TheWebTesterLinkedIn: http://www.linkedin.com/in/roydekleijnWebsite: http://rdekleijn.nlGet your FREE copy usingcoupon code: TADNL2013(coupon code valid for 2 months)
  • AbdulrahmanAlzahrani5

    Jan. 27, 2015
  • rdekleijn

    Jun. 21, 2013

This presentation gives an answer on why you should use a programming language for automating web service tests

Views

Total views

2,548

On Slideshare

0

From embeds

0

Number of embeds

1,607

Actions

Downloads

0

Shares

0

Comments

0

Likes

2

×