SlideShare a Scribd company logo
New types of tests for
Java projects
Vincent Massol, CTO XWiki SAS, December 2019
Agenda
•Context & Current status quo
•Coverage testing
•Mutation testing
•Environment testing
•Crash reproduction
Context: XWiki
• Open source wiki
• 15 years
• 10-15 active committers
• Very extensible, scripting in wiki pages
• Platform for developing ad-hoc web applications
• Strong build practices using Maven and lots of “Quality” plugins
• Using Jenkins & custom pipeline library for the CI
https://xwiki.org
Context: STAMP
• Automatic Test Amplification
• XWiki SAS participating, 3 years
• Experiments on XWiki project
Mutation testing Environment Testing Production Testing
Current Testing Status
• 10986 automated tests (in 2.5 hours):
• Unit tests (using Mockito)
• Integration tests (using Mockito)
• Functional (UI) tests (using Selenium/Webdriver)
New questions
• Are my tests testing enough? Coverage
• How good are my tests? Mutation testing
• Do my software work in various setups?
Environment testing
• How can I reproduce bugs found in production?
Production testing
= in place w/ strategy = in progress
Test Coverage - Local
• Using Jacoco and Clover
• Strategy - “Ratchet effect”:
• Each Maven module has a threshold
• Jacoco Maven plugin fails if new code
has less coverage than before in %
• Dev is allowed to increase threshold
Of course TPC is not panacea. You
could have 100% and app not
working. Also need functional tests.
Aim for 80%.
Test Coverage - Global
• Issue: Local coverage can increase and
global decrease
• Removed code with high TPC
• Code tested indirectly by functional
tests and code refactoring led to
different paths used
• New module with lower TPC than
average
Global TPC evolution
Test Coverage - Global
• Strategy:
• Global Clover TPC computed automatically every night on
Jenkins for all repos combined, using a pipeline
• Email sent to developers with report in email (see next slide)
• Developers fix module they have been working on
• Release Manager (RM) ensures that report passes before
release & we add one step in our Release Plan check list.
Source: http://massol.myxwiki.org/xwiki/bin/view/Blog/ComparingCloverReports
Test Coverage - Global
Mutation Testing
• Using PIT/Gregor, PIT/Descartes
• Concepts of PIT
• Modify code under test (mutants) and run tests
• Good tests kill mutants
• Generates a mutation score similar to the coverage %
• Descartes = extreme mutations that execute fast and have high
values
https://massol.myxwiki.org/xwiki/bin/view/Blog/MutationTestingDescartes
Mutation - Descartes
Image courtesy of Oscar LuisVera Perez / INRIA / STAMP project
Mutation - Example
Mutation - Example
result =
   (getId() == macroId.getId() || (getId() != null && getId().equals(macroId.getId())))
   && (getSyntax() == macroId.getSyntax() || (getSyntax() != null && getSyntax().equals(
    macroId.getSyntax())));
