Top Banner
Improving Test Case Generation for Web Applications Using Automated Interface Discovery William G.J. Halfond and Alessandro Orso Georgia Institute of Technology
40

Improving Test Case Generation for Web Applications Using ...

Jan 28, 2017

Download

Documents

duongthu
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Improving Test Case Generation for Web Applications Using ...

Improving Test Case Generationfor Web Applications Using

Automated Interface Discovery

William G.J. Halfond andAlessandro Orso

Georgia Institute of Technology

Page 2: Improving Test Case Generation for Web Applications Using ...

Web Application Overview

DB

Other Systems

Web Server

End Users

Requesthttp://host?login=alice&pin=1234

HTML Pages

WebApplication

HTML

Servlets

Page 3: Improving Test Case Generation for Web Applications Using ...

public void write(File outfile, String buffer, int length)

Testing Web Applications

Domain information

Parameter grouping

Page 4: Improving Test Case Generation for Web Applications Using ...

Testing Web Applicationsvoid main(Request req)

String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin) // generate second registration pageelse if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else // generate initial registration page

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 5: Improving Test Case Generation for Web Applications Using ...

Testing Web Applicationsvoid main(Request req)

String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin) // generate second registration pageelse if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else // generate initial registration page

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 6: Improving Test Case Generation for Web Applications Using ...

Testing Web Applicationsvoid main(Request req)

String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin) // generate second registration pageelse if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else // generate initial registration page

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 7: Improving Test Case Generation for Web Applications Using ...

Testing Web Applicationsvoid main(Request req)

String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin) // generate second registration pageelse if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else // generate initial registration page

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 8: Improving Test Case Generation for Web Applications Using ...

Testing Web Applicationsvoid main(Request req)

String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin) // generate second registration pageelse if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else // generate initial registration page

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 9: Improving Test Case Generation for Web Applications Using ...

Testing Web Applicationsvoid main(Request req)

String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin) // generate second registration pageelse if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else // generate initial registration page

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 10: Improving Test Case Generation for Web Applications Using ...

Developer-specified modelsRicca and Tonella, ICSE 2001

Approaches toWeb Application Testing

Captured user-sessionsKallepalli and Tian, TSE 2001

Sprenkle et. al., ASE 2006Elbaum et. al., ICSE 2003

Black-box analysisHuang et. al., WWW 2003

Elbaum et. al., WODA 2006

Static code analysisDeng et al., SEN 2004

Page 11: Improving Test Case Generation for Web Applications Using ...

Goal of Our Approach

Develop a technique to automatically discoverall of the interfaces to a web application

Interfaces

WebApplication

HTML

Servlets • Input parameters• Domain information

Page 12: Improving Test Case Generation for Web Applications Using ...

Presentation Outline

• Definitions• Interface Discovery Algorithm• Empirical Evaluation• Conclusions and Future Work

Page 13: Improving Test Case Generation for Web Applications Using ...

Definitions:1. Input Parameter

void main(Request req)String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin)else if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

http://host?login=alice&pin=1234

Page 14: Improving Test Case Generation for Web Applications Using ...

Definitions:1. Input Parameter2. Parameter Function

void main(Request req)String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin)else if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 15: Improving Test Case Generation for Web Applications Using ...

Definitions:1. Input Parameter2. Parameter Function3. Domain Operations

void main(Request req)String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin)else if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 16: Improving Test Case Generation for Web Applications Using ...

Definitions:1. Input Parameter2. Parameter Function3. Domain Operations4. Web Interface

void main(Request req)String formAction = req.getParam(“formAction”)if (formAction.equals(“chooseLogin”)) String requestedLogin = req.getParam(“login”) int pin = getNumParam(req, “pin”) registerLogin(requestedLogin, pin)else if (formAction.equals(“personalInfo”)) String name = req.getParam(“name”) int zip = getNumParam(req, “zip”) if (zip == 30318) finishRegistration(id, name) else error(“You do not live in 30318”)else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Page 17: Improving Test Case Generation for Web Applications Using ...

Interface Discovery Algorithm

Phase 1: Compute domain information foreach Input Parameter

Phase 2: Identify names of Input Parametersand group them into distinct interfaces

Phase 1 Phase 2 Interfaces

WebApplication

HTML

Servlets

Page 18: Improving Test Case Generation for Web Applications Using ...

Phase 1: Compute Domain Information

For each call to a Parameter Function:1. Infer domain information by

• Following def-use chains involving the return value• Considering operations performed on the uses

2. Annotate call site accordingly

WebApplicationwith domaininformationannotations

WebApplication

HTML

Servlets

Phase 1

Page 19: Improving Test Case Generation for Web Applications Using ...

Phase 1Extract domain

information.

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParameter("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318" )else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

Numeric

Numeric

Numeric“30318”

String“chooseLogin”“personalInfo”

String

String

Page 20: Improving Test Case Generation for Web Applications Using ...

Phase 2: Compute Interfaces

For each method m:1. Discover Input Parameter names2. Identify sets of Input Parameters accessed along a path3. For each set, add to m’s summary an interface consisting of

• Input Parameters in the set• Corresponding domain information

WebApplicationwith domaininformationannotations

Phase 2 Interfaces

Page 21: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

String“chooseLogin”“personalInfo”

String

Numeric

Numeric

Numeric“30318”

String

Page 22: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

paramName:Numeric

String“chooseLogin”“personalInfo”

String

Numeric

Numeric“30318”

String

Page 23: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

int getNumParam(Request req, String paramName)String paramValue = req.getParam(paramName)int param = Integer.parseInt(paramValue)return param

