SlideShare ist ein Scribd-Unternehmen logo
1 von 36
Downloaden Sie, um offline zu lesen
ROTTEN GREEN TESTS
(FROM ICSE’19)
J. Delplanque, S. Ducasse, G. Polito, A. P. Black
and A. Etien
Univ. Lille, CNRS, Centrale Lille, Inria, UMR 9189 - CRIStAL
Dept of Computer Science, Portland State University, Oregon, USA
1
WHAT IS A ROTTEN
GREEN TEST?
2
ANATOMY OF A TEST
SetTest » testSetAdd
| s |
s := Set new.
s add: 1.
s add: 1.
self assert: s size equals: 1.
self assert: (s includes: 1)
3
In Pharo
s add: 1. <=> s.add(1);
class SetTest {

method testSetAdd {
def s = Set.new()
s.add(1)
s.add(1)
self.assertEquals(s.size(),1)
self.assert(s.includes(1))

}
}
ANATOMY OF A SMOKE TEST
SetTest » testSetAddSmokeTest
| s |
s := Set new.
s add: 1.
s add: 1
➤ No assertion
➤ Not a rotten green test
4
A ROTTEN GREEN TEST IS
➤ A test passing (green)
➤ A test that contains at least one assertion
➤ One or more assertions is not executed when test runs
5
A LITTLE SKETCH OF A ROTTEN GREEN TEST
class RottenTest {

method testABC {

if (false) then {self.assert(x)}

}
}
A REAL ONE
TPrintOnSequencedTest » testPrintOnDelimiter
| aStream result allElementsAsString |
result := ''.
aStream := ReadWriteStream on: result.
self nonEmpty printOn: aStream delimiter: ', '.
allElementsAsString := result findBetweenSubstrings: ', ‘.
allElementsAsString withIndexDo: [:el :i |
self assert: el equals: ((self nonEmpty at:i) asString) ]
A REAL ONE
TPrintOnSequencedTest » testPrintOnDelimiter
| aStream result allElementsAsString |
result := ''.
aStream := ReadWriteStream on: result.
self nonEmpty printOn: aStream delimiter: ', '.
allElementsAsString := result findBetweenSubstrings: ', ‘.
allElementsAsString withIndexDo: [:el :i |
self assert: el equals: ((self nonEmpty at:i) asString) ]
Not executed!
TPrintOnSequencedTest » testPrintOnDelimiter
| aStream result allElementsAsString |
result := ''.
aStream := ReadWriteStream on: result.
self nonEmpty printOn: aStream delimiter: ', '.
allElementsAsString := result findBetweenSubstrings: ', '.
allElementsAsString withIndexDo: [:el :i |
self assert: el equals: ((self nonEmpty at:i) asString) ]
The programmer believed that the object on which the
stream is working is “magically” mutated on stream growth
‘’result
stream.collection
‘a’
10
Iterator does not run
result stays empty
ROTTEN GREEN TEST WRITERS
➤ Rotten green tests are NOT intentional
➤ We say: this is not the programmer’s fault
➤ Instead: it is the fault of testing tools that do not
report them
11
WHY ARE ROTTEN GREEN TESTS BAD?
➤ Give a false sense of security
➤ Can easily pass unnoticed
➤ Not reported by testing frameworks prior to DrTest
12
MAINLY CAUSED BY
➤ Conditional code not executing a branch
➤ Iterating over an empty collection
13
HOW TO IDENTIFY THEM?
14
HANDLING HELPERS
class RottenTest {

method testABC {

if (false) then {self.helper()}

}
method helper {

self.secondHelper()

}
method secondHelper {

self.assert(x)

}
}
15
HANDLING HELPERS
class RottenTest {

method testABC {

if (false) then {self.helper()}

}
method helper {

self.secondHelper()

}
method secondHelper {

self.assert(x)

}
}
16
Not executed!
Not executed!
ABOUT THE NEED FOR CALL SITE ANALYSIS
17
class RottenTest {

method testDEF {

self.badHelper()

self.assert(true)

}
method badHelper {

if (false) then {

self.secondHelper()

}

}
method secondHelper {

self.assert(x)

}
}
ABOUT THE NEED FOR CALL SITE ANALYSIS
18
class RottenTest {

method testDEF {

self.badHelper()

self.assert(true)

}
method badHelper {

if (false) then {

self.secondHelper()

}

}
method secondHelper {

self.assert(x)

}
}
Executed!
Not executed!
Not executed!
IDENTIFYING ROTTEN GREEN TESTS
➤ We use both
➤ Static analysis, to identify helpers and
inherited methods
➤ Dynamic analysis, to identify call sites that are
not executed
19
IDENTIFYING ROTTEN GREEN TESTS
➤ Static Analysis
➤ Identify “testing primitives” (assert:, deny:…)
➤ Identify helper methods (abstract interpreter)
➤ Dynamic Analysis through instrumentation
➤ Instrument the call-sites of the “test primitives”
➤ Run the test suite
➤ Record green tests whose test primitives are not
executed
➤ Generate Report
20
BEFORE TEST EXECUTION: FIRST IDENTIFYING THE HELPERS
21
class RottenTest {

method testDEF {

self.badHelper()

self.assert(true)

}
method badHelper {

if (false) then {

self.secondHelper()

}

}
method secondHelper {

self.assert(x)

}
}
BEFORE TEST EXECUTION: FIRST IDENTIFYING THE HELPERS
22
class RottenTest {

method testDEF {

self.badHelper()

self.assert(true)

}
method badHelper {

if (false) then {

self.secondHelper()

}

}
method secondHelper {

self.assert(x)

}
}
is an helper
is an helper
BEFORE TEST EXECUTION: INSTALLING CALL SITE SPIES
23
class RottenTest {

method testDEF {

self.badHelper()

self.assert(true)

}
method badHelper {

if (false) then {

self.secondHelper()

}

}
method secondHelper {

self.assert(x)

}
}
spy
spy
AT EXECUTION
24
class RottenTest {

method testDEF {

self.badHelper()

self.assert(true)

}
method badHelper {

if (false) then {

self.secondHelper()

}

}
method secondHelper {

self.assert(x)

}
}
spy
spy
spy
spy
CASE STUDIES (CHECK THE PAPER)
➤ 19,905 tests analysed on mature projects
➤ 294 rotten (25 fully rotten)
25
RESULTS
➤ Missing fail: test passes false to assert:, instead of using fail
➤ Missed skip: test contains guards to stop its execution early
(under certain conditions), instead of using skip
➤ Context-dependent logic: complex logic with different
assertions in different branches — some may be rotten too
➤ Fully rotten: other tests that do not execute one or more
assertions
26
MISSED FAIL
➤ Test passes false to assert:, instead of using fail
TSequencedElementAccessTest » test0FixtureSequencedElementAccessTest
self moreThan4Elements.
self assert: self moreThan4Elements size >= 4.
self subCollectionNotIn
detect: [:each | (self moreThan4Elements includes: each) not]
ifNone: [ self assert: false ].
self elementNotInForElementAccessing.
self deny: (self moreThan4Elements includes: self
elementNotInForElementAccessing).
self elementInForElementAccessing.
self assert: (self moreThan4Elements includes: self
elementInForElementAccessing)
self fail
27
SOLVING MISSING FAIL
➤ Test passes false to assert:
➤ Check on a case by case basis
➤ Use fail to really indicate that the assertion should not be
executed
28
MISSED SKIP
➤ Test contains guards to stop its execution early (under certain
conditions), instead of using skip
OCContextTempMappingTest »
testAccessingArgOfOuterBlockFromAnotherDeepBlock
| actual |
"Check source code availability; do not fail on images without sources"
thisContext method hasSourceCode
ifTrue: [ ^ self ].
actual := [:outerArg | outerArg asString.
[ :innerArg | innerArg asString.
thisContext tempNamed: #outerArg ] value: #innerValue.
] value: #outerValue.
self assert: actual equals: #outerValue
[self skip]
29
SOLVING MISSED SKIP
➤ Test contains guards to stop its execution early (under certain
conditions), instead of using skip
➤ Easy to fix: use self skip
➤ Runner can then report correctly
30
CONTEXT DEPENDENT LOGIC
➤ Complex logic with different assertions in different branches —
some may be rotten too
FLBasicSerializationTest » testCharacter
"Test character serialization. If the code is less than 255 the
same instance is used. But if it is bigger, new ones are
created."
self assertSerializationIdentityOf: $a.
FLPlatform current isSpur
ifTrue: [ self assertSerializationIdentityOf: (Character value: 12345).
"Japanese Hiragana 'A' " ]
ifFalse: [ self assertSerializationEqualityOf: (Character value: 12345).
"Japanese Hiragana 'A' " ].
self assertSerializationEqualityOf: Character allCharacters.
self assertSerializationEqualityOf: (Array with: $a with: (Character value:
12345)).
31
SOLVING CONTEXT DEPENDENT LOGIC
➤ Complex logic with different assertions in different branches
— some may be rotten too
➤ How to fix:
➤ create a separate test for each branch
➤ use self skip to execute the test only when it applies
32
FULLY ROTTEN TESTS
➤ Other tests that do not execute one or more assertions
testFamixPackageNamespace
self
should: [ self assert: self packReferee ]
raise: Error
➤ packageP5FullReferee did raise Error, so assert: is never
invoked!
33
testFamixPackageNamespace {
try{
self.assert(self.packReferee())
self.fail()
} catch(Error e){ }
}
FULLY ROTTEN
➤ Other tests that do not execute one or more assertions
MustBeBooleanTests » testAnd (original)
| myBooleanObject |
myBooleanObject := MyBooleanObject new.
self deny: (myBooleanObject and: [true])
➤ Compiled method bytecode was dynamically rewritten by the
compiler as:
MustBeBooleanTests » testAnd (rewritten)
| myBooleanObject |
myBooleanObject := MyBooleanObject new.
^ (myBooleanObject) and: [ true ]
Oops the deny: disappeared!
34
SOLVING FULLY ROTTEN
➤ Case-by-case analysis and repair
35
CONCLUSION
➤ Rotten Green Tests exist. Yes M’dam
➤ Every Unit-testing framework should report them
➤ DrTests the new Pharo Unit framework reports them
➤ Working on Java and Python replication
➤ Found many of them in great Java frameworks :)
➤ Looking for extra case studies
36