Mutation - Example
@Test
public void testEquality()
{
    MacroId id1 = new MacroId("id", Syntax.XWIKI_2_0);
    MacroId id2 = new MacroId("id", Syntax.XWIKI_2_0);
    MacroId id3 = new MacroId("otherid", Syntax.XWIKI_2_0);
    MacroId id4 = new MacroId("id", Syntax.XHTML_1_0);
    MacroId id5 = new MacroId("otherid", Syntax.XHTML_1_0);
    MacroId id6 = new MacroId("id");
    MacroId id7 = new MacroId("id");
    Assert.assertEquals(id2, id1);
   // Equal objects must have equal hashcode
   Assert.assertTrue(id1.hashCode() == id2.hashCode());
    Assert.assertFalse(id3 == id1);
    Assert.assertFalse(id4 == id1);
    Assert.assertFalse(id5 == id3);
    Assert.assertFalse(id6 == id1);
    Assert.assertEquals(id7, id6);
   // Equal objects must have equal hashcode
   Assert.assertTrue(id6.hashCode() == id7.hashCode());
}
Not testing
for inequality!
Improved thanks to Descartes!
Mutation - Limitations
• Takes time to find interesting things to look at and decide if that’s an issue
to handle or not. Need better categorisation in report (now reported by
Descartes):
• Strong pseudo-tested methods:The worst! No matter what the return
values are the tests always fail
• Pseudo-tested methods: Grey area.The tests pass with at least one
modified value.
• Multi module support - PITmp
• But slow on large projects (e.g. 7+ hours just for xwiki-rendering)
Mutation - Strategy
• Seems to be working ok so far (6+ months of feedback now)
• But still young and not enough data about evolution
• Fail the build when the mutation score of a given module is below
a defined threshold in the pom.xml
• The idea is that new tests should, in average, be of quality equal or
better than past tests.
• Other idea: hook on CI to run it only on modified code/tests.
General goal with coverage + mutation: maintain quality
Mutation: Going further
• Using DSpot
• Uses PIT/Descartes but injects
results to generate new tests
• Adds assertions to existing tests
• Generate new test methods
• Selector can be PIT/Gregor, PIT/
Descartes, Jacoco (instruction
coverage), Clover (Branch
coverage)
https://massol.myxwiki.org/xwiki/bin/view/Blog/TestGenerationDspot
Mutation: Dspot Example 1
public void escapeAttributeValue2() {
String escapedText = XMLUtils.escapeAttributeValue("a < a' && a' < a" => a < a" {");
// AssertGenerator add assertion
Assert.assertEquals("a &#60; a&#39; &#38;&#38; a&#39; &#60; a&#34; =&#62; a &#60; a&#34; &#123;", escapedText);
// AssertGenerator create local variable with return value of invocation
boolean o_escapeAttributeValue__3 = escapedText.contains("<");
// AssertGenerator add assertion
Assert.assertFalse(o_escapeAttributeValue__3);
// AssertGenerator create local variable with return value of invocation
boolean o_escapeAttributeValue__4 = escapedText.contains(">");
// AssertGenerator add assertion
Assert.assertFalse(o_escapeAttributeValue__4);
// AssertGenerator create local variable with return value of invocation
boolean o_escapeAttributeValue__5 = escapedText.contains("'");
// AssertGenerator add assertion
Assert.assertFalse(o_escapeAttributeValue__5);
// AssertGenerator create local variable with return value of invocation
boolean o_escapeAttributeValue__6 = escapedText.contains(""");
// AssertGenerator create local variable with return value of invocation
boolean o_escapeAttributeValue__7 = escapedText.contains("&&");
// AssertGenerator add assertion
Assert.assertFalse(o_escapeAttributeValue__7);
// AssertGenerator create local variable with return value of invocation
boolean o_escapeAttributeValue__8 = escapedText.contains("{");
// AssertGenerator add assertion
Assert.assertFalse(o_escapeAttributeValue__8);
}
Generated test
New test
@Test
public void escapeAttributeValue()
{
String escapedText = XMLUtils.escapeAttributeValue("a < a' && a' < a" => a < a" {");
assertFalse("Failed to escape <", escapedText.contains("<"));
assertFalse("Failed to escape >", escapedText.contains(">"));
assertFalse("Failed to escape '", escapedText.contains("'"));
assertFalse("Failed to escape "", escapedText.contains("""));
assertFalse("Failed to escape &", escapedText.contains("&&"));
assertFalse("Failed to escape {", escapedText.contains("{"));
}
Original test
Mutation: Dspot Example 2
Generated test
Original test
Also increase coverage
Before: 70.5%
After: 71.2%
Mutation: Dspot Strategy
• DSpot is very slow to execute (between 3 to 20mn on
small modules)
• One strategy is to run it on CI and in the pipeline commit
generated tests in a different source root.
• And run it only on Tests affected by commit changeset
• Configure Maven to add a new test directory source using
the Maven Build Helper plugin.
• Work in progress: small coverage and mutation score
improvements on XWiki so far.
Environment Testing
• Environment = combination of Servlet
container & version, DB & version, OS,
Browser & version
• Future: cluster mode, LibreOffice
integration, external SOLR, etc
• Need: Be able to run/debug functional
tests on local dev machines as well as on
CI
• Using Docker / TestContainers
Environment Testing
https://massol.myxwiki.org/xwiki/bin/view/Blog/EnvironmentTestingExperimentations
Environment Testing
Environment Testing
• Feedback: takes about 3 minutes to deploy all (and 1 minute for the
test)
• Strategy
• Run on CI (Jenkins)
• 3 jobs
• “latest”: latest versions of all elements (DB, Servlet Container,
Browser, etc). Once per day
• “all”: all supported versions. Once per week
• “unsupported”: what we want to support in the future. Once
per month.
• Future: IE/Edge + Docker in Docker
• Some instability with Docker and DinD/DooD.
Crash Reproduction
• Tool: Botsing
• Concept:Take a stack trace
and generates a test that,
when executed, leads to this
stack trace
• i.e. find the conditions that
leads to the problem
Botsing Example
10 frames reproduced!
Botsing - Feedback
• Can take a long time to reproduce, doesn’t always succeed
• Generates a test that reproduces the problem, not the fix!
• Often you’d write a test at a different level (usually up in the call
chain, to be more meaningful to the use case)
• Is useful for newcomers who don’t know the codebase well as it
helps pinpoint the problem. Acts as a timesaver.
Parting words
• Experiment, push the limit!
• Some other types of tests not covered and that also need
automation
• Backward compatibility testing
• Performance/Stress testing
• Usability testing
• others?
Q&A
Me
Vincent Massol
vincent@xwiki.com
skype: vmassol
http://about.me/vmassol
http://xwiki.org
http://xwiki.com