String“chooseLogin”“personalInfo”

String

Numeric

Numeric“30318”

String

fp(2):Numeric

Page 24: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

String“chooseLogin”“personalInfo”

String

Numeric

Numeric“30318”

String

getNumParam(Request req, String paramName) fp(2):Numeric

Page 25: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

login:String

formAction:String“chooseLogin”“personalInfo”

pin:Numeric

zip:Numeric“30318”

name:String

getNumParam(Request req, String paramName) fp(2):Numeric

Page 26: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

login:String

formAction:String“chooseLogin”“personalInfo”

pin:Numeric

zip:Numeric“30318”

name:String

getNumParam(Request req, String paramName) fp(2):Numeric

Servlet Interfaces:(formAction, login, pin)

Page 27: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

login:String

formAction:String“chooseLogin”“personalInfo”

pin:Numeric

zip:Numeric“30318”

name:String

getNumParam(Request req, String paramName) fp(2):Numeric

Servlet Interfaces:(formAction, login, pin)(formAction, name, zip)

Page 28: Improving Test Case Generation for Web Applications Using ...

void main(Request req)String formAction = req.getParam("formAction”)if (formAction.equals("chooseLogin” )) String requestedLogin = req.getParam("login") int pin = getNumParam(req, "pin") registerLogin(requestedLogin, pin)else if (formAction.equals("personalInfo")) String name = req.getParam("name") int zip = getNumParam(req, "zip") if (zip == 30318) finishRegistration(id, name) else error("You do not live in 30318")else …

login:String

formAction:String“chooseLogin”“personalInfo”

pin:Numeric

zip:Numeric“30318”

name:String

getNumParam(Request req, String paramName) fp(2):Numeric

Servlet Interfaces:(formAction, login, pin)(formAction, name, zip)(formAction)

Page 29: Improving Test Case Generation for Web Applications Using ...

Servlet Interfaces

“personalInfo”“chooseLogin”StringformAction3

“30318”Numericpin-Stringlogin

“personalInfo”“chooseLogin”StringformAction

2

-Numericpin-Stringlogin

“personalInfo”“chooseLogin”StringformAction

1

Relevant ValuesDomain-TypeNameInterface

Page 30: Improving Test Case Generation for Web Applications Using ...

Empirical Evaluation

• Research Question 1: Does our techniquediscover a higher number of interfaces than aconventional approach?

• Research Question 2: Does testingeffectiveness improve when using interfaceinformation generated by our techniqueinstead of a conventional approach?

Page 31: Improving Test Case Generation for Web Applications Using ...

Prototype Implementation - WAM

• Analyzes bytecode of Web applicationservlets

• Targets Java Enterprise Edition (JEE)• Uses several analysis libraries and tools• Call and control-flow graphs: SOOT• Data-dependency: INDUS• Resolving string values: JSA

Page 32: Improving Test Case Generation for Web Applications Using ...

Spider Implementation

• Crawl pages and links of a web application• Parse HTML to get interface information• Extract <form> and <input> elements• Record default values

• Based on OWASP WebScarab Project• Widely used code-base• Actively maintained

Page 33: Improving Test Case Generation for Web Applications Using ...

Evaluation Subjects

Subject LOC Servlets

Bookstore 19,402 28

Checkers 5,415 33

Classifieds 10,702 19

Employee Directory 5,529 11

Events 7,164 13

Office Talk 4,670 38

Portal 16,089 28

Page 34: Improving Test Case Generation for Web Applications Using ...

Research Question 1 — Results

Number of Discovered Interfaces

0

5

10

15

20

25

30

35

Boo

ksto

re

Che

cker

s

Class

ified

s

Office

Talk

Por

tal

Em

ploy

ee D

ir.

Event

s

# I

nte

rfa

ce

s

spider

wam

Page 35: Improving Test Case Generation for Web Applications Using ...

Research Question 2: Compare Coverage

1. Instrument web applications• Statement• Branch• Database Command-form

2. Generate test inputs with interfaceinformation

3. Run test inputs against applications

Page 36: Improving Test Case Generation for Web Applications Using ...

Block Coverage

0

20

40

60

80

100

Boo

ksto

re

Che

cker

s

Cla

ssified

s

Employ

ee D

ir.

Event

s

Porta

l

Office

Talk

Pe

rce

nt

Co

ve

rag

e

Spider

WAM

Research Question 2 – Results

Average increase: 30%

Page 37: Improving Test Case Generation for Web Applications Using ...

Branch Coverage

0

20

40

60

80

100

Boo

ksto

re

Che

cker

s

Cla

ssified

s

Employ

ee D

ir.

Event

s

Porta

l

Office

Talk

Pe

rce

nt

Co

ve

rag

e

Spider

WAM

Research Question 2 – Results

Average increase: 48%

Page 38: Improving Test Case Generation for Web Applications Using ...

Database Command-form Coverage

020406080

100120140160180

Boo

ksto

re

Che

cker

s

Cla

ssified

s

Employ

ee D

ir.

Event

s

Porta

l

Office

Talk

# o

f C

om

man

d-f

orm

s

Spider

WAM

Research Question 2 – Results

Average increase: 94%

Page 39: Improving Test Case Generation for Web Applications Using ...

Conclusions & Future Work

• Fully automated static analysis technique fordiscovering web application interfaces

• Empirical evaluation against Spider• Discovered higher number of interfaces• Led to test inputs with higher coverage

• Future work includes:• Apply symbolic execution to improve domain

information• Improve automated modeling of web applications

Page 40: Improving Test Case Generation for Web Applications Using ...

Questions?