Weitere ähnliche Inhalte

Was ist angesagt?

TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingDavid Rodenas
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214David Rodenas
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test frameworkAbner Chih Yi Huang
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentationnicobn
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingDavid Rodenas
 
Debug - MITX60012016-V005100
Debug - MITX60012016-V005100Debug - MITX60012016-V005100
Debug - MITX60012016-V005100Ha Nguyen
 
GTAC 2014: What lurks in test suites?
GTAC 2014: What lurks in test suites?GTAC 2014: What lurks in test suites?
GTAC 2014: What lurks in test suites?Patrick Lam
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYCMike Dirolf
 
C++ exception handling
C++ exception handlingC++ exception handling
C++ exception handlingRay Song
 
EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++Prof Ansari
 
Mutation Testing - Ruby Edition
Mutation Testing - Ruby EditionMutation Testing - Ruby Edition
Mutation Testing - Ruby EditionChris Sinjakli
 
Exception handling and templates
Exception handling and templatesException handling and templates
Exception handling and templatesfarhan amjad
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8Sergiu Mircea Indrie
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnitJace Ju
 

Was ist angesagt? (20)

TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving Testing
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012
 
Bsit1
Bsit1Bsit1
Bsit1
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: Testing
 
Debug - MITX60012016-V005100
Debug - MITX60012016-V005100Debug - MITX60012016-V005100
Debug - MITX60012016-V005100
 