More Related Content

PDF
New types of tests for Java projects
PDF
Building XWiki
PDF
PuppetConf 2016: Enjoying the Journey from Puppet 3.x to 4.x – Rob Nelson, AT&T
PPTX
Bug zillatestopiajenkins
PDF
Monitoring Akka with Kamon 1.0
PPTX
Mcroservices with docker kubernetes, goang and grpc, overview
PPTX
Test driving QML
PPTX
Cooking the Cake for Nuget packages
New types of tests for Java projects
Building XWiki
PuppetConf 2016: Enjoying the Journey from Puppet 3.x to 4.x – Rob Nelson, AT&T
Bug zillatestopiajenkins
Monitoring Akka with Kamon 1.0
Mcroservices with docker kubernetes, goang and grpc, overview
Test driving QML
Cooking the Cake for Nuget packages

What's hot (20)

PPTX
Test driving-qml
PPTX
Java build tools
PDF
[KubeCon NA 2018] Telepresence Deep Dive Session - Rafael Schloming & Luke Sh...
PPTX
Test it! Unit, mocking and in-container Meet Arquillian!
PDF
Testing the Enterprise layers, with Arquillian
PDF
Summit 16: Stop Writing Legacy Code!
PDF
AQAvit: Vitality through Testing
PDF
Docker in Continuous Integration
PDF
[KubeCon NA 2018] Effective Kubernetes Develop: Turbocharge Your Dev Loop - P...
PDF
Into The Box 2018 | Assert control over your legacy applications
PPTX
Automated testing on steroids – Trick for managing test data using Docker sna...
PDF
Let's go HTTPS-only! - More Than Buying a Certificate
PPTX
Ensuring OpenStack Version up Compatibility for CloudOpen Japan 2013-05-31
PDF
Craig Box (Google) - The road to Kubernetes 1.0
PDF
Mini-Training: NFluent
PDF
Junit5: the next gen of testing, don't stay behind
PDF
Getting to Walk with DevOps
PDF
2013 10-28 php ug presentation - ci using phing and hudson
PDF
Lightweight Java EE with MicroProfile
PDF
Testing with Docker
Test driving-qml
Java build tools
[KubeCon NA 2018] Telepresence Deep Dive Session - Rafael Schloming & Luke Sh...
Test it! Unit, mocking and in-container Meet Arquillian!
Testing the Enterprise layers, with Arquillian
Summit 16: Stop Writing Legacy Code!
AQAvit: Vitality through Testing
Docker in Continuous Integration
[KubeCon NA 2018] Effective Kubernetes Develop: Turbocharge Your Dev Loop - P...
Into The Box 2018 | Assert control over your legacy applications
Automated testing on steroids – Trick for managing test data using Docker sna...
Let's go HTTPS-only! - More Than Buying a Certificate
Ensuring OpenStack Version up Compatibility for CloudOpen Japan 2013-05-31
Craig Box (Google) - The road to Kubernetes 1.0
Mini-Training: NFluent
Junit5: the next gen of testing, don't stay behind
Getting to Walk with DevOps
2013 10-28 php ug presentation - ci using phing and hudson
Lightweight Java EE with MicroProfile
Testing with Docker
Ad

Similar to Advanced Java Testing @ POSS 2019 (20)

