SlideShare a Scribd company logo
Self-testing REST APIs
with
API First, Swagger and Play
You need two days to write test cases!?
You already have the Requirements Specification.
Just copy and paste from it.
http://inderpsingh.blogspot.de/2010/05/funny-things-that-testers-hear.html
Specification
Specification
Specification
Specification
Architectural style
Specification
Architectural style
Technological stack
Architectural style
Architectural style
REST
REST
• Client-Server
• Stateless
• Cacheable
• Layered System
• Uniform Interface
• Identification of resources
• Manipulation of resources through these representations
• Self-descriptive messages
• Hypermedia as the engine of application state
Everybody's doing it…
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API First, Swagger and Play"
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API First, Swagger and Play"
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API First, Swagger and Play"
Testers, how are you doing it?
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API First, Swagger and Play"
All of them are just different views of
the same piece of software…
What is software?
Simple
the programs that run on a computer and perform certain
functions
something used or associated with and usually contrasted
with hardware as the entire set of programs, procedures,
and related documentation associated with a system and
especially a computer system.
Full
Can you remember quality metrics of your current project?
Libraries it uses?
Runtime environment it runs in?
Container or/and hypervisor?
Operating system?
Firmware/BIOS ?
[A] constructive approach to the problem of program
correctness [is] a usual technique to make a program and
then to test it. But, program testing can be a very effective
way to show the presence of bugs, it is hopelessly
inadequate for showing their absence. The only effective
way to raise the confidence level of a program significantly
is to give a convincing proof of its correctness.
-- Edsger, Wybe Di jkstra, ACM Turing Lecture, The Humble Programmer, 1972
Property based testing
Types are specifications of possible values complying to that Type
Types describe the rules that values must comply to
A possibility to generate ranges of data values for given Types
Boolean: True or False
Equality: Equal or Not Equal
Ordering: Greater, Equal or Less
Provable
Numbers
Strings
Pretty much anything not composed from Provables
Falsifiable
Let’s look again at our system
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API First, Swagger and Play"
aka Ports and Adapters
Chris Fidao
https://www.youtube.com/watch?v=6SBjKOwVq0o
Specification
Architectural style
Technology stack
Let’s look again at our solution space
Transport
Transport
Validations
Validations
Model
Model
DRY
DRY
Most people take DRY to mean you shouldn't duplicate code.
That's not its intention. The idea behind DRY is far grander
than that. DRY says that every piece of system knowledge
should have one authoritative, unambiguous representation.
Dave Thomas
Specification is software
It should be a single source of
truth about the system
Formal specification gives us:
Possibility to prove implementation conformance
Self-Evident poorly specified areas
Self-Documented API definition
Intelligent scaffolding
http://www.heppenstall.ca/academics/doc/320/L15_Z.pdf
You need two days to write test cases!?
You already have the requirements specification.
Just copy and paste from it.
Specification
Architectural style
Technology stack
Let’s look again at our technology choice
• Easy to use
• Human readable
• Widest adoption
• Open Source
• Scala and Java
• Dynamic recompilation
• Hot reload
• Asynchronous IO
• Easy to use
Specification
URLs
Verbs
Parameters
Security
Definitions
Specification
URLs
Verbs
Parameters
Security
Definitions Validations
Model
Test Data
Validations
Play Routes
Marshallers
Tests
Controllers
DEMO
Architecture
AST
Play
Akka HTTP
Swagger
RAML
Apiary
Blueprint
…
…
…
Generated code
Metadata
swagger: "2.0"

info:

version: 1.0.0

title: Swagger Petstore

description: A sample API that uses a petstore as an example to
demonstrate features in the swagger-2.0 specification

termsOfService: http://swagger.io/terms/

contact:

name: Swagger API Team

email: foo@example.com

url: http://madskristensen.net

license:

name: MIT

url: http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT

host: petstore.swagger.io

basePath: /api

schemes:

- http

consumes:

- application/json

produces:

- application/json
Definitions
definitions:

Pet:

allOf:

- $ref: '#/definitions/NewPet'

- required:

- id

properties:

id:

type: integer

format: int64

NewPet:

required:

- name 

properties:

name:

type: string

tag:

type: string 

Error:

required:

- code

- message

properties:

code:

type: integer

format: int32

message:

type: string
object definitions {

trait NewPetDef {

def name: String

def tag: Option[String]

}

case class Pet(

id: Option[Long],

name: String,

tag: Option[String]

) extends NewPetDef

case class NewPet(

name: String,

tag: Option[String]

) extends NewPetDef

case class Error(

code: Int,

message: String

)

}
Test data
definitions:

Pet:

allOf:

- $ref: '#/definitions/NewPet'

- required:

- id

properties:

id:

type: integer

format: int64

NewPet:

required:

- name 

properties:

name:

type: string

tag:

type: string 

Error:

required:

- code

- message

properties:

code:

type: integer

format: int32

message:

type: string
object generatorDefinitions {



def createPet = _generate(PetGenerator)

def createNewPet = _generate(NewPetGenerator)

def createError = _generate(ErrorGenerator)

// test data generator for /definitions/Pet

val PetGenerator =

for {

id <- Gen.option(arbitrary[Long])

name <- arbitrary[String]

tag <- Gen.option(arbitrary[String])

} yield Pet(id, name, tag)

// test data generator for /definitions/NewPet

val NewPetGenerator =

for {

name <- arbitrary[String]

tag <- Gen.option(arbitrary[String])

} yield NewPet(name, tag)

// test data generator for /definitions/Error

val ErrorGenerator =

for {

code <- arbitrary[Int]

message <- arbitrary[String]

} yield Error(code, message)

def _generate[T](gen: Gen[T]) = (count: Int) =>
for (i <- 1 to count) yield gen.sample

}
Validations'#/definitions/NewPet'

red:

rties:

ype: integer

ormat: int64



s:

string

string 

ge

s:

integer

t: int32

:

string
class PetValidation(instance: Pet) {

import de.zalando.play.controllers.PlayValidations._

val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]

val result = {

val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else Right(instance)

}

}





class NewPetValidation(instance: NewPet) {

import de.zalando.play.controllers.PlayValidations._

val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]

val result = {

val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else Right(instance)

}

}





class ErrorValidation(instance: Error) {

import de.zalando.play.controllers.PlayValidations._

val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]

val result = {

val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else Right(instance)

}

}
Validations
/pets/{id}:

get:

description: Returns a user based
on a single ID, if the user does not
have access to the pet

operationId: find pet by id

parameters:

- name: id

in: path

description: ID of pet to fetch

required: true

type: integer

format: int64

responses:

200:

description: pet response

schema:

$ref: '#/definitions/Pet'

default:

description: unexpected error

schema:

$ref: '#/definitions/Error'
class ValidationForPetexpandedYamlfindPetById(in: (Long)) {

val (id) = in



val idConstraints = new ValidationBase[Long] {

override def constraints: Seq[Constraint[Long]] = Seq()

}



val normalValidations =
Seq(idConstraints.applyConstraints(id))



val containerValidations =
Seq.empty[scala.Either[scala.Seq[ParsingError], String]]



val rightResult = Right((id))



val allValidations = normalValidations ++
containerValidations



val result = {

val errors =
allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else rightResult

}

}
Tests
"discard invalid data" in new WithApplication {

val genInputs =

for {

id <- arbitrary[Long]

} yield (id)

val inputs = genInputs suchThat { i => new ValidationForPetexpandedYamlfindPetById(i).result !=
Right(i) }

val props = forAll(inputs) { i => testInvalidInput(i) }

checkResult(props)

}
Tests
def testInvalidInput(in: (Long)) = {

val (id) = in

val url = s"""/api/pets/${id}"""

val path = route(FakeRequest(GET, url)).get

val validation = new ValidationForPetexpandedYamlfindPetById(id).result

lazy val validations = validation.left.get flatMap {

_.messages map { m => contentAsString(path).contains(m) ?= true }

}

("given an URL: [" + url + "]") |: all(

status(path) ?= BAD_REQUEST,

contentType(path) ?= Some("application/json"),

validation.isLeft ?= true,

all(validations:_*)

)

}
Controllers
private val findPetByIdResponseMimeType = "application/json"

private val findPetByIdActionSuccessStatus = Status(200)



private type findPetByIdActionRequestType = (Long)

private type findPetByIdActionResultType = Pet

private type findPetByIdActionType = findPetByIdActionRequestType => Either[Throwable, findPetByIdActionResultType]



private def errorToStatusfindPetById: PartialFunction[Throwable, Status] = PartialFunction.empty[Throwable, Status]



def findPetByIdAction = (f: findPetByIdActionType) => (id: Long) => Action {

val result = new ValidationForPetexpandedYamlfindPetById(id).result.right.map {

processValidfindPetByIdRequest(f)

}

implicit val marshaller = parsingErrors2Writable(findPetByIdResponseMimeType)

val response = result.left.map { BadRequest(_) }

response.fold(a => a, c => c)

}



