I Stand With Ukraine
“We need tests to refactor,
but we need to refactor
to make the code testable.”
Slide 3
Slide 3 text
I Stand With Ukraine
Anna Filina
• Coding since 1997.
• PHP, Java, C#, Flash, etc.
• Legacy archaeology.
• Test automation.
• Mentoring.
• Filina Consulting.
Slide 4
Slide 4 text
I Stand With Ukraine
Slide 5
Slide 5 text
I Stand With Ukraine
No Tests
Slide 6
Slide 6 text
I Stand With Ukraine
Slide 7
Slide 7 text
I Stand With Ukraine
Write tests
as part of other work.
Slide 8
Slide 8 text
I Stand With Ukraine
• Bug report.
• New feature.
• Refactoring.
• Build coverage over time.
Slide 9
Slide 9 text
I Stand With Ukraine
Not Unit-Testable
Slide 10
Slide 10 text
I Stand With Ukraine
• Might bootstrap the framework.
• Hit the database.
• Call external APIs.
• Require extensive mocking.
Slide 11
Slide 11 text
I Stand With Ukraine
Unit tests end up being
convoluted and not useful.
Slide 12
Slide 12 text
I Stand With Ukraine
Slide 13
Slide 13 text
I Stand With Ukraine
Slide 14
Slide 14 text
I Stand With Ukraine
Slide 15
Slide 15 text
I Stand With Ukraine
• Break up class.
• Extract method.
• Change method signature.
• Reorganize dependencies.
Slide 16
Slide 16 text
I Stand With Ukraine
Slide 17
Slide 17 text
I Stand With Ukraine
Slide 18
Slide 18 text
I Stand With Ukraine
ASP
Classic
Slide 19
Slide 19 text
I Stand With Ukraine
PHP
Slide 20
Slide 20 text
I Stand With Ukraine
Scenario: User can subscribe with a credit card
Given I selected a subscription level
When I enter valid credit card details
Then I should see a payment receipt
Slide 21
Slide 21 text
I Stand With Ukraine
• Behat
• Codeception
Slide 22
Slide 22 text
I Stand With Ukraine
Slower but fewer
Slide 23
Slide 23 text
I Stand With Ukraine
Unit Tests
Slide 24
Slide 24 text
I Stand With Ukraine
Slide 25
Slide 25 text
I Stand With Ukraine
Slide 26
Slide 26 text
I Stand With Ukraine
class ProductController extends AbstractController
{
public function search()
{
//...
$products = $this->repository->search($criteria);
return $this->render("products/search.html.twig", $products);
}
}
Slide 27
Slide 27 text
I Stand With Ukraine
class ProductController
{
//...
public function __construct(Templating $templating)
{
$this->templating = $templating;
}
public function search()
{
//...
$products = $this->repository->search($criteria);
return $this->templating->render("products/search.html.twig", $products);
}
}
Slide 28
Slide 28 text
I Stand With Ukraine
New Tests
• Write characterization that survive refactoring.
• Write unit tests for new or refactored code.
Slide 29
Slide 29 text
I Stand With Ukraine
Broken Tests
Slide 30
Slide 30 text
I Stand With Ukraine
• Didn't compile.
• Most failed due to DB changes.
• After fixes, many kept failing.
• After review, most were wrong or redundant.
Slide 31
Slide 31 text
I Stand With Ukraine
• Checking that something did not happen.
• Comparing large DB dump after execution.
• Many unnecessary permutations.
• Many scenarios untested despite 300 tests.
Slide 32
Slide 32 text
I Stand With Ukraine
Afraid to throw
code away
Slide 33
Slide 33 text
I Stand With Ukraine
• Fixing estimated at 6 months.
• The tests would still be unmaintainable.
• Many scenarios would still require new tests.
I Stand With Ukraine
• 46 new tests.
• All scenarios covered.
• No redundancies.
• Easy to read and to maintain.
Slide 36
Slide 36 text
I Stand With Ukraine
Scenario: Add warning for invalid city
Given city exists for PL-POZ
And file contains entry for PL-POZ / 2024-01-01
And file contains entry for CA-MTL / 2024-01-01
When I execute Import Daily Weather
Then 1 weather entry should have been imported
And warning Invalid city code "CA-MTL" should be logged
Slide 37
Slide 37 text
I Stand With Ukraine
Existing Tests
• Will the tests survive refactoring?
• Effort of fixing vs rewriting tests.
• Do the tests give you confidence?
• Can you maintain these tests?