PDF
New types of tests for Java projects
PDF
Advanced Java Testing
PPTX
GeeCON - Improve your tests with Mutation Testing
PDF
Automated Developer Testing: Achievements and Challenges
PPTX
Kill the mutants and test your tests - Roy van Rijn
PDF
Kill the mutants - A better way to test your tests
PPTX
Javantura v3 - Mutation Testing for everyone – Nicolas Fränkel
PDF
May: Automated Developer Testing: Achievements and Challenges
PPTX
Voxxed Days Athens - Improve your tests with Mutation Testing
PDF
Mutation Testing: Start Hunting The Bugs
PDF
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
PDF
Hardening
PPT
PPTX
I.T.A.K.E Unconference - Mutation testing to the rescue of your tests
PPTX
Testing in Scala. Adform Research
PPTX
Testing in Scala by Adform research
PPTX
ConFoo - Improve your tests with mutation testing
PPTX
Joker - Improve your tests with mutation testing
PDF
GTAC 2014: What lurks in test suites?
PPTX
DevExperience - Improve your tests with mutation testing
New types of tests for Java projects
Advanced Java Testing
GeeCON - Improve your tests with Mutation Testing
Automated Developer Testing: Achievements and Challenges
Kill the mutants and test your tests - Roy van Rijn
Kill the mutants - A better way to test your tests
Javantura v3 - Mutation Testing for everyone – Nicolas Fränkel
May: Automated Developer Testing: Achievements and Challenges
Voxxed Days Athens - Improve your tests with Mutation Testing
Mutation Testing: Start Hunting The Bugs
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
Hardening
I.T.A.K.E Unconference - Mutation testing to the rescue of your tests
Testing in Scala. Adform Research
Testing in Scala by Adform research
ConFoo - Improve your tests with mutation testing
Joker - Improve your tests with mutation testing
GTAC 2014: What lurks in test suites?
DevExperience - Improve your tests with mutation testing
Ad

More from Vincent Massol (20)

PDF
XWiki Testing with TestContainers
PDF
XWiki: The best wiki for developers
PDF
Configuration Testing with Docker & TestContainers
PDF
What's new in XWiki 9.x and 10.x
PDF
QDashboard 1.2
PDF
Creating your own project's Quality Dashboard
PDF
XWiki: wiki collaboration as an alternative to Confluence and Sharepoint
PDF
Creating your own project's Quality Dashboard
PDF
XWiki: The web's Swiss Army Knife
PDF
Leading a Community-Driven Open Source Project
PDF
Developing XWiki
PDF
XWiki Status - July 2015
PDF
XWiki SAS development practices
PDF
XWiki SAS: An open source company
PDF
XWiki: A web dev runtime for writing web apps @ FOSDEM 2014
PDF
XWiki Rendering @ FOSDEM 2014
PDF
Implementing Quality on a Java Project
ODP
Implementing Quality on Java projects (Short version)
PDF
Implementing quality in Java projects
PDF
Implementing Quality on Java projects
XWiki Testing with TestContainers
XWiki: The best wiki for developers
Configuration Testing with Docker & TestContainers
What's new in XWiki 9.x and 10.x
QDashboard 1.2
Creating your own project's Quality Dashboard
XWiki: wiki collaboration as an alternative to Confluence and Sharepoint
Creating your own project's Quality Dashboard
XWiki: The web's Swiss Army Knife
Leading a Community-Driven Open Source Project
Developing XWiki
XWiki Status - July 2015
XWiki SAS development practices
XWiki SAS: An open source company
XWiki: A web dev runtime for writing web apps @ FOSDEM 2014
XWiki Rendering @ FOSDEM 2014
Implementing Quality on a Java Project
Implementing Quality on Java projects (Short version)
Implementing quality in Java projects
Implementing Quality on Java projects

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
cuic standard and advanced reporting.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Spectroscopy.pptx food analysis technology
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
KodekX | Application Modernization Development
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Empathic Computing: Creating Shared Understanding
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
Big Data Technologies - Introduction.pptx
Teaching material agriculture food technology
20250228 LYD VKU AI Blended-Learning.pptx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
cuic standard and advanced reporting.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Dropbox Q2 2025 Financial Results & Investor Presentation
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Encapsulation_ Review paper, used for researhc scholars
Chapter 3 Spatial Domain Image Processing.pdf
Network Security Unit 5.pdf for BCA BBA.
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Spectroscopy.pptx food analysis technology
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
KodekX | Application Modernization Development
The AUB Centre for AI in Media Proposal.docx
Empathic Computing: Creating Shared Understanding
“AI and Expert System Decision Support & Business Intelligence Systems”
Big Data Technologies - Introduction.pptx