private def processValidfindPetByIdRequest(f: findPetByIdActionType)(request: findPetByIdActionRequestType) = {

val callerResult = f(request)

val status = callerResult match {

case Left(error) => (errorToStatusfindPetById orElse defaultErrorMapping)(error)

case Right(result) => findPetByIdActionSuccessStatus

}

implicit val findPetByIdWritableJson = anyToWritable[findPetByIdActionResultType](findPetByIdResponseMimeType)

status(callerResult)

}
Skeletons
class PetexpandedYaml extends PetexpandedYamlBase {



// handler for GET /pets

def findPets = findPetsAction { in : (Option[Seq[String]], Option[Int]) =>

val (tags, limit) = in

???

}



// handler for POST /pets

def addPet = addPetAction { in : (NewPet) =>

val (pet) = in

???

}



// handler for GET /pets/{id}

def findPetById = findPetByIdAction { in : (Long) =>

val (id) = in

???

}



// handler for DELETE /pets/{id}

def deletePet = deletePetAction { in : (Long) =>

val (id) = in

???

}

}
http://github.com/zalando/play-swagger
Questions?
Ad

More Related Content

What's hot (19)

Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
Rabble .
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava Schmidt
JavaDayUA
 
SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!
Taras Oleksyn
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015
CiaranMcNulty
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScript
Ynon Perek
 
Crafting [Better] API Clients
Crafting [Better] API ClientsCrafting [Better] API Clients
Crafting [Better] API Clients
Wellfire Interactive
 
Real world dependency injection - DPC10
Real world dependency injection - DPC10Real world dependency injection - DPC10
Real world dependency injection - DPC10
Stephan Hochdörfer
 
TDD, BDD, RSpec
TDD, BDD, RSpecTDD, BDD, RSpec
TDD, BDD, RSpec
Nascenia IT
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
Tarek Yehia
 
Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11
Stephan Hochdörfer
 
KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
WO Community
 
Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17
Andres Almiray
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the Job
CiaranMcNulty
 
Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)
Vysakh Sreenivasan
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
SWIFTotter Solutions
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
Jalpesh Vasa
 
Rails Best Practices
Rails Best PracticesRails Best Practices
Rails Best Practices
Wen-Tien Chang
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala Microservices
Federico Feroldi
 
Not your father's tests
Not your father's testsNot your father's tests
Not your father's tests
Sean P. Floyd
 
Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007Introduction to Active Record at MySQL Conference 2007
Introduction to Active Record at MySQL Conference 2007
Rabble .
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava Schmidt
JavaDayUA
 
SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!
Taras Oleksyn
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015
CiaranMcNulty
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScript
Ynon Perek
 