GTAC 2014: What lurks in test suites?
GTAC 2014: What lurks in test suites?GTAC 2014: What lurks in test suites?
GTAC 2014: What lurks in test suites?
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
 
C++ exception handling
C++ exception handlingC++ exception handling
C++ exception handling
 
Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
 
EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++EXCEPTION HANDLING in C++
EXCEPTION HANDLING in C++
 
GMock framework
GMock frameworkGMock framework
GMock framework
 
Mutation Testing - Ruby Edition
Mutation Testing - Ruby EditionMutation Testing - Ruby Edition
Mutation Testing - Ruby Edition
 
Exception handling and templates
Exception handling and templatesException handling and templates
Exception handling and templates
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Beginning PHPUnit
Beginning PHPUnitBeginning PHPUnit
Beginning PHPUnit
 

Ähnlich wie Rotten Green Tests

Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in LaravelAhmed Yahia
 
STAMP Descartes Presentation
STAMP Descartes PresentationSTAMP Descartes Presentation
STAMP Descartes PresentationSTAMP Project
 
System Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancementsSystem Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancementsSubash John
 
The Art of Identifying Vulnerabilities - CascadiaFest 2015
The Art of Identifying Vulnerabilities  - CascadiaFest 2015The Art of Identifying Vulnerabilities  - CascadiaFest 2015
The Art of Identifying Vulnerabilities - CascadiaFest 2015Adam Baldwin
 