Advanced Java Testing @ POSS 2019

  • 1. New types of tests for Java projects Vincent Massol, CTO XWiki SAS, December 2019
  • 2. Agenda •Context & Current status quo •Coverage testing •Mutation testing •Environment testing •Crash reproduction
  • 3. Context: XWiki • Open source wiki • 15 years • 10-15 active committers • Very extensible, scripting in wiki pages • Platform for developing ad-hoc web applications • Strong build practices using Maven and lots of “Quality” plugins • Using Jenkins & custom pipeline library for the CI https://xwiki.org
  • 4. Context: STAMP • Automatic Test Amplification • XWiki SAS participating, 3 years • Experiments on XWiki project Mutation testing Environment Testing Production Testing
  • 5. Current Testing Status • 10986 automated tests (in 2.5 hours): • Unit tests (using Mockito) • Integration tests (using Mockito) • Functional (UI) tests (using Selenium/Webdriver)
  • 6. New questions • Are my tests testing enough? Coverage • How good are my tests? Mutation testing • Do my software work in various setups? Environment testing • How can I reproduce bugs found in production? Production testing = in place w/ strategy = in progress
  • 7. Test Coverage - Local • Using Jacoco and Clover • Strategy - “Ratchet effect”: • Each Maven module has a threshold • Jacoco Maven plugin fails if new code has less coverage than before in % • Dev is allowed to increase threshold Of course TPC is not panacea. You could have 100% and app not working. Also need functional tests. Aim for 80%.
  • 8. Test Coverage - Global • Issue: Local coverage can increase and global decrease • Removed code with high TPC • Code tested indirectly by functional tests and code refactoring led to different paths used • New module with lower TPC than average Global TPC evolution
  • 9. Test Coverage - Global • Strategy: • Global Clover TPC computed automatically every night on Jenkins for all repos combined, using a pipeline • Email sent to developers with report in email (see next slide) • Developers fix module they have been working on • Release Manager (RM) ensures that report passes before release & we add one step in our Release Plan check list. Source: http://massol.myxwiki.org/xwiki/bin/view/Blog/ComparingCloverReports
  • 10. Test Coverage - Global
  • 11. Mutation Testing • Using PIT/Gregor, PIT/Descartes • Concepts of PIT • Modify code under test (mutants) and run tests • Good tests kill mutants • Generates a mutation score similar to the coverage % • Descartes = extreme mutations that execute fast and have high values https://massol.myxwiki.org/xwiki/bin/view/Blog/MutationTestingDescartes
  • 12. Mutation - Descartes Image courtesy of Oscar LuisVera Perez / INRIA / STAMP project
  • 14. Mutation - Example result =    (getId() == macroId.getId() || (getId() != null && getId().equals(macroId.getId())))    && (getSyntax() == macroId.getSyntax() || (getSyntax() != null && getSyntax().equals(     macroId.getSyntax())));
  • 15. Mutation - Example @Test public void testEquality() {     MacroId id1 = new MacroId("id", Syntax.XWIKI_2_0);     MacroId id2 = new MacroId("id", Syntax.XWIKI_2_0);     MacroId id3 = new MacroId("otherid", Syntax.XWIKI_2_0);     MacroId id4 = new MacroId("id", Syntax.XHTML_1_0);     MacroId id5 = new MacroId("otherid", Syntax.XHTML_1_0);     MacroId id6 = new MacroId("id");     MacroId id7 = new MacroId("id");     Assert.assertEquals(id2, id1);    // Equal objects must have equal hashcode    Assert.assertTrue(id1.hashCode() == id2.hashCode());     Assert.assertFalse(id3 == id1);     Assert.assertFalse(id4 == id1);     Assert.assertFalse(id5 == id3);     Assert.assertFalse(id6 == id1);     Assert.assertEquals(id7, id6);    // Equal objects must have equal hashcode    Assert.assertTrue(id6.hashCode() == id7.hashCode()); } Not testing for inequality! Improved thanks to Descartes!
  • 16. Mutation - Limitations • Takes time to find interesting things to look at and decide if that’s an issue to handle or not. Need better categorisation in report (now reported by Descartes): • Strong pseudo-tested methods:The worst! No matter what the return values are the tests always fail • Pseudo-tested methods: Grey area.The tests pass with at least one modified value. • Multi module support - PITmp • But slow on large projects (e.g. 7+ hours just for xwiki-rendering)
  • 17. Mutation - Strategy • Seems to be working ok so far (6+ months of feedback now) • But still young and not enough data about evolution • Fail the build when the mutation score of a given module is below a defined threshold in the pom.xml • The idea is that new tests should, in average, be of quality equal or better than past tests. • Other idea: hook on CI to run it only on modified code/tests. General goal with coverage + mutation: maintain quality
  • 18. Mutation: Going further • Using DSpot • Uses PIT/Descartes but injects results to generate new tests • Adds assertions to existing tests • Generate new test methods • Selector can be PIT/Gregor, PIT/ Descartes, Jacoco (instruction coverage), Clover (Branch coverage) https://massol.myxwiki.org/xwiki/bin/view/Blog/TestGenerationDspot
  • 19. Mutation: Dspot Example 1 public void escapeAttributeValue2() { String escapedText = XMLUtils.escapeAttributeValue("a < a' && a' < a" => a < a" {"); // AssertGenerator add assertion Assert.assertEquals("a &#60; a&#39; &#38;&#38; a&#39; &#60; a&#34; =&#62; a &#60; a&#34; &#123;", escapedText); // AssertGenerator create local variable with return value of invocation boolean o_escapeAttributeValue__3 = escapedText.contains("<"); // AssertGenerator add assertion Assert.assertFalse(o_escapeAttributeValue__3); // AssertGenerator create local variable with return value of invocation boolean o_escapeAttributeValue__4 = escapedText.contains(">"); // AssertGenerator add assertion Assert.assertFalse(o_escapeAttributeValue__4); // AssertGenerator create local variable with return value of invocation boolean o_escapeAttributeValue__5 = escapedText.contains("'"); // AssertGenerator add assertion Assert.assertFalse(o_escapeAttributeValue__5); // AssertGenerator create local variable with return value of invocation boolean o_escapeAttributeValue__6 = escapedText.contains("""); // AssertGenerator create local variable with return value of invocation boolean o_escapeAttributeValue__7 = escapedText.contains("&&"); // AssertGenerator add assertion Assert.assertFalse(o_escapeAttributeValue__7); // AssertGenerator create local variable with return value of invocation boolean o_escapeAttributeValue__8 = escapedText.contains("{"); // AssertGenerator add assertion Assert.assertFalse(o_escapeAttributeValue__8); } Generated test New test @Test public void escapeAttributeValue() { String escapedText = XMLUtils.escapeAttributeValue("a < a' && a' < a" => a < a" {"); assertFalse("Failed to escape <", escapedText.contains("<")); assertFalse("Failed to escape >", escapedText.contains(">")); assertFalse("Failed to escape '", escapedText.contains("'")); assertFalse("Failed to escape "", escapedText.contains(""")); assertFalse("Failed to escape &", escapedText.contains("&&")); assertFalse("Failed to escape {", escapedText.contains("{")); } Original test
  • 20. Mutation: Dspot Example 2 Generated test Original test Also increase coverage Before: 70.5% After: 71.2%
  • 21. Mutation: Dspot Strategy • DSpot is very slow to execute (between 3 to 20mn on small modules) • One strategy is to run it on CI and in the pipeline commit generated tests in a different source root. • And run it only on Tests affected by commit changeset • Configure Maven to add a new test directory source using the Maven Build Helper plugin. • Work in progress: small coverage and mutation score improvements on XWiki so far.
  • 22. Environment Testing • Environment = combination of Servlet container & version, DB & version, OS, Browser & version • Future: cluster mode, LibreOffice integration, external SOLR, etc • Need: Be able to run/debug functional tests on local dev machines as well as on CI • Using Docker / TestContainers
  • 25. Environment Testing • Feedback: takes about 3 minutes to deploy all (and 1 minute for the test) • Strategy • Run on CI (Jenkins) • 3 jobs • “latest”: latest versions of all elements (DB, Servlet Container, Browser, etc). Once per day • “all”: all supported versions. Once per week • “unsupported”: what we want to support in the future. Once per month. • Future: IE/Edge + Docker in Docker • Some instability with Docker and DinD/DooD.
  • 26. Crash Reproduction • Tool: Botsing • Concept:Take a stack trace and generates a test that, when executed, leads to this stack trace • i.e. find the conditions that leads to the problem
  • 28. Botsing - Feedback • Can take a long time to reproduce, doesn’t always succeed • Generates a test that reproduces the problem, not the fix! • Often you’d write a test at a different level (usually up in the call chain, to be more meaningful to the use case) • Is useful for newcomers who don’t know the codebase well as it helps pinpoint the problem. Acts as a timesaver.
  • 29. Parting words • Experiment, push the limit! • Some other types of tests not covered and that also need automation • Backward compatibility testing • Performance/Stress testing • Usability testing • others?