Real world dependency injection - DPC10
Real world dependency injection - DPC10Real world dependency injection - DPC10
Real world dependency injection - DPC10
Stephan Hochdörfer
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
Tarek Yehia
 
Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11Testing untestable code - PHPBNL11
Testing untestable code - PHPBNL11
Stephan Hochdörfer
 
Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17
Andres Almiray
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the Job
CiaranMcNulty
 
Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)Testing Ruby with Rspec (a beginner's guide)
Testing Ruby with Rspec (a beginner's guide)
Vysakh Sreenivasan
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
SWIFTotter Solutions
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
Jalpesh Vasa
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala Microservices
Federico Feroldi
 
Not your father's tests
Not your father's testsNot your father's tests
Not your father's tests
Sean P. Floyd
 

Viewers also liked (17)

Super powered API testing
Super powered API testing Super powered API testing
Super powered API testing
postmanclient
 
Developing and Testing a MongoDB and Node.js REST API
Developing and Testing a MongoDB and Node.js REST APIDeveloping and Testing a MongoDB and Node.js REST API
Developing and Testing a MongoDB and Node.js REST API
All Things Open
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
Samantha Geitz
 
SOAP-UI The Web service Testing
SOAP-UI The Web service TestingSOAP-UI The Web service Testing
SOAP-UI The Web service Testing
Ganesh Mandala
 
Api testing
Api testingApi testing
Api testing
test test
 
4 Major Advantages of API Testing
4 Major Advantages of API Testing4 Major Advantages of API Testing
4 Major Advantages of API Testing
QASource
 
OpenStack Tempest and REST API testing
OpenStack Tempest and REST API testingOpenStack Tempest and REST API testing
OpenStack Tempest and REST API testing
openstackindia
 
software testing on whatsapp
software testing on whatsappsoftware testing on whatsapp
software testing on whatsapp
nil65
 
API Testing: The heart of functional testing" with Bj Rollison
API Testing: The heart of functional testing" with Bj RollisonAPI Testing: The heart of functional testing" with Bj Rollison
API Testing: The heart of functional testing" with Bj Rollison
TEST Huddle
 
API Testing
API TestingAPI Testing
API Testing
Bikash Sharma
 
Api testing
Api testingApi testing
Api testing
Keshav Kashyap
 
REST API testing with SpecFlow
REST API testing with SpecFlowREST API testing with SpecFlow
REST API testing with SpecFlow
Aiste Stikliute
 
How to Automate API Testing
How to Automate API TestingHow to Automate API Testing
How to Automate API Testing
Bruno Pedro
 
Pentesting RESTful WebServices v1.0
Pentesting RESTful WebServices v1.0Pentesting RESTful WebServices v1.0
Pentesting RESTful WebServices v1.0
n|u - The Open Security Community
 
Webservices testing using SoapUI
Webservices testing using SoapUIWebservices testing using SoapUI
Webservices testing using SoapUI
Testing World
 
Pentesting ReST API
Pentesting ReST APIPentesting ReST API
Pentesting ReST API
Nutan Kumar Panda
 
Testing web services
Testing web servicesTesting web services
Testing web services
Taras Lytvyn
 
Super powered API testing
Super powered API testing Super powered API testing
Super powered API testing
postmanclient
 
Developing and Testing a MongoDB and Node.js REST API
Developing and Testing a MongoDB and Node.js REST APIDeveloping and Testing a MongoDB and Node.js REST API
Developing and Testing a MongoDB and Node.js REST API
All Things Open
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
Samantha Geitz
 
SOAP-UI The Web service Testing
SOAP-UI The Web service TestingSOAP-UI The Web service Testing
SOAP-UI The Web service Testing
Ganesh Mandala
 
4 Major Advantages of API Testing
4 Major Advantages of API Testing4 Major Advantages of API Testing
4 Major Advantages of API Testing
QASource
 
OpenStack Tempest and REST API testing
OpenStack Tempest and REST API testingOpenStack Tempest and REST API testing
OpenStack Tempest and REST API testing
openstackindia
 
software testing on whatsapp
software testing on whatsappsoftware testing on whatsapp
software testing on whatsapp
nil65
 
API Testing: The heart of functional testing" with Bj Rollison
API Testing: The heart of functional testing" with Bj RollisonAPI Testing: The heart of functional testing" with Bj Rollison
API Testing: The heart of functional testing" with Bj Rollison
TEST Huddle
 
REST API testing with SpecFlow
REST API testing with SpecFlowREST API testing with SpecFlow
REST API testing with SpecFlow
Aiste Stikliute
 
How to Automate API Testing
How to Automate API TestingHow to Automate API Testing
How to Automate API Testing
Bruno Pedro
 
Webservices testing using SoapUI
Webservices testing using SoapUIWebservices testing using SoapUI
Webservices testing using SoapUI
Testing World
 
Testing web services
Testing web servicesTesting web services
Testing web services
Taras Lytvyn
 
Ad

Similar to QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API First, Swagger and Play" (20)

Whidbey old
Whidbey old Whidbey old
Whidbey old
grenaud
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
Caleb Jenkins
 
Measuring Your Code
Measuring Your CodeMeasuring Your Code
Measuring Your Code
Nate Abele
 
Measuring Your Code 2.0
Measuring Your Code 2.0Measuring Your Code 2.0
Measuring Your Code 2.0
Nate Abele
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Code
erikmsp
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
Srinivasa GV
 
Developer power tools
Developer power toolsDeveloper power tools
Developer power tools
Nick Harrison
 
Code review
Code reviewCode review
Code review
Abhishek Sur
 
10 Rules for Safer Code
10 Rules for Safer Code10 Rules for Safer Code
10 Rules for Safer Code
Quang Ngoc
 
Mining Code Examples with Descriptive Text from Software Artifacts
Mining Code Examples with Descriptive Text from Software ArtifactsMining Code Examples with Descriptive Text from Software Artifacts
Mining Code Examples with Descriptive Text from Software Artifacts
Preetha Chatterjee
 
Asp.net MVC - Course 2
Asp.net MVC - Course 2Asp.net MVC - Course 2
Asp.net MVC - Course 2
erdemergin
 
Validate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation apiValidate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation api
Raffaele Chiocca
 
Secure Programming
Secure ProgrammingSecure Programming
Secure Programming
alpha0
 
Codeigniter
CodeigniterCodeigniter
Codeigniter
minhrau111
 
Pragmatic Parallels: Java and JavaScript
Pragmatic Parallels: Java and JavaScriptPragmatic Parallels: Java and JavaScript
Pragmatic Parallels: Java and JavaScript
davejohnson
 
Java Programming For Android
Java Programming For AndroidJava Programming For Android
Java Programming For Android
TechiNerd
 
Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...
Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...
Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...
Lionel Briand
 
Extreme
ExtremeExtreme
Extreme
ESUG
 
Whidbey old
Whidbey old Whidbey old
Whidbey old
grenaud
 
Measuring Your Code
Measuring Your CodeMeasuring Your Code
Measuring Your Code
Nate Abele
 
Measuring Your Code 2.0
Measuring Your Code 2.0Measuring Your Code 2.0
Measuring Your Code 2.0
Nate Abele
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
Working Effectively With Legacy Perl Code
Working Effectively With Legacy Perl CodeWorking Effectively With Legacy Perl Code
Working Effectively With Legacy Perl Code
erikmsp
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
Srinivasa GV
 
Developer power tools
Developer power toolsDeveloper power tools
Developer power tools
Nick Harrison
 
10 Rules for Safer Code
10 Rules for Safer Code10 Rules for Safer Code
10 Rules for Safer Code
Quang Ngoc
 
Mining Code Examples with Descriptive Text from Software Artifacts
Mining Code Examples with Descriptive Text from Software ArtifactsMining Code Examples with Descriptive Text from Software Artifacts
Mining Code Examples with Descriptive Text from Software Artifacts
Preetha Chatterjee
 
Asp.net MVC - Course 2
Asp.net MVC - Course 2Asp.net MVC - Course 2
Asp.net MVC - Course 2
erdemergin
 
Validate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation apiValidate your entities with symfony validator and entity validation api
Validate your entities with symfony validator and entity validation api
Raffaele Chiocca
 
Secure Programming
Secure ProgrammingSecure Programming
Secure Programming
alpha0
 
Pragmatic Parallels: Java and JavaScript
Pragmatic Parallels: Java and JavaScriptPragmatic Parallels: Java and JavaScript
Pragmatic Parallels: Java and JavaScript
davejohnson
 
Java Programming For Android
Java Programming For AndroidJava Programming For Android
Java Programming For Android
TechiNerd
 
Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...
Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...
Mining SQL Injection and Cross Site Scripting Vulnerabilities using Hybrid Pr...
Lionel Briand
 
Extreme
ExtremeExtreme
Extreme
ESUG
 
Ad

More from GeeksLab Odessa (20)

DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...
DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...
DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...
GeeksLab Odessa
 
DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...
DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...
DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...
GeeksLab Odessa
 
DataScience Lab 2017_Блиц-доклад_Турский Виктор
DataScience Lab 2017_Блиц-доклад_Турский ВикторDataScience Lab 2017_Блиц-доклад_Турский Виктор
DataScience Lab 2017_Блиц-доклад_Турский Виктор
GeeksLab Odessa
 
DataScience Lab 2017_Обзор методов детекции лиц на изображение
DataScience Lab 2017_Обзор методов детекции лиц на изображениеDataScience Lab 2017_Обзор методов детекции лиц на изображение
DataScience Lab 2017_Обзор методов детекции лиц на изображение
GeeksLab Odessa
 
DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...
DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...
DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...
GeeksLab Odessa
 
DataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-докладDataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-доклад
GeeksLab Odessa
 
DataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-докладDataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-доклад
GeeksLab Odessa
 
DataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-докладDataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-доклад
GeeksLab Odessa
 
DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...
DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...
DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...
GeeksLab Odessa
 
DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...
DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...
DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...
GeeksLab Odessa
 
DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко
DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко
DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко
GeeksLab Odessa
 
DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...
DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...
DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...
GeeksLab Odessa
 
DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...
DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...
DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...
GeeksLab Odessa
 
DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...
DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...
DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...
GeeksLab Odessa
 
DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...
DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...
DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...
GeeksLab Odessa
 
DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...
DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...
DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...
GeeksLab Odessa
 
DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...
DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...
DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...
GeeksLab Odessa
 
DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот
DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот
DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот
GeeksLab Odessa
 
JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...
JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...
JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...
GeeksLab Odessa
 
JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js
JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js
JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js
GeeksLab Odessa
 
DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...
DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...
DataScience Lab2017_Коррекция геометрических искажений оптических спутниковых...
GeeksLab Odessa
 
DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...
DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...
DataScience Lab 2017_Kappa Architecture: How to implement a real-time streami...
GeeksLab Odessa
 
DataScience Lab 2017_Блиц-доклад_Турский Виктор
DataScience Lab 2017_Блиц-доклад_Турский ВикторDataScience Lab 2017_Блиц-доклад_Турский Виктор
DataScience Lab 2017_Блиц-доклад_Турский Виктор
GeeksLab Odessa
 
DataScience Lab 2017_Обзор методов детекции лиц на изображение
DataScience Lab 2017_Обзор методов детекции лиц на изображениеDataScience Lab 2017_Обзор методов детекции лиц на изображение
DataScience Lab 2017_Обзор методов детекции лиц на изображение
GeeksLab Odessa
 
DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...
DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...
DataScienceLab2017_Сходство пациентов: вычистка дубликатов и предсказание про...
GeeksLab Odessa
 
DataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-докладDataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-доклад
GeeksLab Odessa
 
DataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-докладDataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-доклад
GeeksLab Odessa
 
DataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-докладDataScienceLab2017_Блиц-доклад
DataScienceLab2017_Блиц-доклад
GeeksLab Odessa
 
DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...
DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...
DataScienceLab2017_Cервинг моделей, построенных на больших данных с помощью A...
GeeksLab Odessa
 
DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...
DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...
DataScienceLab2017_BioVec: Word2Vec в задачах анализа геномных данных и биоин...
GeeksLab Odessa
 
DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко
DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко
DataScienceLab2017_Data Sciences и Big Data в Телекоме_Александр Саенко
GeeksLab Odessa
 
DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...
DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...
DataScienceLab2017_Высокопроизводительные вычислительные возможности для сист...
GeeksLab Odessa
 
DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...
DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...
DataScience Lab 2017_Мониторинг модных трендов с помощью глубокого обучения и...
GeeksLab Odessa
 
DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...
DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...
DataScience Lab 2017_Кто здесь? Автоматическая разметка спикеров на телефонны...
GeeksLab Odessa
 
DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...
DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...
DataScience Lab 2017_From bag of texts to bag of clusters_Терпиль Евгений / П...
GeeksLab Odessa
 
DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...
DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...
DataScience Lab 2017_Графические вероятностные модели для принятия решений в ...
GeeksLab Odessa
 
DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...
DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...
DataScienceLab2017_Оптимизация гиперпараметров машинного обучения при помощи ...
GeeksLab Odessa
 
DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот
DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот
DataScienceLab2017_Как знать всё о покупателях (или почти всё)?_Дарина Перемот
GeeksLab Odessa
 
JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...
JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...
JS Lab 2017_Mapbox GL: как работают современные интерактивные карты_Владимир ...
GeeksLab Odessa
 
JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js
JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js
JS Lab2017_Под микроскопом: блеск и нищета микросервисов на node.js
GeeksLab Odessa
 

Recently uploaded (20)

Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
#StandardsGoals for 2025: Standards & certification roundup - Tech Forum 2025
BookNet Canada
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 

QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API First, Swagger and Play"

  • 1. Self-testing REST APIs with API First, Swagger and Play
  • 2. You need two days to write test cases!? You already have the Requirements Specification. Just copy and paste from it. http://inderpsingh.blogspot.de/2010/05/funny-things-that-testers-hear.html
  • 10. REST • Client-Server • Stateless • Cacheable • Layered System • Uniform Interface • Identification of resources • Manipulation of resources through these representations • Self-descriptive messages • Hypermedia as the engine of application state
  • 15. Testers, how are you doing it?
  • 17. All of them are just different views of the same piece of software…
  • 19. Simple the programs that run on a computer and perform certain functions
  • 20. something used or associated with and usually contrasted with hardware as the entire set of programs, procedures, and related documentation associated with a system and especially a computer system. Full
  • 21. Can you remember quality metrics of your current project? Libraries it uses? Runtime environment it runs in? Container or/and hypervisor? Operating system? Firmware/BIOS ?
  • 22. [A] constructive approach to the problem of program correctness [is] a usual technique to make a program and then to test it. But, program testing can be a very effective way to show the presence of bugs, it is hopelessly inadequate for showing their absence. The only effective way to raise the confidence level of a program significantly is to give a convincing proof of its correctness. -- Edsger, Wybe Di jkstra, ACM Turing Lecture, The Humble Programmer, 1972
  • 24. Types are specifications of possible values complying to that Type Types describe the rules that values must comply to A possibility to generate ranges of data values for given Types
  • 25. Boolean: True or False Equality: Equal or Not Equal Ordering: Greater, Equal or Less Provable
  • 26. Numbers Strings Pretty much anything not composed from Provables Falsifiable
  • 27. Let’s look again at our system
  • 29. aka Ports and Adapters Chris Fidao https://www.youtube.com/watch?v=6SBjKOwVq0o
  • 32. DRY
  • 33. DRY Most people take DRY to mean you shouldn't duplicate code. That's not its intention. The idea behind DRY is far grander than that. DRY says that every piece of system knowledge should have one authoritative, unambiguous representation. Dave Thomas
  • 34. Specification is software It should be a single source of truth about the system
  • 35. Formal specification gives us: Possibility to prove implementation conformance Self-Evident poorly specified areas Self-Documented API definition Intelligent scaffolding http://www.heppenstall.ca/academics/doc/320/L15_Z.pdf
  • 36. You need two days to write test cases!? You already have the requirements specification. Just copy and paste from it.
  • 37. Specification Architectural style Technology stack Let’s look again at our technology choice
  • 38. • Easy to use • Human readable • Widest adoption • Open Source • Scala and Java • Dynamic recompilation • Hot reload • Asynchronous IO • Easy to use
  • 41. DEMO
  • 45. Metadata swagger: "2.0"
 info:
 version: 1.0.0
 title: Swagger Petstore
 description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
 termsOfService: http://swagger.io/terms/
 contact:
 name: Swagger API Team
 email: [email protected]
 url: http://madskristensen.net
 license:
 name: MIT
 url: http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
 host: petstore.swagger.io
 basePath: /api
 schemes:
 - http
 consumes:
 - application/json
 produces:
 - application/json
  • 46. Definitions definitions:
 Pet:
 allOf:
 - $ref: '#/definitions/NewPet'
 - required:
 - id
 properties:
 id:
 type: integer
 format: int64
 NewPet:
 required:
 - name 
 properties:
 name:
 type: string
 tag:
 type: string 
 Error:
 required:
 - code
 - message
 properties:
 code:
 type: integer
 format: int32
 message:
 type: string object definitions {
 trait NewPetDef {
 def name: String
 def tag: Option[String]
 }
 case class Pet(
 id: Option[Long],
 name: String,
 tag: Option[String]
 ) extends NewPetDef
 case class NewPet(
 name: String,
 tag: Option[String]
 ) extends NewPetDef
 case class Error(
 code: Int,
 message: String
 )
 }
  • 47. Test data definitions:
 Pet:
 allOf:
 - $ref: '#/definitions/NewPet'
 - required:
 - id
 properties:
 id:
 type: integer
 format: int64
 NewPet:
 required:
 - name 
 properties:
 name:
 type: string
 tag:
 type: string 
 Error:
 required:
 - code
 - message
 properties:
 code:
 type: integer
 format: int32
 message:
 type: string object generatorDefinitions {
 
 def createPet = _generate(PetGenerator)
 def createNewPet = _generate(NewPetGenerator)
 def createError = _generate(ErrorGenerator)
 // test data generator for /definitions/Pet
 val PetGenerator =
 for {
 id <- Gen.option(arbitrary[Long])
 name <- arbitrary[String]
 tag <- Gen.option(arbitrary[String])
 } yield Pet(id, name, tag)
 // test data generator for /definitions/NewPet
 val NewPetGenerator =
 for {
 name <- arbitrary[String]
 tag <- Gen.option(arbitrary[String])
 } yield NewPet(name, tag)
 // test data generator for /definitions/Error
 val ErrorGenerator =
 for {
 code <- arbitrary[Int]
 message <- arbitrary[String]
 } yield Error(code, message)
 def _generate[T](gen: Gen[T]) = (count: Int) => for (i <- 1 to count) yield gen.sample
 }
  • 48. Validations'#/definitions/NewPet'
 red:
 rties:
 ype: integer
 ormat: int64
 
 s:
 string
 string 
 ge
 s:
 integer
 t: int32
 :
 string class PetValidation(instance: Pet) {
 import de.zalando.play.controllers.PlayValidations._
 val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else Right(instance)
 }
 }
 
 
 class NewPetValidation(instance: NewPet) {
 import de.zalando.play.controllers.PlayValidations._
 val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else Right(instance)
 }
 }
 
 
 class ErrorValidation(instance: Error) {
 import de.zalando.play.controllers.PlayValidations._
 val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else Right(instance)
 }
 }
  • 49. Validations /pets/{id}:
 get:
 description: Returns a user based on a single ID, if the user does not have access to the pet
 operationId: find pet by id
 parameters:
 - name: id
 in: path
 description: ID of pet to fetch
 required: true
 type: integer
 format: int64
 responses:
 200:
 description: pet response
 schema:
 $ref: '#/definitions/Pet'
 default:
 description: unexpected error
 schema:
 $ref: '#/definitions/Error' class ValidationForPetexpandedYamlfindPetById(in: (Long)) {
 val (id) = in
 
 val idConstraints = new ValidationBase[Long] {
 override def constraints: Seq[Constraint[Long]] = Seq()
 }
 
 val normalValidations = Seq(idConstraints.applyConstraints(id))
 
 val containerValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 
 val rightResult = Right((id))
 
 val allValidations = normalValidations ++ containerValidations
 
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else rightResult
 }
 }
  • 50. Tests "discard invalid data" in new WithApplication {
 val genInputs =
 for {
 id <- arbitrary[Long]
 } yield (id)
 val inputs = genInputs suchThat { i => new ValidationForPetexpandedYamlfindPetById(i).result != Right(i) }
 val props = forAll(inputs) { i => testInvalidInput(i) }
 checkResult(props)
 }
  • 51. Tests def testInvalidInput(in: (Long)) = {
 val (id) = in
 val url = s"""/api/pets/${id}"""
 val path = route(FakeRequest(GET, url)).get
 val validation = new ValidationForPetexpandedYamlfindPetById(id).result
 lazy val validations = validation.left.get flatMap {
 _.messages map { m => contentAsString(path).contains(m) ?= true }
 }
 ("given an URL: [" + url + "]") |: all(
 status(path) ?= BAD_REQUEST,
 contentType(path) ?= Some("application/json"),
 validation.isLeft ?= true,
 all(validations:_*)
 )
 }
  • 52. Controllers private val findPetByIdResponseMimeType = "application/json"
 private val findPetByIdActionSuccessStatus = Status(200)
 
 private type findPetByIdActionRequestType = (Long)
 private type findPetByIdActionResultType = Pet
 private type findPetByIdActionType = findPetByIdActionRequestType => Either[Throwable, findPetByIdActionResultType]
 
 private def errorToStatusfindPetById: PartialFunction[Throwable, Status] = PartialFunction.empty[Throwable, Status]
 
 def findPetByIdAction = (f: findPetByIdActionType) => (id: Long) => Action {
 val result = new ValidationForPetexpandedYamlfindPetById(id).result.right.map {
 processValidfindPetByIdRequest(f)
 }
 implicit val marshaller = parsingErrors2Writable(findPetByIdResponseMimeType)
 val response = result.left.map { BadRequest(_) }
 response.fold(a => a, c => c)
 }
 
 private def processValidfindPetByIdRequest(f: findPetByIdActionType)(request: findPetByIdActionRequestType) = {
 val callerResult = f(request)
 val status = callerResult match {
 case Left(error) => (errorToStatusfindPetById orElse defaultErrorMapping)(error)
 case Right(result) => findPetByIdActionSuccessStatus
 }
 implicit val findPetByIdWritableJson = anyToWritable[findPetByIdActionResultType](findPetByIdResponseMimeType)
 status(callerResult)
 }
  • 53. Skeletons class PetexpandedYaml extends PetexpandedYamlBase {
 
 // handler for GET /pets
 def findPets = findPetsAction { in : (Option[Seq[String]], Option[Int]) =>
 val (tags, limit) = in
 ???
 }
 
 // handler for POST /pets
 def addPet = addPetAction { in : (NewPet) =>
 val (pet) = in
 ???
 }
 
 // handler for GET /pets/{id}
 def findPetById = findPetByIdAction { in : (Long) =>
 val (id) = in
 ???
 }
 
 // handler for DELETE /pets/{id}
 def deletePet = deletePetAction { in : (Long) =>
 val (id) = in
 ???
 }
 }