property-based testing (FrOsCon 9, 2014, August 23)
property-based testing (FrOsCon 9, 2014, August 23)property-based testing (FrOsCon 9, 2014, August 23)
property-based testing (FrOsCon 9, 2014, August 23)Christoph Neuroth
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
Introduction To Testing With Perl
Introduction To Testing With PerlIntroduction To Testing With Perl
Introduction To Testing With Perljoshua.mcadams
 
Pitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz BankowskiPitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz BankowskiAgileee
 
Introduction to Julia
Introduction to JuliaIntroduction to Julia
Introduction to Julia岳華 杜
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!Thoughtworks
 
#codemotion2016: Everything you should know about testing to go with @pedro_g...
#codemotion2016: Everything you should know about testing to go with @pedro_g...#codemotion2016: Everything you should know about testing to go with @pedro_g...
#codemotion2016: Everything you should know about testing to go with @pedro_g...Sergio Arroyo
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Knowvilniusjug
 
R Programming: Comparing Objects In R
R Programming: Comparing Objects In RR Programming: Comparing Objects In R
R Programming: Comparing Objects In RRsquared Academy
 

Ähnlich wie Rotten Green Tests (20)

Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in Laravel
 
STAMP Descartes Presentation
STAMP Descartes PresentationSTAMP Descartes Presentation
STAMP Descartes Presentation
 
TDD Training
TDD TrainingTDD Training
TDD Training
 
Comp102 lec 5.1
Comp102   lec 5.1Comp102   lec 5.1
Comp102 lec 5.1
 
ppt.pptx
ppt.pptxppt.pptx
ppt.pptx
 
System Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancementsSystem Verilog 2009 & 2012 enhancements
System Verilog 2009 & 2012 enhancements
 
The Art of Identifying Vulnerabilities - CascadiaFest 2015
The Art of Identifying Vulnerabilities  - CascadiaFest 2015The Art of Identifying Vulnerabilities  - CascadiaFest 2015
The Art of Identifying Vulnerabilities - CascadiaFest 2015
 
property-based testing (FrOsCon 9, 2014, August 23)
property-based testing (FrOsCon 9, 2014, August 23)property-based testing (FrOsCon 9, 2014, August 23)
property-based testing (FrOsCon 9, 2014, August 23)
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
ppopoff
ppopoffppopoff
ppopoff
 
Introduction To Testing With Perl
Introduction To Testing With PerlIntroduction To Testing With Perl
Introduction To Testing With Perl
 
Pitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz BankowskiPitfalls Of Tdd Adoption by Bartosz Bankowski
Pitfalls Of Tdd Adoption by Bartosz Bankowski
 
Introduction to Julia
Introduction to JuliaIntroduction to Julia
Introduction to Julia
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!
 
