QwalKeko, a History Querying Tool

30
QwalKeko, a History Querying Tool Reinout Stevens [email protected] @ReinoutStevens 1 1

Transcript of QwalKeko, a History Querying Tool

QwalKeko, a History Querying Tool

Reinout [email protected]@ReinoutStevens

1

1

Motivation

•Commit Changes•Undo Changes•Retrieve Changes•Branch & Merge

2

2

Motivation’

~6600 commits~1000 source files

3

3

Concrete Examplepublic class Example { WebDriver driver; @BeforeTest public void startDriver(){ driver = new FirefoxDriver(); }

@AfterTest public void stopDriver(){ driver.quit(); }

@Test public void testTitle(){ driver.get("http://www.google.com"); WebElement element = driver.findElement(By.name("q")); element.sendKeys("Cheese!"); element.submit(); assertEquals(driver.getTitle(), "Cheese!"); }}

Prevalence and Maintenance of Automated Functional Tests for Web Applications Laurent Christophe, Reinout Stevens, Coen De Roover and Wolfgang De MeuterProceedings of the 30th International Conference on Software Maintenance and Evolution (ICSMe14), Victoria (Canada)

4

4

Concrete Example’public class Example { WebDriver driver; @BeforeTest public void startDriver(){ driver = new FirefoxDriver(); }

@AfterTest public void stopDriver(){ driver.quit(); }

@Test public void testTitle(){ driver.get("http://www.google.com"); WebElement element = driver.findElement(By.name("q")); element.sendKeys("Cheese!"); element.submit(); assertEquals(driver.getTitle(), "Cheese!"); }}

• Assertion

• Command

• Constant

• Location

• Demarcator

5

5

6

1. Do Selenium-based functional tests co-evolve with the web application? For how long is such a test maintained as the application evolves over time?

2. How are Selenium-based functional tests maintained? Which parts of a functional test are most prone to changes?

6

End Result●

0.0

0.1

0.2

0.3

0.4

assertion command constant demarcator locationChange Classification

Cha

nge

Hit

Rat

io

7

7

Necessary Steps

1) Identify modified Selenium files

2) Compute changes made to the file

3) Classify changes made to the file

8

8

QwalKeko

Version 1 Version 2

Version 3a

Version 4a

Version 3b

Version 4b

Version 5

Specify Source Code Conditionsusing Ekeko

Move through Graph

Reason over Changes9

transformed

9

Ekeko... specify code characteristics through Ekeko relations

collection of all substitutions for ?s and ?e

such that the following Ekeko relations hold:

has/3 holds for :expression, ?s, and ?e

ast/2 holds for :ReturnStatement, ?s

ast/2 holds for :NullLiteral, ?e

(ekeko* [?s ?e] (ast :ReturnStatement ?s) (has :expression ?s ?e) (ast :NullLiteral ?e))

?e is the value of the property named :expression

of ASTNode ?s

actual search performed by core.logic

([#<ReturnStatement return null; #<NullLiteral null>] ... [#<ReturnStatement return null; #<NullLiteral null>])

([?s1 ?e2] ... [?sn ?en])

10

10

Compute Changes

1 (qwalkeko* [?left-cu ?right-cu ?change]2 (qwal graph start ?end 3 (in-source-code [curr]4 (ast :CompilationUnit ?left-cu))

5 q=>

6 (in-source-code7 (compilationunit|corresponding ?left-cu ?right-cu)8 (change ?change ?left-cu ?right-cu))))

start

?end

}

}

11

11

AST Changes

Beat Fluri and Harald C. Gall. Classifying Change Types for Qualifying Change Couplings. In Proceedings of the 14th International Conference on Program Comprehension, 2006.

A

B C

D E

α’

C

E D

F

B

A

D

F

Delete

Update

Move

Insert

12

12

0.0

0.1

0.2

0.3

0.4

assertion command constant demarcator locationChange Classification

Cha

nge

Hit

Rat

io

Steps

1. Identify Selenium Files

2. Compute Changes

3. Classify Changes

13

13

Identify Selenium File

1 (defn compilationunit|selenium [?cu]2 (fresh [?imp ?impname ?str]3 (ast :CompilationUnit ?cu)4 (child :imports ?cu ?imp)5 (has :name ?imp ?impname)6 (name|qualified-string ?impname ?str)7 (succeeds (string-contains ?str ".selenium"))))

14

14

Identifying all Selenium Files

1 (qwalkeko* [?info ?cu ?end]2 (qwal graph start ?end3 q=>* 4 (in-source-code [current]5 (file|added ?info current)6 (file|compilationunit ?info ?cu current)7 (compilationunit|selenium ?cu))))

{:status :add, :file ".../ExperimentPage.java"} #<CompilationUnit package uk.ac.ebi.atlas.acceptance.selenium.pages;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;...> #<Metaversion-867a3be00501e415bc081f25032b273f44713672>

15

start

?end

...

15

16

Do Selenium-based functional tests co-evolve with the web application? For how long is such a test maintained as

the application evolves over time?

16

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●

●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●

●●●●●●

●●

●●●●●

●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●

●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●

●●●

●●●●●●●●●●●●●●●●●●

●●●●●●●●●

●●●●●●

●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●

●●●●●●●●●●●●●●

●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●

●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●● ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●

