SlideShare a Scribd company logo
1 of 22
Download to read offline
8/7/2019
1
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 1@CoverosGene #THATConference
Agility. Security. Delivered.Get to Green:
How to Safely Refactor Legacy Code
Gene Gotimer
@CoverosGene
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 2@CoverosGene #THATConference
Agility. Security. Delivered.
8/7/2019
2
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 3@CoverosGene #THATConference
About Coveros
• Coveros helps companies accelerate the delivery of
secure, reliable software using agile methods
• Agile & DevOps Services
• DevOps Implementation
• DevSecOps Integration
• Agile Transformations & Coaching
• Agile Software Development
• Agile Testing & Automation
• Agile, DevOps, Testing, Security Training
• Open Source Products
• SecureCI – Secure DevOps toolchain
• Selenified – Agile test framework
Development Platforms
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 4@CoverosGene #THATConference
Selected Commercial Clients
8/7/2019
3
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 5@CoverosGene #THATConference
Selected Federal Clients
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 6@CoverosGene #THATConference
Refactoring
Refactoring is a disciplined technique
for restructuring an existing body of code,
altering its internal structure
without changing its external behavior.
Martin Fowler, https://refactoring.com
8/7/2019
4
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 7@CoverosGene #THATConference
Legacy Code
Legacy code is simply code without tests.
Code without tests is bad code.
Michael C. Feathers, Working Effectively with Legacy Code
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 8@CoverosGene #THATConference
Addressing Legacy Code
The temptation is to get rid of it and
start over from scratch.
But even if legacy code is bad code:
• it works (maybe, sort of)
• it is a known quantity
• there may be a reason the solution
isn’t as simple as you think it could
or should be
8/7/2019
5
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 9@CoverosGene #THATConference
Why Refactor At All?
If it works, why change it?
Because bad code carries cost and risk.
• What if it needs to be updated?
• What if it has a security issue?
• What if it is incompatible with an
update that fixes a security problem?
• Be proactive, not reactive.
• Don't wait until it has to be changed right now.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 10@CoverosGene #THATConference
Example Refactored Code
public boolean isUserAllowed(User someUser) {
boolean isAllowed = false;
for (String role : someUser.userRoles()) {
if (this.currentService.allowedRoles().contains(role)) {
isAllowed = true;
break;
}
}
return isAllowed;
}
public boolean isUserAllowed(User someUser) {
return this.currentService.allowedRoles().stream()
.anyMatch(someUser.userRoles()::contains);
}
8/7/2019
6
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 11@CoverosGene #THATConference
Refactoring
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 12@CoverosGene #THATConference
Catalog of Refactorings
• Change Function Declaration
• Change Reference to Value
• Change Value to Reference
• Collapse Hierarchy
• Combine Functions into Class
• Combine Functions into Transform
• Consolidate Conditional Expression
• Decompose Conditional
• Encapsulate Collection
• Encapsulate Record
• Encapsulate Variable
• Extract Class
• Extract Function
• Extract Superclass
• Extract Variable
• Hide Delegate
• Inline Class
• Inline Function
• Inline Variable
• Introduce Assertion
• Introduce Parameter Object
• Introduce Special Case
• Move Field
• Move Function
• Move Statements into Function
• Move Statements to Callers
• Parameterize Function
• Preserve Whole Object
• Pull Up Constructor Body
• Pull Up Field
• Pull Up Method
• Push Down Field
• Push Down Method
• Remove Dead Code
• Remove Flag Argument
• Remove Middle Man
• Remove Setting Method
• Remove Subclass
• Rename Field
• Rename Variable
• Replace Command with Function
• Replace Conditional with Polymorphism
• Replace Constructor with Factory Function
• Replace Control Flag with Break
• Replace Derived Variable with Query
• Replace Error Code with Exception
• Replace Exception with Precheck
• Replace Function with Command
• Replace Inline Code with Function Call
• Replace Loop with Pipeline
• Replace Magic Literal
• Replace Nested Conditional with Guard Clauses
• Replace Parameter with Query
• Replace Primitive with Object
• Replace Query with Parameter
• Replace Subclass with Delegate
• Replace Superclass with Delegate
• Replace Temp with Query
• Replace Type Code with Subclasses
• Return Modified Value
• Separate Query from Modifier
• Slide Statements
• Split Loop
• Split Phase
• Split Variable
• Substitute Algorithm
https://refactoring.com/catalog/
8/7/2019
7
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 13@CoverosGene #THATConference
What to Refactor
Do not refactor that which offends you.
Refactor that which impedes you.
Tim Ottinger, @tottinge
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 14@CoverosGene #THATConference
First Step
Whenever I do refactoring,
the first step is always the same.
I need to build a solid set of tests
for that section of code.
Martin Fowler, Refactoring: Improving the Design of Existing Code
8/7/2019
8
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 15@CoverosGene #THATConference
Unit Testing
Unit testing is a way for developers
to document the behavior of code.
Unit tests
• are automated,
• are independent,
• usually test individual methods or smaller,
• have no external dependencies, and
• become our safety net for fearless refactoring.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 16@CoverosGene #THATConference
Unit Testing Enables Change
• The challenge of how to refactor legacy code becomes
a challenge of how to unit test legacy code.
• Once it has tests, it isn’t legacy code anymore.
• We have a safety net.
• We can fearlessly refactor.
• We can just follow the catalog of refactorings.
• And/or we can modify the behavior safely in the future.
8/7/2019
9
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 17@CoverosGene #THATConference
Testing a Private Method
private double getPerimeter() {
double perimeter = 0.0d;
for (double length : lengths) {
perimeter += length;
}
return perimeter;
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
double getPerimeter() {
double perimeter = 0.0d;
for (double length : lengths) {
perimeter += length;
}
return perimeter;
}
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 18@CoverosGene #THATConference
Key Takeaways
• Safety is the goal. Strive for fearless refactoring.
• Don't over-complicate the solution.
• Unit tests will almost always be the safety net,
but it doesn't have to be unit tests.
Simple code reviews can provide a safety net.
8/7/2019
10
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 19@CoverosGene #THATConference
Code Coverage
• Measures code executed when unit tests run
• NOT amount of code tested
• Good tool to find untested code
• Not covered == not tested
• Covered == possibly tested
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 20@CoverosGene #THATConference
Mutation Testing
Mutation testing
public int foo(int i) {
i--;
return i;
}
public int foo(int i) {
i++;
return i;
}
public String bar(String s) {
if (s == null) {
// do something
public String bar(String s) {
if (s != null) {
// do something
8/7/2019
11
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 21@CoverosGene #THATConference
PIT Report Example
Light green shows line coverage, dark green shows mutation coverage.
Light pink show lack of line coverage, dark pink shows lack of mutation coverage.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 22@CoverosGene #THATConference
Key Takeaways
• Code coverage tells you what code is executed during tests.
• Mutation testing tells you what code is tested.
• You don't need 100% tested,
but at least the pieces that you
want to change need a safety net.
8/7/2019
12
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 23@CoverosGene #THATConference
Testing a God Method
• God method = “The Method That Does Everything”
• For example: 2,000-line Java method, private static void
• Nothing but side effects
• Modifies parameters
• Calls external services
• Implements time travel, I assume
• Small, incremental changes
• Need a safety net
• Unit testing will be necessary, but difficult
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 24@CoverosGene #THATConference
“Untestable” Code
We want to add tests, but the code isn’t making that easy.
• Important methods are void, rely on side effects, etc.
• Long methods do too much to comprehend, or require complicated
and specific setup before the test can be executed.
• Other code or services are invoked from within, so the unit of code
can’t be easily isolated.
8/7/2019
13
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 25@CoverosGene #THATConference
Mock Frameworks
• Allow you to create objects that have predetermined responses to
specific requests.
• Rely on interfaces to replace “real” instances.
• Replacement for external services in unit tests,
• or sometimes when it is just tedious to create a graph of objects.
• Dependency injection makes testing with mocks easy.
when(mockService.get(anyInt()).thenReturn("foo");
when(mockService.get(-1).thenThrow(new IllegalArgumentException());
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 26@CoverosGene #THATConference
Using mocks
public ZapSensor(ZapSensorConfiguration configuration, FileSystem fileSystem,
PathResolver pathResolver, Rules rules) {
this.rules = rules;
this.report = new XmlReportFile(configuration, fileSystem, pathResolver);
}
@Before
public void setUp() {
final ZapSensorConfiguration configuration = mock(ZapSensorConfiguration.class);
final FileSystem fileSystem = mock(FileSystem.class);
final PathResolver pathResolver = mock(PathResolver.class);
final Rules rules = mock(Rules.class);
this.zapSensor = new ZapSensor(configuration, fileSystem, pathResolver, rules);
}
8/7/2019
14
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 27@CoverosGene #THATConference
PowerMock
• Useful when you don't have interfaces or dependency injection
• Extends Mockito and EasyMock
• Uses reflection to mock
• constructors
• final methods
• static methods
• private methods
• Make PowerMock use temporary.
The goal is to use it to refactor so that you do not need it.
“Please note that PowerMock is mainly intended for people with expert
knowledge in unit testing. Putting it in the hands of junior developers
may cause more harm than good.”
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 28@CoverosGene #THATConference
Using PowerMock
…
void addIssue(SensorContext context, AlertItem alert) {
Severity severity =
ZapUtils.riskCodeToSonarQubeSeverity(alert.getRiskcode());
…
mockStatic(ZapUtils.class);
…
when(ZapUtils.riskCodeToSonarQubeSeverity(3))
.thenReturn(Severity.CRITICAL);
8/7/2019
15
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 29@CoverosGene #THATConference
Removing PowerMock
…
void addIssue(SensorContext context, AlertItem alert) {
Severity severity =
ZapUtils.riskCodeToSonarQubeSeverity(alert.getRiskcode());
…
void addIssue(SensorContext context, Severity severity) {
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 30@CoverosGene #THATConference
Removing PowerMock
public static Severity riskCodeToSonarQubeSeverity(int riskcode) {
if (riskcode == 3) {
return Severity.CRITICAL;
} else if (riskcode == 2) {
return Severity.MAJOR;
} else if (riskcode == 1) {
return Severity.MINOR;
} else {
return Severity.INFO;
}
}
8/7/2019
16
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 31@CoverosGene #THATConference
Removing PowerMock
@Deprecated
public static Severity riskCodeToSonarQubeSeverity(int riskcode) {
return new ZapUtils().riskCodeToSonarQubeSeverity(riskcode);
}
public Severity riskCodeToSonarQubeSeverity(int riskcode) {
if (riskcode == 3) {
return Severity.CRITICAL;
} else if (riskcode == 2) {
return Severity.MAJOR;
} else if (riskcode == 1) {
return Severity.MINOR;
} else {
return Severity.INFO;
}
}
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 32@CoverosGene #THATConference
Key Takeaways
• Use mocking frameworks to isolate units from
external dependencies.
• Mocks can also simplify tests by making it easier
to set up objects that you need but aren't
directly involved in the test.
• Frameworks like PowerMock can be
used as temporary solutions. The goal is to
use PowerMock to safely refactor until you
don't need PowerMock anymore.
8/7/2019
17
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 33@CoverosGene #THATConference
Static Code Analysis
• Inspects source code for
• code coverage
• duplicated code
• complex code
• tightly coupled code
• security issues
• Helps identify riskiest code
• Refactoring opportunities
• Also shows
• unused variables
• confusing code
• best practices
• coding standards
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 34@CoverosGene #THATConference
8/7/2019
18
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 35@CoverosGene #THATConference
IDE Code Inspections
• IDEs have some static analysis built-in (red, squiggly lines)
• Other static analysis tools can be integrated
• e.g., SonarLint
• Quicker feedback loop, could show some low-hanging fruit
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 36@CoverosGene #THATConference
IDE Refactoring
• IDEs have built-in refactoring support
• You still need unit tests as the safety net
8/7/2019
19
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 37@CoverosGene #THATConference
Key Takeaways
• Static code analysis tools can identify riskiest code,
which are prime candidates for refactoring.
• IDEs often have static code analysis built in.
• IDEs often have refactoring tools built in.
You still need unit tests.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 38@CoverosGene #THATConference
General Plan of Attack
For example, for our 2,000-line Java method, private static void
1. Unit test with mocks to isolate units.
2. Use PowerMock when necessary.
3. Use mutation testing to make sure code being touched is tested.
4. Replace chunks with package-private methods, @VisibleForTesting.
5. Refactor to eliminate the need for PowerMock.
6. Let static analysis tools identify refactoring opportunities.
7. Use IDE tools to perform individual refactorings.
One change at a time. Refactor – Test – Repeat.
8/7/2019
20
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 39@CoverosGene #THATConference
#Coveros5
• Safety is the goal. Strive for fearless refactoring.
• Unit tests are the best safety net for making code changes.
• Use mutation testing to make sure
your unit tests are actually covering
what you need covered.
• Use a combination of mocking tools and
mocks to isolate your units to test.
• Make small, incremental, safe changes.
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 40@CoverosGene #THATConference
Tools Required
• Unit testing framework
• Code coverage tool
• Mutation testing tool
• Mock frameworks
• Static analysis tools
• IDE refactoring tools
• Lots of patience
8/7/2019
21
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 41@CoverosGene #THATConference
Java Tools
• JUnit https://junit.org
• JaCoCo https://www.eclemma.org/jacoco
• PIT http://pitest.org
• Mockito https://github.com/mockito/mockito
• EasyMock http://easymock.org
• PowerMock https://github.com/powermock/powermock
• PMD CPD https://pmd.github.io
• SonarQube https://www.sonarqube.org
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 42@CoverosGene #THATConference
C#/.NET Tools
• NUnit https://nunit.org
• NCover (commercial) https://www.ncover.com
• OpenCover https://github.com/OpenCover/opencover
• Ninja Turtles http://www.mutation-testing.net
• Moq https://github.com/moq/moq4
• Microsoft Fakes https://docs.microsoft.com/en-
us/visualstudio/test/isolating-code-under-test-with-microsoft-fakes
• PMD CPD https://pmd.github.io
• SonarQube https://www.sonarqube.org
8/7/2019
22
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 43@CoverosGene #THATConference
Reading List
• Refactoring: Improving the Design of Existing Code,
by Martin Fowler https://amzn.com/0134757599
• Working Effectively with Legacy Code,
by Michael Feathers https://amzn.com/0131177052
• Clean Code: A Handbook of Agile Software Craftsmanship,
by Robert C. Martin https://amzn.com/0132350882
• Pragmatic Unit Testing in Java 8 with JUnit,
by Jeff Langr https://amzn.com/1941222595
© COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 44@CoverosGene #THATConference
Questions?
gene.gotimer@coveros.com
@CoverosGene
https://hub.techwell.com/
Live refactoring office hours: Tuesday, August 13, noon-1PM Central Time
I'll post a link on Slack.

More Related Content

What's hot

Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
QAware GmbH
 
Load Balancing Apps in Docker Swarm with NGINX
Load Balancing Apps in Docker Swarm with NGINXLoad Balancing Apps in Docker Swarm with NGINX
Load Balancing Apps in Docker Swarm with NGINX
NGINX, Inc.
 
cloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptx
cloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptxcloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptx
cloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptx
VitNguyn252054
 

What's hot (20)

Kubernetes Secrets Management on Production with Demo
Kubernetes Secrets Management on Production with DemoKubernetes Secrets Management on Production with Demo
Kubernetes Secrets Management on Production with Demo
 
Kubernetes Architecture | Understanding Kubernetes Components | Kubernetes Tu...
Kubernetes Architecture | Understanding Kubernetes Components | Kubernetes Tu...Kubernetes Architecture | Understanding Kubernetes Components | Kubernetes Tu...
Kubernetes Architecture | Understanding Kubernetes Components | Kubernetes Tu...
 
DevOps : mission [im]possible ?
DevOps : mission [im]possible ?DevOps : mission [im]possible ?
DevOps : mission [im]possible ?
 
Docker introduction (1)
Docker introduction (1)Docker introduction (1)
Docker introduction (1)
 
Kubernetes Introduction
Kubernetes IntroductionKubernetes Introduction
Kubernetes Introduction
 
The Juniper SDN Landscape
The Juniper SDN LandscapeThe Juniper SDN Landscape
The Juniper SDN Landscape
 
Docker networking Tutorial 101
Docker networking Tutorial 101Docker networking Tutorial 101
Docker networking Tutorial 101
 
VMware HCI solutions - 2020-01-16
VMware HCI solutions - 2020-01-16VMware HCI solutions - 2020-01-16
VMware HCI solutions - 2020-01-16
 
An Introduction to Kubernetes
An Introduction to KubernetesAn Introduction to Kubernetes
An Introduction to Kubernetes
 
Kubernetes Introduction
Kubernetes IntroductionKubernetes Introduction
Kubernetes Introduction
 
Domain Driven Design
Domain Driven Design Domain Driven Design
Domain Driven Design
 
Red Hat Container Strategy
Red Hat Container StrategyRed Hat Container Strategy
Red Hat Container Strategy
 
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
Migrating Hundreds of Legacy Applications to Kubernetes - The Good, the Bad, ...
 
Load Balancing Apps in Docker Swarm with NGINX
Load Balancing Apps in Docker Swarm with NGINXLoad Balancing Apps in Docker Swarm with NGINX
Load Balancing Apps in Docker Swarm with NGINX
 
Istio Service Mesh for Developers and Platform Engineers
Istio Service Mesh for Developers and Platform EngineersIstio Service Mesh for Developers and Platform Engineers
Istio Service Mesh for Developers and Platform Engineers
 
Architecture Overview: Kubernetes with Red Hat Enterprise Linux 7.1
Architecture Overview: Kubernetes with Red Hat Enterprise Linux 7.1Architecture Overview: Kubernetes with Red Hat Enterprise Linux 7.1
Architecture Overview: Kubernetes with Red Hat Enterprise Linux 7.1
 
containerd summit - Deep Dive into containerd
containerd summit - Deep Dive into containerdcontainerd summit - Deep Dive into containerd
containerd summit - Deep Dive into containerd
 
Introduction of kubernetes rancher
Introduction of kubernetes rancherIntroduction of kubernetes rancher
Introduction of kubernetes rancher
 
cloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptx
cloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptxcloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptx
cloud_foundation_on_vxrail_vcf_pnp_licensing_guide.pptx
 
Présentation docker et kubernetes
Présentation docker et kubernetesPrésentation docker et kubernetes
Présentation docker et kubernetes
 

Similar to Get to Green: How to Safely Refactor Legacy Code

DevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene Gotimer
DevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene GotimerDevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene Gotimer
DevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene Gotimer
DevOpsDays Baltimore
 
A better faster pipeline for software delivery, even in the government
A better faster pipeline for software delivery, even in the governmentA better faster pipeline for software delivery, even in the government
A better faster pipeline for software delivery, even in the government
Gene Gotimer
 
Best Practices for Shifting Left Performance and Accessibility Testing
Best Practices for Shifting Left Performance and Accessibility TestingBest Practices for Shifting Left Performance and Accessibility Testing
Best Practices for Shifting Left Performance and Accessibility Testing
Perfecto by Perforce
 
A Better, Faster Pipeline for Software Delivery
A Better, Faster Pipeline for Software DeliveryA Better, Faster Pipeline for Software Delivery
A Better, Faster Pipeline for Software Delivery
Gene Gotimer
 
Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...
Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...
Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...
Curiosity Software Ireland
 
Enabling Agility Through DevOps
Enabling Agility Through DevOpsEnabling Agility Through DevOps
Enabling Agility Through DevOps
Leland Newsom CSP-SM, SPC5, SDP
 

Similar to Get to Green: How to Safely Refactor Legacy Code (20)

DevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene Gotimer
DevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene GotimerDevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene Gotimer
DevOpsDays Baltimore 2018: A Definition of Done for DevSecOps - Gene Gotimer
 
A better faster pipeline for software delivery, even in the government
A better faster pipeline for software delivery, even in the governmentA better faster pipeline for software delivery, even in the government
A better faster pipeline for software delivery, even in the government
 
A Definition of Done for DevSecOps
A Definition of Done for DevSecOpsA Definition of Done for DevSecOps
A Definition of Done for DevSecOps
 
Tests Your Pipeline Might Be Missing
Tests Your Pipeline Might Be MissingTests Your Pipeline Might Be Missing
Tests Your Pipeline Might Be Missing
 
DevOps for Leadership
DevOps for LeadershipDevOps for Leadership
DevOps for Leadership
 
Shifting security all day dev ops
Shifting security all day dev opsShifting security all day dev ops
Shifting security all day dev ops
 
DevOps Patterns to Enable Success in Microservices
DevOps Patterns to Enable Success in MicroservicesDevOps Patterns to Enable Success in Microservices
DevOps Patterns to Enable Success in Microservices
 
Shifting Security Left - The Innovation of DevSecOps - AgileDC
Shifting Security Left - The Innovation of DevSecOps - AgileDCShifting Security Left - The Innovation of DevSecOps - AgileDC
Shifting Security Left - The Innovation of DevSecOps - AgileDC
 
Best Practices for Shifting Left Performance and Accessibility Testing
Best Practices for Shifting Left Performance and Accessibility TestingBest Practices for Shifting Left Performance and Accessibility Testing
Best Practices for Shifting Left Performance and Accessibility Testing
 
DevOps Patterns to Enable Success in Microservices
DevOps Patterns to Enable Success in MicroservicesDevOps Patterns to Enable Success in Microservices
DevOps Patterns to Enable Success in Microservices
 
A Better, Faster Pipeline for Software Delivery
A Better, Faster Pipeline for Software DeliveryA Better, Faster Pipeline for Software Delivery
A Better, Faster Pipeline for Software Delivery
 
Shifting Security Left - The Innovation of DevSecOps - ValleyTechCon
Shifting Security Left - The Innovation of DevSecOps - ValleyTechConShifting Security Left - The Innovation of DevSecOps - ValleyTechCon
Shifting Security Left - The Innovation of DevSecOps - ValleyTechCon
 
Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...
Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...
Curiosity software Ireland and Perfecto present: achieving in-sprint regressi...
 
The Path to a Programmable Network
The Path to a Programmable NetworkThe Path to a Programmable Network
The Path to a Programmable Network
 
Sogeti Software Maintainability Roadshow
Sogeti Software Maintainability RoadshowSogeti Software Maintainability Roadshow
Sogeti Software Maintainability Roadshow
 
GitOps, Jenkins X &Future of CI/CD
GitOps, Jenkins X &Future of CI/CDGitOps, Jenkins X &Future of CI/CD
GitOps, Jenkins X &Future of CI/CD
 
Stf 2019 workshop - enhanced test automation for web and desktop apps
Stf 2019   workshop - enhanced test automation for web and desktop appsStf 2019   workshop - enhanced test automation for web and desktop apps
Stf 2019 workshop - enhanced test automation for web and desktop apps
 
Creative Solutions to Already Solved Problems II
Creative Solutions to Already Solved Problems IICreative Solutions to Already Solved Problems II
Creative Solutions to Already Solved Problems II
 
CI/CD Best Practices for Your DevOps Journey
CI/CD Best  Practices for Your DevOps JourneyCI/CD Best  Practices for Your DevOps Journey
CI/CD Best Practices for Your DevOps Journey
 
Enabling Agility Through DevOps
Enabling Agility Through DevOpsEnabling Agility Through DevOps
Enabling Agility Through DevOps
 

More from Gene Gotimer

Experiences Bringing CD to a DoD Project
Experiences Bringing CD to a DoD ProjectExperiences Bringing CD to a DoD Project
Experiences Bringing CD to a DoD Project
Gene Gotimer
 
Bringing CD to the DoD
Bringing CD to the DoDBringing CD to the DoD
Bringing CD to the DoD
Gene Gotimer
 

More from Gene Gotimer (20)

A Developer’s Guide to Kubernetes Security
A Developer’s Guide to Kubernetes SecurityA Developer’s Guide to Kubernetes Security
A Developer’s Guide to Kubernetes Security
 
How I Learned to Stop Worrying and Love Legacy Code
How I Learned to Stop Worrying and Love Legacy CodeHow I Learned to Stop Worrying and Love Legacy Code
How I Learned to Stop Worrying and Love Legacy Code
 
Ten Ways To Doom Your DevOps
Ten Ways To Doom Your DevOpsTen Ways To Doom Your DevOps
Ten Ways To Doom Your DevOps
 
Keeping Your Kubernetes Cluster Secure
Keeping Your Kubernetes Cluster SecureKeeping Your Kubernetes Cluster Secure
Keeping Your Kubernetes Cluster Secure
 
Keeping your Kubernetes Cluster Secure
Keeping your Kubernetes Cluster SecureKeeping your Kubernetes Cluster Secure
Keeping your Kubernetes Cluster Secure
 
Explain DevOps To Me Like I’m Five: DevOps for Managers
Explain DevOps To Me Like I’m Five: DevOps for ManagersExplain DevOps To Me Like I’m Five: DevOps for Managers
Explain DevOps To Me Like I’m Five: DevOps for Managers
 
Keeping your Kubernetes Cluster Secure
Keeping your Kubernetes Cluster SecureKeeping your Kubernetes Cluster Secure
Keeping your Kubernetes Cluster Secure
 
Creative Solutions to Already Solved Problems
Creative Solutions to Already Solved ProblemsCreative Solutions to Already Solved Problems
Creative Solutions to Already Solved Problems
 
Pyramid Discussion: DevOps Adoption in Large, Slow Organizations
Pyramid Discussion: DevOps Adoption in Large, Slow OrganizationsPyramid Discussion: DevOps Adoption in Large, Slow Organizations
Pyramid Discussion: DevOps Adoption in Large, Slow Organizations
 
Building the Pipeline of My Dreams
Building the Pipeline of My DreamsBuilding the Pipeline of My Dreams
Building the Pipeline of My Dreams
 
Open Source Security Tools for the Pipeline
Open Source Security Tools for the PipelineOpen Source Security Tools for the Pipeline
Open Source Security Tools for the Pipeline
 
Which Development Metrics Should I Watch?
Which Development Metrics Should I Watch?Which Development Metrics Should I Watch?
Which Development Metrics Should I Watch?
 
Add Security Testing Tools to Your Delivery Pipeline
Add Security Testing Tools to Your Delivery PipelineAdd Security Testing Tools to Your Delivery Pipeline
Add Security Testing Tools to Your Delivery Pipeline
 
Testing in a Continuous Delivery Pipeline - Better, Faster, Cheaper
Testing in a Continuous Delivery Pipeline - Better, Faster, CheaperTesting in a Continuous Delivery Pipeline - Better, Faster, Cheaper
Testing in a Continuous Delivery Pipeline - Better, Faster, Cheaper
 
Experiences Bringing CD to a DoD Project
Experiences Bringing CD to a DoD ProjectExperiences Bringing CD to a DoD Project
Experiences Bringing CD to a DoD Project
 
Bringing CD to the DoD
Bringing CD to the DoDBringing CD to the DoD
Bringing CD to the DoD
 
Tests your pipeline might be missing
Tests your pipeline might be missingTests your pipeline might be missing
Tests your pipeline might be missing
 
Continuous Delivery in a Legacy Shop - One Step at a Time
Continuous Delivery in a Legacy Shop - One Step at a TimeContinuous Delivery in a Legacy Shop - One Step at a Time
Continuous Delivery in a Legacy Shop - One Step at a Time
 
Create Disposable Test Environments with Vagrant and Puppet
Create Disposable Test Environments with Vagrant and PuppetCreate Disposable Test Environments with Vagrant and Puppet
Create Disposable Test Environments with Vagrant and Puppet
 
Bringing Continuous Delivery to the Enterprise: It's all about the Mindset
Bringing Continuous Delivery to the Enterprise: It's all about the MindsetBringing Continuous Delivery to the Enterprise: It's all about the Mindset
Bringing Continuous Delivery to the Enterprise: It's all about the Mindset
 

Recently uploaded

Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 

Recently uploaded (20)

WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
 
Driving Innovation: Scania's API Revolution with WSO2
Driving Innovation: Scania's API Revolution with WSO2Driving Innovation: Scania's API Revolution with WSO2
Driving Innovation: Scania's API Revolution with WSO2
 
WSO2CON2024 - Why Should You Consider Ballerina for Your Next Integration
WSO2CON2024 - Why Should You Consider Ballerina for Your Next IntegrationWSO2CON2024 - Why Should You Consider Ballerina for Your Next Integration
WSO2CON2024 - Why Should You Consider Ballerina for Your Next Integration
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & InnovationWSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
 
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
 
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
WSO2CON 2024 - Building a Digital Government in Uganda
WSO2CON 2024 - Building a Digital Government in UgandaWSO2CON 2024 - Building a Digital Government in Uganda
WSO2CON 2024 - Building a Digital Government in Uganda
 
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of TransformationWSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
 
WSO2Con2024 - Unleashing the Financial Potential of 13 Million People
WSO2Con2024 - Unleashing the Financial Potential of 13 Million PeopleWSO2Con2024 - Unleashing the Financial Potential of 13 Million People
WSO2Con2024 - Unleashing the Financial Potential of 13 Million People
 

Get to Green: How to Safely Refactor Legacy Code

  • 1. 8/7/2019 1 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 1@CoverosGene #THATConference Agility. Security. Delivered.Get to Green: How to Safely Refactor Legacy Code Gene Gotimer @CoverosGene © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 2@CoverosGene #THATConference Agility. Security. Delivered.
  • 2. 8/7/2019 2 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 3@CoverosGene #THATConference About Coveros • Coveros helps companies accelerate the delivery of secure, reliable software using agile methods • Agile & DevOps Services • DevOps Implementation • DevSecOps Integration • Agile Transformations & Coaching • Agile Software Development • Agile Testing & Automation • Agile, DevOps, Testing, Security Training • Open Source Products • SecureCI – Secure DevOps toolchain • Selenified – Agile test framework Development Platforms © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 4@CoverosGene #THATConference Selected Commercial Clients
  • 3. 8/7/2019 3 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 5@CoverosGene #THATConference Selected Federal Clients © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 6@CoverosGene #THATConference Refactoring Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. Martin Fowler, https://refactoring.com
  • 4. 8/7/2019 4 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 7@CoverosGene #THATConference Legacy Code Legacy code is simply code without tests. Code without tests is bad code. Michael C. Feathers, Working Effectively with Legacy Code © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 8@CoverosGene #THATConference Addressing Legacy Code The temptation is to get rid of it and start over from scratch. But even if legacy code is bad code: • it works (maybe, sort of) • it is a known quantity • there may be a reason the solution isn’t as simple as you think it could or should be
  • 5. 8/7/2019 5 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 9@CoverosGene #THATConference Why Refactor At All? If it works, why change it? Because bad code carries cost and risk. • What if it needs to be updated? • What if it has a security issue? • What if it is incompatible with an update that fixes a security problem? • Be proactive, not reactive. • Don't wait until it has to be changed right now. © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 10@CoverosGene #THATConference Example Refactored Code public boolean isUserAllowed(User someUser) { boolean isAllowed = false; for (String role : someUser.userRoles()) { if (this.currentService.allowedRoles().contains(role)) { isAllowed = true; break; } } return isAllowed; } public boolean isUserAllowed(User someUser) { return this.currentService.allowedRoles().stream() .anyMatch(someUser.userRoles()::contains); }
  • 6. 8/7/2019 6 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 11@CoverosGene #THATConference Refactoring © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 12@CoverosGene #THATConference Catalog of Refactorings • Change Function Declaration • Change Reference to Value • Change Value to Reference • Collapse Hierarchy • Combine Functions into Class • Combine Functions into Transform • Consolidate Conditional Expression • Decompose Conditional • Encapsulate Collection • Encapsulate Record • Encapsulate Variable • Extract Class • Extract Function • Extract Superclass • Extract Variable • Hide Delegate • Inline Class • Inline Function • Inline Variable • Introduce Assertion • Introduce Parameter Object • Introduce Special Case • Move Field • Move Function • Move Statements into Function • Move Statements to Callers • Parameterize Function • Preserve Whole Object • Pull Up Constructor Body • Pull Up Field • Pull Up Method • Push Down Field • Push Down Method • Remove Dead Code • Remove Flag Argument • Remove Middle Man • Remove Setting Method • Remove Subclass • Rename Field • Rename Variable • Replace Command with Function • Replace Conditional with Polymorphism • Replace Constructor with Factory Function • Replace Control Flag with Break • Replace Derived Variable with Query • Replace Error Code with Exception • Replace Exception with Precheck • Replace Function with Command • Replace Inline Code with Function Call • Replace Loop with Pipeline • Replace Magic Literal • Replace Nested Conditional with Guard Clauses • Replace Parameter with Query • Replace Primitive with Object • Replace Query with Parameter • Replace Subclass with Delegate • Replace Superclass with Delegate • Replace Temp with Query • Replace Type Code with Subclasses • Return Modified Value • Separate Query from Modifier • Slide Statements • Split Loop • Split Phase • Split Variable • Substitute Algorithm https://refactoring.com/catalog/
  • 7. 8/7/2019 7 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 13@CoverosGene #THATConference What to Refactor Do not refactor that which offends you. Refactor that which impedes you. Tim Ottinger, @tottinge © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 14@CoverosGene #THATConference First Step Whenever I do refactoring, the first step is always the same. I need to build a solid set of tests for that section of code. Martin Fowler, Refactoring: Improving the Design of Existing Code
  • 8. 8/7/2019 8 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 15@CoverosGene #THATConference Unit Testing Unit testing is a way for developers to document the behavior of code. Unit tests • are automated, • are independent, • usually test individual methods or smaller, • have no external dependencies, and • become our safety net for fearless refactoring. © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 16@CoverosGene #THATConference Unit Testing Enables Change • The challenge of how to refactor legacy code becomes a challenge of how to unit test legacy code. • Once it has tests, it isn’t legacy code anymore. • We have a safety net. • We can fearlessly refactor. • We can just follow the catalog of refactorings. • And/or we can modify the behavior safely in the future.
  • 9. 8/7/2019 9 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 17@CoverosGene #THATConference Testing a Private Method private double getPerimeter() { double perimeter = 0.0d; for (double length : lengths) { perimeter += length; } return perimeter; } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) double getPerimeter() { double perimeter = 0.0d; for (double length : lengths) { perimeter += length; } return perimeter; } © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 18@CoverosGene #THATConference Key Takeaways • Safety is the goal. Strive for fearless refactoring. • Don't over-complicate the solution. • Unit tests will almost always be the safety net, but it doesn't have to be unit tests. Simple code reviews can provide a safety net.
  • 10. 8/7/2019 10 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 19@CoverosGene #THATConference Code Coverage • Measures code executed when unit tests run • NOT amount of code tested • Good tool to find untested code • Not covered == not tested • Covered == possibly tested © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 20@CoverosGene #THATConference Mutation Testing Mutation testing public int foo(int i) { i--; return i; } public int foo(int i) { i++; return i; } public String bar(String s) { if (s == null) { // do something public String bar(String s) { if (s != null) { // do something
  • 11. 8/7/2019 11 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 21@CoverosGene #THATConference PIT Report Example Light green shows line coverage, dark green shows mutation coverage. Light pink show lack of line coverage, dark pink shows lack of mutation coverage. © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 22@CoverosGene #THATConference Key Takeaways • Code coverage tells you what code is executed during tests. • Mutation testing tells you what code is tested. • You don't need 100% tested, but at least the pieces that you want to change need a safety net.
  • 12. 8/7/2019 12 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 23@CoverosGene #THATConference Testing a God Method • God method = “The Method That Does Everything” • For example: 2,000-line Java method, private static void • Nothing but side effects • Modifies parameters • Calls external services • Implements time travel, I assume • Small, incremental changes • Need a safety net • Unit testing will be necessary, but difficult © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 24@CoverosGene #THATConference “Untestable” Code We want to add tests, but the code isn’t making that easy. • Important methods are void, rely on side effects, etc. • Long methods do too much to comprehend, or require complicated and specific setup before the test can be executed. • Other code or services are invoked from within, so the unit of code can’t be easily isolated.
  • 13. 8/7/2019 13 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 25@CoverosGene #THATConference Mock Frameworks • Allow you to create objects that have predetermined responses to specific requests. • Rely on interfaces to replace “real” instances. • Replacement for external services in unit tests, • or sometimes when it is just tedious to create a graph of objects. • Dependency injection makes testing with mocks easy. when(mockService.get(anyInt()).thenReturn("foo"); when(mockService.get(-1).thenThrow(new IllegalArgumentException()); © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 26@CoverosGene #THATConference Using mocks public ZapSensor(ZapSensorConfiguration configuration, FileSystem fileSystem, PathResolver pathResolver, Rules rules) { this.rules = rules; this.report = new XmlReportFile(configuration, fileSystem, pathResolver); } @Before public void setUp() { final ZapSensorConfiguration configuration = mock(ZapSensorConfiguration.class); final FileSystem fileSystem = mock(FileSystem.class); final PathResolver pathResolver = mock(PathResolver.class); final Rules rules = mock(Rules.class); this.zapSensor = new ZapSensor(configuration, fileSystem, pathResolver, rules); }
  • 14. 8/7/2019 14 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 27@CoverosGene #THATConference PowerMock • Useful when you don't have interfaces or dependency injection • Extends Mockito and EasyMock • Uses reflection to mock • constructors • final methods • static methods • private methods • Make PowerMock use temporary. The goal is to use it to refactor so that you do not need it. “Please note that PowerMock is mainly intended for people with expert knowledge in unit testing. Putting it in the hands of junior developers may cause more harm than good.” © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 28@CoverosGene #THATConference Using PowerMock … void addIssue(SensorContext context, AlertItem alert) { Severity severity = ZapUtils.riskCodeToSonarQubeSeverity(alert.getRiskcode()); … mockStatic(ZapUtils.class); … when(ZapUtils.riskCodeToSonarQubeSeverity(3)) .thenReturn(Severity.CRITICAL);
  • 15. 8/7/2019 15 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 29@CoverosGene #THATConference Removing PowerMock … void addIssue(SensorContext context, AlertItem alert) { Severity severity = ZapUtils.riskCodeToSonarQubeSeverity(alert.getRiskcode()); … void addIssue(SensorContext context, Severity severity) { © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 30@CoverosGene #THATConference Removing PowerMock public static Severity riskCodeToSonarQubeSeverity(int riskcode) { if (riskcode == 3) { return Severity.CRITICAL; } else if (riskcode == 2) { return Severity.MAJOR; } else if (riskcode == 1) { return Severity.MINOR; } else { return Severity.INFO; } }
  • 16. 8/7/2019 16 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 31@CoverosGene #THATConference Removing PowerMock @Deprecated public static Severity riskCodeToSonarQubeSeverity(int riskcode) { return new ZapUtils().riskCodeToSonarQubeSeverity(riskcode); } public Severity riskCodeToSonarQubeSeverity(int riskcode) { if (riskcode == 3) { return Severity.CRITICAL; } else if (riskcode == 2) { return Severity.MAJOR; } else if (riskcode == 1) { return Severity.MINOR; } else { return Severity.INFO; } } © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 32@CoverosGene #THATConference Key Takeaways • Use mocking frameworks to isolate units from external dependencies. • Mocks can also simplify tests by making it easier to set up objects that you need but aren't directly involved in the test. • Frameworks like PowerMock can be used as temporary solutions. The goal is to use PowerMock to safely refactor until you don't need PowerMock anymore.
  • 17. 8/7/2019 17 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 33@CoverosGene #THATConference Static Code Analysis • Inspects source code for • code coverage • duplicated code • complex code • tightly coupled code • security issues • Helps identify riskiest code • Refactoring opportunities • Also shows • unused variables • confusing code • best practices • coding standards © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 34@CoverosGene #THATConference
  • 18. 8/7/2019 18 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 35@CoverosGene #THATConference IDE Code Inspections • IDEs have some static analysis built-in (red, squiggly lines) • Other static analysis tools can be integrated • e.g., SonarLint • Quicker feedback loop, could show some low-hanging fruit © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 36@CoverosGene #THATConference IDE Refactoring • IDEs have built-in refactoring support • You still need unit tests as the safety net
  • 19. 8/7/2019 19 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 37@CoverosGene #THATConference Key Takeaways • Static code analysis tools can identify riskiest code, which are prime candidates for refactoring. • IDEs often have static code analysis built in. • IDEs often have refactoring tools built in. You still need unit tests. © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 38@CoverosGene #THATConference General Plan of Attack For example, for our 2,000-line Java method, private static void 1. Unit test with mocks to isolate units. 2. Use PowerMock when necessary. 3. Use mutation testing to make sure code being touched is tested. 4. Replace chunks with package-private methods, @VisibleForTesting. 5. Refactor to eliminate the need for PowerMock. 6. Let static analysis tools identify refactoring opportunities. 7. Use IDE tools to perform individual refactorings. One change at a time. Refactor – Test – Repeat.
  • 20. 8/7/2019 20 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 39@CoverosGene #THATConference #Coveros5 • Safety is the goal. Strive for fearless refactoring. • Unit tests are the best safety net for making code changes. • Use mutation testing to make sure your unit tests are actually covering what you need covered. • Use a combination of mocking tools and mocks to isolate your units to test. • Make small, incremental, safe changes. © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 40@CoverosGene #THATConference Tools Required • Unit testing framework • Code coverage tool • Mutation testing tool • Mock frameworks • Static analysis tools • IDE refactoring tools • Lots of patience
  • 21. 8/7/2019 21 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 41@CoverosGene #THATConference Java Tools • JUnit https://junit.org • JaCoCo https://www.eclemma.org/jacoco • PIT http://pitest.org • Mockito https://github.com/mockito/mockito • EasyMock http://easymock.org • PowerMock https://github.com/powermock/powermock • PMD CPD https://pmd.github.io • SonarQube https://www.sonarqube.org © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 42@CoverosGene #THATConference C#/.NET Tools • NUnit https://nunit.org • NCover (commercial) https://www.ncover.com • OpenCover https://github.com/OpenCover/opencover • Ninja Turtles http://www.mutation-testing.net • Moq https://github.com/moq/moq4 • Microsoft Fakes https://docs.microsoft.com/en- us/visualstudio/test/isolating-code-under-test-with-microsoft-fakes • PMD CPD https://pmd.github.io • SonarQube https://www.sonarqube.org
  • 22. 8/7/2019 22 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 43@CoverosGene #THATConference Reading List • Refactoring: Improving the Design of Existing Code, by Martin Fowler https://amzn.com/0134757599 • Working Effectively with Legacy Code, by Michael Feathers https://amzn.com/0131177052 • Clean Code: A Handbook of Agile Software Craftsmanship, by Robert C. Martin https://amzn.com/0132350882 • Pragmatic Unit Testing in Java 8 with JUnit, by Jeff Langr https://amzn.com/1941222595 © COPYRIGHT 2019 COVEROS, INC. ALL RIGHTS RESERVED. 44@CoverosGene #THATConference Questions? gene.gotimer@coveros.com @CoverosGene https://hub.techwell.com/ Live refactoring office hours: Tuesday, August 13, noon-1PM Central Time I'll post a link on Slack.