#codemotion2016: Everything you should know about testing to go with @pedro_g...
#codemotion2016: Everything you should know about testing to go with @pedro_g...#codemotion2016: Everything you should know about testing to go with @pedro_g...
#codemotion2016: Everything you should know about testing to go with @pedro_g...
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Know
 
Laravel Unit Testing
Laravel Unit TestingLaravel Unit Testing
Laravel Unit Testing
 
Chapter 00 revision
Chapter 00 revisionChapter 00 revision
Chapter 00 revision
 
R Programming: Comparing Objects In R
R Programming: Comparing Objects In RR Programming: Comparing Objects In R
R Programming: Comparing Objects In R
 

Mehr von ESUG

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingESUG
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in PharoESUG
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapESUG
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoESUG
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...ESUG
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsESUG
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6ESUG
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationESUG
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingESUG
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesESUG
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportESUG
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsESUG
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector TuningESUG
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseESUG
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FutureESUG
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the DebuggerESUG
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing ScoreESUG
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptESUG
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocESUG
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsESUG
 

Mehr von ESUG (20)

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in Pharo
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in Pharo
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector Tuning
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the Debugger
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing Score
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design Mooc
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and Transformations
 

Kürzlich hochgeladen

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 

Kürzlich hochgeladen (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 

Rotten Green Tests

  • 1. ROTTEN GREEN TESTS (FROM ICSE’19) J. Delplanque, S. Ducasse, G. Polito, A. P. Black and A. Etien Univ. Lille, CNRS, Centrale Lille, Inria, UMR 9189 - CRIStAL Dept of Computer Science, Portland State University, Oregon, USA 1
  • 2. WHAT IS A ROTTEN GREEN TEST? 2
  • 3. ANATOMY OF A TEST SetTest » testSetAdd | s | s := Set new. s add: 1. s add: 1. self assert: s size equals: 1. self assert: (s includes: 1) 3 In Pharo s add: 1. <=> s.add(1); class SetTest {
 method testSetAdd { def s = Set.new() s.add(1) s.add(1) self.assertEquals(s.size(),1) self.assert(s.includes(1))
 } }
  • 4. ANATOMY OF A SMOKE TEST SetTest » testSetAddSmokeTest | s | s := Set new. s add: 1. s add: 1 ➤ No assertion ➤ Not a rotten green test 4
  • 5. A ROTTEN GREEN TEST IS ➤ A test passing (green) ➤ A test that contains at least one assertion ➤ One or more assertions is not executed when test runs 5
  • 6.
  • 7. A LITTLE SKETCH OF A ROTTEN GREEN TEST class RottenTest {
 method testABC {
 if (false) then {self.assert(x)}
 } }
  • 8. A REAL ONE TPrintOnSequencedTest » testPrintOnDelimiter | aStream result allElementsAsString | result := ''. aStream := ReadWriteStream on: result. self nonEmpty printOn: aStream delimiter: ', '. allElementsAsString := result findBetweenSubstrings: ', ‘. allElementsAsString withIndexDo: [:el :i | self assert: el equals: ((self nonEmpty at:i) asString) ]
  • 9. A REAL ONE TPrintOnSequencedTest » testPrintOnDelimiter | aStream result allElementsAsString | result := ''. aStream := ReadWriteStream on: result. self nonEmpty printOn: aStream delimiter: ', '. allElementsAsString := result findBetweenSubstrings: ', ‘. allElementsAsString withIndexDo: [:el :i | self assert: el equals: ((self nonEmpty at:i) asString) ] Not executed!
  • 10. TPrintOnSequencedTest » testPrintOnDelimiter | aStream result allElementsAsString | result := ''. aStream := ReadWriteStream on: result. self nonEmpty printOn: aStream delimiter: ', '. allElementsAsString := result findBetweenSubstrings: ', '. allElementsAsString withIndexDo: [:el :i | self assert: el equals: ((self nonEmpty at:i) asString) ] The programmer believed that the object on which the stream is working is “magically” mutated on stream growth ‘’result stream.collection ‘a’ 10 Iterator does not run result stays empty
  • 11. ROTTEN GREEN TEST WRITERS ➤ Rotten green tests are NOT intentional ➤ We say: this is not the programmer’s fault ➤ Instead: it is the fault of testing tools that do not report them 11
  • 12. WHY ARE ROTTEN GREEN TESTS BAD? ➤ Give a false sense of security ➤ Can easily pass unnoticed ➤ Not reported by testing frameworks prior to DrTest 12
  • 13. MAINLY CAUSED BY ➤ Conditional code not executing a branch ➤ Iterating over an empty collection 13
  • 14. HOW TO IDENTIFY THEM? 14
  • 15. HANDLING HELPERS class RottenTest {
 method testABC {
 if (false) then {self.helper()}
 } method helper {
 self.secondHelper()
 } method secondHelper {
 self.assert(x)
 } } 15
  • 16. HANDLING HELPERS class RottenTest {
 method testABC {
 if (false) then {self.helper()}
 } method helper {
 self.secondHelper()
 } method secondHelper {
 self.assert(x)
 } } 16 Not executed! Not executed!
  • 17. ABOUT THE NEED FOR CALL SITE ANALYSIS 17 class RottenTest {
 method testDEF {
 self.badHelper()
 self.assert(true)
 } method badHelper {
 if (false) then {
 self.secondHelper()
 }
 } method secondHelper {
 self.assert(x)
 } }
  • 18. ABOUT THE NEED FOR CALL SITE ANALYSIS 18 class RottenTest {
 method testDEF {
 self.badHelper()
 self.assert(true)
 } method badHelper {
 if (false) then {
 self.secondHelper()
 }
 } method secondHelper {
 self.assert(x)
 } } Executed! Not executed! Not executed!
  • 19. IDENTIFYING ROTTEN GREEN TESTS ➤ We use both ➤ Static analysis, to identify helpers and inherited methods ➤ Dynamic analysis, to identify call sites that are not executed 19
  • 20. IDENTIFYING ROTTEN GREEN TESTS ➤ Static Analysis ➤ Identify “testing primitives” (assert:, deny:…) ➤ Identify helper methods (abstract interpreter) ➤ Dynamic Analysis through instrumentation ➤ Instrument the call-sites of the “test primitives” ➤ Run the test suite ➤ Record green tests whose test primitives are not executed ➤ Generate Report 20
  • 21. BEFORE TEST EXECUTION: FIRST IDENTIFYING THE HELPERS 21 class RottenTest {
 method testDEF {
 self.badHelper()
 self.assert(true)
 } method badHelper {
 if (false) then {
 self.secondHelper()
 }
 } method secondHelper {
 self.assert(x)
 } }
  • 22. BEFORE TEST EXECUTION: FIRST IDENTIFYING THE HELPERS 22 class RottenTest {
 method testDEF {
 self.badHelper()
 self.assert(true)
 } method badHelper {
 if (false) then {
 self.secondHelper()
 }
 } method secondHelper {
 self.assert(x)
 } } is an helper is an helper
  • 23. BEFORE TEST EXECUTION: INSTALLING CALL SITE SPIES 23 class RottenTest {
 method testDEF {
 self.badHelper()
 self.assert(true)
 } method badHelper {
 if (false) then {
 self.secondHelper()
 }
 } method secondHelper {
 self.assert(x)
 } } spy spy
  • 24. AT EXECUTION 24 class RottenTest {
 method testDEF {
 self.badHelper()
 self.assert(true)
 } method badHelper {
 if (false) then {
 self.secondHelper()
 }
 } method secondHelper {
 self.assert(x)
 } } spy spy spy spy
  • 25. CASE STUDIES (CHECK THE PAPER) ➤ 19,905 tests analysed on mature projects ➤ 294 rotten (25 fully rotten) 25
  • 26. RESULTS ➤ Missing fail: test passes false to assert:, instead of using fail ➤ Missed skip: test contains guards to stop its execution early (under certain conditions), instead of using skip ➤ Context-dependent logic: complex logic with different assertions in different branches — some may be rotten too ➤ Fully rotten: other tests that do not execute one or more assertions 26
  • 27. MISSED FAIL ➤ Test passes false to assert:, instead of using fail TSequencedElementAccessTest » test0FixtureSequencedElementAccessTest self moreThan4Elements. self assert: self moreThan4Elements size >= 4. self subCollectionNotIn detect: [:each | (self moreThan4Elements includes: each) not] ifNone: [ self assert: false ]. self elementNotInForElementAccessing. self deny: (self moreThan4Elements includes: self elementNotInForElementAccessing). self elementInForElementAccessing. self assert: (self moreThan4Elements includes: self elementInForElementAccessing) self fail 27
  • 28. SOLVING MISSING FAIL ➤ Test passes false to assert: ➤ Check on a case by case basis ➤ Use fail to really indicate that the assertion should not be executed 28
  • 29. MISSED SKIP ➤ Test contains guards to stop its execution early (under certain conditions), instead of using skip OCContextTempMappingTest » testAccessingArgOfOuterBlockFromAnotherDeepBlock | actual | "Check source code availability; do not fail on images without sources" thisContext method hasSourceCode ifTrue: [ ^ self ]. actual := [:outerArg | outerArg asString. [ :innerArg | innerArg asString. thisContext tempNamed: #outerArg ] value: #innerValue. ] value: #outerValue. self assert: actual equals: #outerValue [self skip] 29
  • 30. SOLVING MISSED SKIP ➤ Test contains guards to stop its execution early (under certain conditions), instead of using skip ➤ Easy to fix: use self skip ➤ Runner can then report correctly 30
  • 31. CONTEXT DEPENDENT LOGIC ➤ Complex logic with different assertions in different branches — some may be rotten too FLBasicSerializationTest » testCharacter "Test character serialization. If the code is less than 255 the same instance is used. But if it is bigger, new ones are created." self assertSerializationIdentityOf: $a. FLPlatform current isSpur ifTrue: [ self assertSerializationIdentityOf: (Character value: 12345). "Japanese Hiragana 'A' " ] ifFalse: [ self assertSerializationEqualityOf: (Character value: 12345). "Japanese Hiragana 'A' " ]. self assertSerializationEqualityOf: Character allCharacters. self assertSerializationEqualityOf: (Array with: $a with: (Character value: 12345)). 31
  • 32. SOLVING CONTEXT DEPENDENT LOGIC ➤ Complex logic with different assertions in different branches — some may be rotten too ➤ How to fix: ➤ create a separate test for each branch ➤ use self skip to execute the test only when it applies 32
  • 33. FULLY ROTTEN TESTS ➤ Other tests that do not execute one or more assertions testFamixPackageNamespace self should: [ self assert: self packReferee ] raise: Error ➤ packageP5FullReferee did raise Error, so assert: is never invoked! 33 testFamixPackageNamespace { try{ self.assert(self.packReferee()) self.fail() } catch(Error e){ } }
  • 34. FULLY ROTTEN ➤ Other tests that do not execute one or more assertions MustBeBooleanTests » testAnd (original) | myBooleanObject | myBooleanObject := MyBooleanObject new. self deny: (myBooleanObject and: [true]) ➤ Compiled method bytecode was dynamically rewritten by the compiler as: MustBeBooleanTests » testAnd (rewritten) | myBooleanObject | myBooleanObject := MyBooleanObject new. ^ (myBooleanObject) and: [ true ] Oops the deny: disappeared! 34
  • 35. SOLVING FULLY ROTTEN ➤ Case-by-case analysis and repair 35
  • 36. CONCLUSION ➤ Rotten Green Tests exist. Yes M’dam ➤ Every Unit-testing framework should report them ➤ DrTests the new Pharo Unit framework reports them ➤ Working on Java and Python replication ➤ Found many of them in great Java frameworks :) ➤ Looking for extra case studies 36