●●

●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●

●●●●

●●

●●

●●●●●●●●●●●●

●●

●●

●●●●●●●●●●●●●●●●●

●●

●●●●●

●●●●

●●●●●●●●●●●●●●●●●●●

0

500

1000

1500

0 500 1000 1500 2000CommitId

FileId

ChangeType● added−regularadded−seleniumdelete−regulardelete−seleniumedit−regularedit−selenium

17

17

18

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●● ●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●● ●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●● ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●● ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●

●●●●●

●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●

●●●● ●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

● ●●●●●●●

0

500

1000

1500

2000

0 250 500 750CommitId

FileId

ChangeType ● added−regular added−selenium delete−regular delete−selenium edit−regular edit−selenium

18

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●

●●●●●●● ●●●●●●●●●●●●●●

●●●●●● ●●●●●●●●●●● ●●●●●●●● ●●●●●●● ● ●●●●●●● ●●●●●●● ●●●●●●●●●

●●●●●●●●●●●●● ●●●●●●●● ● ●●●●●●●●●●●●●●●●●● ●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ● ●●●● ●●●●●●●●●●●●●●●●●

●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● ●●● ●●●●● ●● ●●●●● ●●●●●●●●● ●● ●●●●●● ●●●●●●●●●●●●●●●

● ●● ●●●●●● ● ●●● ●●●●

0

500

1000

0 500 1000 1500CommitId

FileId

19

19

20

How are Selenium-based functional tests maintained? Which parts of a functional test are most prone to

changes?

20

Rememberpublic class Example { WebDriver driver; @BeforeTest public void startDriver(){ driver = new FirefoxDriver(); }

@AfterTest public void stopDriver(){ driver.quit(); }

@Test public void testTitle(){ driver.get("http://www.google.com"); WebElement element = driver.findElement(By.name("q")); element.sendKeys("Cheese!"); element.submit(); assertEquals(driver.getTitle(), "Cheese!"); }}

• Assertion

• Command

• Constant

• Location

• Demarcator

21

21

1 (qwalkeko* [?change ?info ?end ?type]2 (qwal graph start ?end [?left-cu ?right-cu]3 (in-source-code [curr]4 (file|selenium|edit ?info curr))5 (file|compilationunit ?info ?right-cu curr))

6 q<= ;;move backwards

7 (in-source-code [curr]8 (compilationunit|corresponding ?right-cu ?left-cu))9 (change ?change ?left-cu ?right-cu)0 (classify-change ?change ?type))))

Classify Change

22

22

Classify Location01 ;;driver.findElement(By.name("q"));02 (defn methodinvocation|by [?x]03 (fresh [?name]04 (ast :MethodInvocation ?x)05 (child :expression ?x ?name)06 (name|simple-string ?name "By")))07 08 09 (defn change|affects-findBy [change ?find-by]10 (all11 (change|affects-node change ?find-by)12 (methodinvocation|by ?find-by)))

23

23

Result●

0.0

0.1

0.2

0.3

0.4

assertion command constant demarcator locationChange Classification

Cha

nge

Hit

Rat

io

24

24

Other Applications

25

• Detect Refactorings

• Verification of Development Practices

A History Querying Tool and its Application to Detect Multi-version Refactorings Reinout Stevens, Coen De Roover, Carlos Noguera, Viviane Jonckers

Proceedings of the 17th European Conference on Software Maintenance and Reengineering (CSMR 2013), Early Research Achievements Track, Genova (Italy)

A Logic Foundation for a General-Purpose History Querying Tool Reinout Stevens, Coen De Roover, Carlos Noguera, Andy Kellens, Viviane Jonckers

Elsevier Journal on Science of Computer Programming

25

Pulled up Method

Version 1

Version 2

DerivedClass

Method()BaseClass

Method()DerivedClass

BaseClass

26

26

Pulled up Method

(ast :MethodDeclaration ?method)(declaring-class ?method ?derived) Version 1

Version 2

Template-based Reconstruction of Complex RefactoringsKyle Prete, Napol Rachatasumrit, Nikita Sudan, Miryung KimInternational Conference on Software Maintenance (ICSM), p.1--10, 2010

(method-moved ?method ?pulled)(declaring-class ?pulled ?base)(superclass ?base ?derived)

27

27

Pulled Up Method’

Version 1

Version 2

(in-source-code (ast :MethodDeclaration ?method) (declaring-class ?method ?derived))

(qwal graph version1 version2

q=> ;;transition to next version

(in-source-code (method-moved ?method ?pulled) (declaring-class ?pulled ?base) (superclass ?base ?derived)))

28

28

Multiversion Refactorings

(in-source-code (ast :MethodDeclaration ?method) (declaring-class ?method ?derived))

(qwal graph version1 ?versionX

(q=>+) ;;skip >= 1 versions

(in-source-code (method-moved ?method ?pulled) (declaring-class ?pulled ?base) (superclass ?base ?derived)))

Version 1

Version X

...

29

29

Conclusion

• Express conditions on a single version

• Express transitions between versions

• Express conditions on changes between two versions

[email protected]@ReinoutStevens

https://github.com/ReinoutStevens/damp.qwalkeko/https://github.com/ReinoutStevens/ChangeNodes/

https://github.com/cderoove/damp.ekeko

30

30