w7 - Testing and Code Review
w7 - Testing and Code Review
∞ NTU 1
Dr. Scott McMaster, Sr. Technical Manager
Experience: Education:
• Nearly 30 years of experience in IT, consumer software, • Ph.D. and M.S. (Computer Science), U. of Maryland, USA
engineering management and cloud computing • M.S.E. (Software Engineering), Seattle University, USA
• Former adjunct professor of Computer Science and Software • B.S. (Mathematics), U. of Nebraska, USA
Engineering at the University of Washington and Seattle
University
1995– 2002 2005 – 2007 2009 – 2015 2017 – 2019 2021 -- 2022
as Software Test
Engineering, Lead
as Software Engineer as Software Engineer as Senior Software as Founding Engineer TSMC
Engineering Manager
∞ NTU 2
Agenda
• Unit Testing
▪ “What” and “Why” of Unit Testing
▪ How to Structure a Unit Test
▪ Some Specific Unit Testing Techniques
• Functional Testing
▪ What is Functional Testing, and Differences From Unit Testing
▪ Designing and Automating Functional Tests
▪ Functional Tests in the Agile Process
• Code Review
▪ Why Review Code?
▪ How to Conduct a Code Review
▪ What to Look For
∞ NTU 3
UNIT TESTING
∞ NTU 4
What Makes Users Happy?
• Tests?
▪ Not clear that more tests => less bugs.
▪ Not clear that less tests => more bugs.
• => Tests don’t make users happy!
∞ NTU 5
How Do We Build a Lack of Bugs?
• One approach:
▪ Write and deploy a bunch of code.
▪ Have the testers and/or users take a look.
▪ Go back and fix the bugs.
• Why not this?
▪ It’s expensive.
▪ It’s frustrating.
▪ It has an open-ended timeframe.
∞ NTU 6
How Do We Stop Bugs Before Deployment?
∞ NTU 7
Bugs Stopped! We’re Done?
∞ NTU 8
Useful Software is Never Really “Done”
• In fact, it decays!
▪ Users need new features and changed business logic.
▪ Libraries need patches.
▪ The infrastructure is changing.
▪ The operating environment is changing.
∞ NTU 9
If You Touch It, It Will Break
• It’s Really Hard to safely make changes to software.
▪ Especially when you haven’t looked at that code in six months.
▪ Or somebody else wrote it.
• How do you get changed software into the hands of users without
introducing new bugs?
Automated tests!
∞ NTU 10
Where To Start Testing?
Scenario Tests
System Tests
Integration Tests
Unit Tests
∞ NTU 11
You Have to Start Somewhere
Scenario Tests
System Tests
Integration Tests
The Egyptians
started here,
too Unit Tests
∞ NTU 12
Automated Unit Tests
∞ NTU 13
Side Note: Unit Testing in the SDLC
• Unit testing isn’t really a “testing” activity
▪ It should not be part of your software testing estimates.
• Unit testing is a “coding” activity.
▪ It should be part of your software development estimates.
∞ NTU 14
What Does a “Good” Unit Test Do?
∞ NTU 15
How Does a “Good” Unit Test Do It?
∞ NTU 16
Let’s Look at Some Unit Tests!
∞ NTU 17
Here’s a Class
We should
definitely test this
Testing these is
debatable.
∞ NTU 18
Here’s a Test
Three observations to
follow…
∞ NTU 19
Observation 1: The Test Passes and is Fast!
∞ NTU 20
Observation 2: The Test Gets 100% Code Coverage!
∞ NTU 21
Observation 3: The Code We’re Testing is Spectacularly
Broken!
∞ NTU 22
Aside on Code Coverage
∞ NTU 23
Better Test
∞ NTU 24
Better Result
∞ NTU 25
Unit Test Structure
∞ NTU 26
Any Lingering Problems?
We didn’t test
the order date
value
∞ NTU 27
Idea 1: Use a Regular Expression
∞ NTU 28
Idea 2: Use the Date From the Order
∞ NTU 29
Idea 3: Take Control of the Date
∞ NTU 30
Side Quest: Software Design
∞ NTU 31
Testability
∞ NTU 32
How to Achieve Testability
∞ NTU 33
Test Doubles
∞ NTU 34
What Is There To Dislike With This Code?
∞ NTU 35
Constructor Cautions
∞ NTU 36
Constructors Can Be Bad For Testability
• Let’s make our constructors trivial.
• And private!
∞ NTU 37
Creational Design Patterns
• Factories
• Builders
∞ NTU 38
Builder Example
Note this
∞ NTU 39
I Thought We Were Discussing Unit Testing
• Now we can write a really good unit test for toString()
∞ NTU 40
Aside: You Should Unit Test the Builder, Too
∞ NTU 41
Aside 2: Better Ways to Handle the Clock
∞ NTU 43
Let’s Try Something Else – File Output
∞ NTU 44
First Try Unit Test
• How many problems do you see?
∞ NTU 45
Problem 1: Pollutes the Test Output
• By using a real logger – can make test output hard to read and debug
• Unit Testing Guideline: Don’t write to log files or the console in a unit
test.
∞ NTU 46
Fix 1: Use a Stub Logger
∞ NTU 47
Aside: Fakes vs. Stubs
∞ NTU 48
Fix 1 Continued
• Update the test
∞ NTU 49
Problem 2: Pollutes the File System
• This test can fail with a false negative if run more than once.
∞ NTU 50
Fix 2: Use Temp Directories and Files
• You can try to clean up files after a test, but if you fail, the system will eventually clean up for
you.
• And no worries about conflicting file names.
∞ NTU 51
Where We’ve Been
• “What” and “Why” of Unit Testing
• Arrange -> Act -> Assert
• Testability and Test Doubles
▪ Fake
▪ Stub
• Constructors, Builders, and Inversion of Control
• Temp Files in Unit Tests
∞ NTU 52
Much More
∞ NTU 53
Unit Testing Wrap-Up
∞ NTU 54
FUNCTIONAL TESTING
∞ NTU 55
Functional Tests
• Test like the user!
▪ Black-box =>
▫ You can’t see the code.
▫ You do not assume anything about the code.
▫ You can only see externally observable actions.
• Why?
▪ More realistic.
▪ Can explain to (and even develop with) your PM and/or users.
▪ One or two such tests might provide solid assurance that everything works well
for the user.
∞ NTU 56
Behold The Testing Pyramid (Again)
Scenario Tests
Unit Tests
∞ NTU 57
(Some) Types of Functional Tests
• Integration
▪ Multiple modules
• System
▪ Whole system put together on real (or realistic) infrastructure
• Scenario
▪ Whole system put together like a user would use it
∞ NTU 58
Functional vs. End-to-End (Scenario) Testing
• Difference (if any) depends on how you define the scope of the
“system”.
• Observation 1:
▪ Since some of our systems have effects in the physical world, true end-to-end
testing is not always possible/appropriate to do on a regular basis.
• Observation 2:
▪ Because of Observation 1, defining the system boundaries for functional testing
is important.
∞ NTU 59
Unit Testing vs. Functional Testing
∞ NTU 60
Unit Testing vs. Functional Testing
∞ NTU 61
Unit Testing vs. Functional Testing
Would you rather drive
after these are tested? Or this is tested?
∞ NTU 62
Agile Testing Quadrants
Automated &
Manual Business-Facing Manual
Support Engineering
Exploratory
Functional
Critique Product
UAT
Prevent User Story Detect
Scenario
Bugs Bugs
Performance
Unit Load
Component Chaos
Security
∞ NTU 63
Start Functional Testing
Let’s
NotAutomate!
So Fast
∞ NTU 64
Role of Automation in Functional Testing
∞ NTU 65
To Automate Functional Tests?
• Automated functional tests may require a significant investment to
create and maintain.
• Unless you release relatively frequently, the ROI may be low.
▪ Once a month might be worth it.
▪ Once a quarter may well not be.
• Depends heavily on the difficulty in automating.
• And this depends heavily on the specific system and its environment.
∞ NTU 66
Functional Test Automation ROI
• Estimate #Executions and $Maintenance over some % of the lifetime of the system.
• Consider some less-tangible factors (time to execute, reliability of execution).
• Only automate if Manual Cost >> Automation Cost in the final calculation.
∞ NTU 67
Releasing With Less-Than-Fully-Automated Tests
• When performing any manual release testing, there should be:
▪ Documented test cases
▫ Excel, Jira, or (better yet) a test case management system
▪ Reporting:
▫ What was tested
▫ By whom
▫ Results
▪ Sign-off to meet one or more of the following requirements:
▫ Compliance
▫ Accountability
▫ Trust
▫ => Can be done via the issue tracker
∞ NTU 68
Functional Test Design
∞ NTU 69
Functional Test Case Design
• Unlike with unit tests, it is NOT sufficient to rely on automation code to
specify functional tests!
• => We need documented functional test case designs.
▪ Even in Agile / DevOps.
• Documentation usually follows a test case template.
▪ Expect many people are already familiar with this idea.
▪ Can use the behavior-driven design (BDD) format.
▫ Given / When / Then
∞ NTU 70
Functional Test Case Template
Title
Priority
ID
Description
Setup/Teardown
Steps
Expected Results
∞ NTU 71
Functional Testing Timeline
• Given a new feature:
1. Design new functional tests as part of user story development.
2. Code the feature (and unit tests).
3. Manually run the functional tests for the feature in an integration environment ASAP.
4. Release the feature to UAT.
5. Re-test the feature in the UAT environment.
6. Release to users.
• When to automate:
▪ Between 2 and 3?
▪ Between 3 and 5?
▪ After 5? Suggestion: Don’t block a release
▪ Never? pending an automated functional
test.
∞ NTU 72
Automate Functional Tests
∞ NTU 73
Functional Test Automation Options
• Scripting
▪ Generally considered the best currently-feasible approach ⭐
• Capture/Replay
▪ Not recommended ❌
• Model-based testing
▪ May or may not be directly automatable (usually only applies well to certain systems)
• Test-in-production
▪ Canary testing
▪ Blue/Green deployments
▪ Shadow traffic
▪ May run into a lot of process and technology constraints in our environments
∞ NTU 74
Functional Test Technology Observations
• Functional test automation tends to be very application/domain-
specific.
▪ Unlike unit testing.
▪ Web != API != Mobile != Vendor != Infra Automation != AI/ML Sys != …
▫ And I mean, radically !=
▪ => No single or right-or-wrong answer to automation technology choices.
• However:
▪ The most interesting problems with functional test automation are around quality
processes, not technical implementations 💡
∞ NTU 75
Functional Test Scripting Technology
• Can often use the same tech used in unit testing.
▪ xUnit, TestContainers, your IDE, CI/CD system
▪ API, service, and database simulation and virtualization where needed.
• Video recording / screenshots
• Fuzzy/visual verification tools.
• Shared environments and databases.
▪ Be careful with state management, setup and teardown.
• Can use a dedicated “test scripting language”.
▪ Typically, Python or JavaScript these days.
∞ NTU 76
Functional Testing Metrics
• % Automated (vs. Manual)
• Product Coverage
▪ Can use user stories and tasks.
▪ Or requirements.
▪ Can include non-functional requirements (performance, load, etc.)
▪ Count test cases per criterion and note that there can be a M:M relationship between test
cases and product criteria.
• Risk Coverage
▪ Enumerate the risks / things that can go wrong.
• Code Coverage?
▪ Fun fact: You can collect code coverage from functional testing (including manual
functional testing).
∞ NTU 77
Functional Testing in the SDLC
∞ NTU 78
Functional Testing in the Waterfall
Requirements
Design
Implementation
Testing
Deployment
Maintenance
∞ NTU 79
Functional Testing in Agile
Deployment Planning
This does
not refer to
unit testing
Testing Design
Implementation
∞ NTU 80
Functional Testing in Waterfall vs. Agile
• The main difference is how often you perform the functional testing
process:
▪ Waterfall:
▫ Expectation is that the cycle is very long, so you can afford a “long” test phase.
▪ Agile:
▫ Expectation is that the cycle is short, and therefore each individual phase must be
short.
♦ Implies the “Testing” phase must proceed quickly.
♦ Number of tests you can run may be limited.
∞ NTU 81
Agile Functional Testing Challenge
∞ NTU 82
Let’s Test Agilely
∞ NTU 83
Agile Functional Testing Process
• Execute and report on tests with each release.
• Add regression tests when bugs are found in UAT or production.
• Opportunistically automate the highest-priority functional test cases.
• Consider cost-based and risk-based tradeoffs.
∞ NTU 84
Example Agile Testing Process
Sprint 1
Release 1
Story 1 Func Test 1
Sprint 1 Sprint 2
Release 1
Release 2
Story 1 Func Test 1 Story 4 Func Test 4
Release 1
Release 3
Release 2
Story 1 Func Test 1 Story 4 Func Test 4 Story 8 Func Test 8
Sprint 3 Sprint 4
Release 3
Release 4
Story 8 Func Test 8 Story 10 Func Test 10
Regr Test 1
Regression tests
BUG 1
are usually the top
automation priority
∞ NTU 89
CODE REVIEWS
∞ NTU 90
Why Do Code Reviews?
• Educate developers.
▪ Onboard new engineers faster.
▪ Share new programming
practices and libraries.
▪ Works both ways (reviewer <->
author)
• Spread knowledge around the team.
▪ At least two engineers then
know how to debug each piece
of code.
∞ NTU 91
Why Do Code Reviews? (2)
∞ NTU 92
Why Do Code Reviews? (3)
• Prepare the code for future maintenance.
▪ Reduce complexity.
▪ Increase readability.
• Detect defects
▪ Find bugs by inspection.
▪ Cheaper to fix during review than after merge.
I put this
one last ☺
∞ NTU 93
Code Review Roles
• Author:
▪ The person writing the code
and requesting a review of a
merge request.
• Reviewer:
▪ One or more engineers
reviewing the merge request,
making comments, and
(ultimately) approving.
▪ May be “required” or
“optional”.
∞ NTU 94
Code Review Terminology
∞ NTU 95
Code Review Prerequisites
• Before a code review is requested, the code must:
▪ Be formatted according to standards
▪ Pass all linter checks
▪ Pass all new and existing unit tests
▪ Pass all other continuous integration (CI) checks
• Select reviewer(s)
▪ Good practice is two reviewers when possible:
▫ One reviewer more experienced in the domain or codebase.
▫ One reviewer less experienced in the domain or codebase.
∞ NTU 96
Code Review: Author Perspective
∞ NTU 97
Code Review: Author Perspective (2)
• Include new/improved unit tests in the same merge request.
▪ Test size counts toward the overall review size (make your merge requests small).
• Write a clear merge request title and description.
▪ Add details to the merge request to help the reviewer.
▫ Link to issue?
▫ Link to design document?
▫ Additional comments and explanations?
▫ Consider speaking 1:1 if that will help.
▫ Consider making review comments on your own code (but also if that should really be
a source comment).
∞ NTU 98
Code Review: Author Perspective (3)
• Consider adding screenshots or video if the change has UI.
∞ NTU 99
Tips for Creating Small Merge Requests
• Remember each merge request should do one (and only one) thing.
• Use feature flags.
▪ Keep work not ready to launch behind flags and off.
▪ Extra benefit: Feature flags make production releases less risky.
∞ NTU 100
Code Review: Reviewer Perspective
• Before starting:
▪ Does the code satisfy the Code
Review Prerequisites?
▪ Do you understand the change
well enough to review?
▫ If not, ask for explanation.
▪ Are there any other reviewers
that should be added?
• Dedicate a block of time.
▪ Less effective to switch back
and forth between other tasks
while reviewing.
∞ NTU 101
Things to Look for in Code Reviews
• Coding style
▪ Should match the style guide for the
languages used
• Naming
▪ Functions/methods
▪ Variables
▪ Packages
▪ Files
▪ Classes
• Readability
▪ Control structures that are easy to
understand
▪ Minimize levels of nesting {}
∞ NTU 102
Things to Look for in Code Reviews (2)
• Repetitive code
▪ Introduce constants for hard-coded
strings and numbers.
▪ Refactor common code to helper
functions.
• Documentation quality
▪ “Just right” amount of comments.
▫ Prefer to simplify the code!
▪ Extra care for documentation of code
being reused by other teams.
• Performance
▪ Efficient use of data structures and
algorithms
▪ Minimize RPC/database calls
∞ NTU 103
Things to Look for in Code Reviews (3)
• Logging
▪ Levels
▪ No PII, passwords, tokens, etc.
▪ Useful messages with context.
• Dependencies
▪ Use of approved libraries and
frameworks
▪ Reusable code in other projects
▪ Impacts on projects that depend
on the reviewed code
∞ NTU 104
Things to Look for in Code Reviews (4)
∞ NTU 105
Things to Look for in Code Reviews (5)
• Error handling
▪ Usually something other than simply logging
▪ Exceptions vs. error codes
• Language-specific issues
• Unit tests
▪ For new features and changes
▪ All “interesting” inputs are covered
▪ Assertions that validate that the code did what was expected
• Think about the overall architecture and design
▪ Easy to forget when you’re focused on individual lines of code.
∞ NTU 106
Reviewer FAQs at This Point
∞ NTU 107
Code Review Checklist (Example)
https://codereviewchecklist.com
∞ NTU 108
Social Aspects of Code Review
∞ NTU 109
Code Review Service Level Agreement
∞ NTU 110
Delivering Code Review Feedback
• Be polite
▪ Focus on the code and making the code better,
not on the author.
• Explain why
▪ Refer to style guide or best practice.
▪ Point out how the suggestion improves the
code and its long-term maintainability.
• Make optional suggestions.
▪ Some things are interesting to point out but not
worth changes.
▪ Possible alternate solutions.
• Include compliments.
▪ “This function is particularly clear, nice job.”
∞ NTU 111
Handling Disagreements
• Assume the style guide is correct.
• Reviewer:
▪ Remember that the author of the merge request probably knows the code better
than you.
• Author:
▪ If it’s not in the style guide and there are no other deciding factors, bias toward
implementing the reviewer’s request.
• Worst case:
▪ Ask the team, tech lead, or manager for an opinion.
▪ Should be very rare.
∞ NTU 112
Requests for Cleanup/Simplification
∞ NTU 113
Use the Tools
∞ NTU 114
Use the Tools Most Effectively (some lesser-known features)
• “Start a Review”
▪ Batches up a bunch of comments to be published together.
• Suggestions
▪ Reviewer can write code in the comment, author can one-click apply.
• Drafts
▪ Start a merge request in “draft” mode, mark as “ready for review” later.
• See history / updates of the merge request
▪ Rewind through branch history to see the previously reviewed state of the code
• Bot reviewers
▪ Linters that run in the pipeline and insert comments to the review
∞ NTU 115
Code Reviews Wrap-Up
∞ NTU 116
Thank You!