Increasing Code coverage with Gemini
On my last post I asked Gemini to create a product requirement document to outline a plan to improve the overall state of the ev-calc-pricing application. In this blog entry I will discuss my interaction with Gemini and how it increased code coverage of the ev-calc-pricing application. Below is an example of the prompts:
----
> review PRD.md for @ev-calc-pricing
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ ReadFile PRD.md │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ The PRD.md outlines a plan to refactor the ev-calc-pricing application to improve maintainability, data accuracy, and
robustness.
Key issues identified:
* Manual, hardcoded electricity rate data in StateRates.pm.
* Minimal test coverage.
* Unused scripts and lack of input validation.
The plan focuses on four epics:
1. Automated Data Pipeline: To fetch, process, and load electricity rate data automatically.
2. Comprehensive Test Suite: To ensure accuracy and stability of calculations and data loading.
3. Code Refactoring and Cleanup: To remove hardcoded data, unused scripts, and consolidate data files.
4. Enhanced User Experience: To add input validation and better user feedback.
The success metrics include reducing data update time, increasing code coverage to over 80%, and eliminating
calculation-related bugs.
> Lets focus on code coverage
✦ Okay, code coverage. The PRD says EVCalc.pm and StateRates.pm need unit tests. I'll start by reviewing the existing
tests in the t/ directory.
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ ReadFolder t │
│ │
│ Listed 2 item(s). │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ Okay, two test files: 001_base.t and 002_index_route.t. I'll read 001_base.t first to see what it covers.
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ ReadFile t/001_base.t │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ 001_base.t just loads EVCalc. Now reading 002_index_route.t to check its web interface tests.
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ ReadFile t/002_index_route.t │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ 002_index_route.t is a simple integration test for the main route. I'll now examine EVCalc.pm to understand the core
logic for testing.
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ✓ ReadFile lib/EVCalc.pm │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
✦ I've analyzed EVCalc.pm and found the calculation logic is embedded in the post '/' route. To properly test it, I'll
refactor the calculations into a new calculate_costs subroutine. My plan is to move the logic, create a new test file
t/003_calculation.t, and then write unit tests for various scenarios. I'm starting with the refactoring of EVCalc.pm
now.
-------------
And yes Gemini did refactor my code in order to create a test file and test the new function but unfortunately it didn't get it write in the first try.
Here is the refactored code with the test script
And now the correction on the test script .
line of code in the test script :
------------
is( $results{state_rates}->{'Alabama'}->{total_price}, '10.77', 'Correct total price for Alabama' );
------------
Essentially Gemini assumed that the states were abbreviated on StateRates.pm until it attempted a test run and learned that not only the state name was incorrect but also the calculated results. So you see AI just like humans have moments where it forgets what it wrote a few mins ago.
And now for the coverage report:
---------------------------------------
t/001_base.t ......... ok
t/002_index_route.t .. 1/2 [EVCalc:26770] core @2025-11-01 22:13:40> looking for get / in /Library/Perl/5.34/Dancer2/Core/App.pm l. 37
[EVCalc:26770] core @2025-11-01 22:13:40> Entering hook core.app.before_request in (eval 279)[/System/Library/Perl/Extras/5.34/Class/Method/Modifiers.pm:89] l. 1
[EVCalc:26770] core @2025-11-01 22:13:40> Entering hook core.app.after_request in (eval 279)[/System/Library/Perl/Extras/5.34/Class/Method/Modifiers.pm:89] l. 1
[EVCalc:26770] core @2025-11-01 22:13:40> running hook entry Dancer2::Core::App::__ANON__ in (eval 279)[/System/Library/Perl/Extras/5.34/Class/Method/Modifiers.pm:89] l. 1
t/002_index_route.t .. ok
t/003_calculation.t .. ok
All tests successful.
Files=3, Tests=6, 1 wallclock secs ( 0.01 usr 0.00 sys + 0.87 cusr 0.08 csys = 0.96 CPU)
Result: PASS
Reading database from /Users/itcharlie/Desktop/Projects/ev-calc-pricing/cover_db
---------------------- ------ ------ ------ ------ ------ ------
File stmt bran cond sub time total
---------------------- ------ ------ ------ ------ ------ ------
blib/lib/EVCalc.pm 100.0 n/a n/a 100.0 99.9 100.0
blib/lib/StateRates.pm 100.0 n/a n/a 100.0 0.0 100.0
Total 100.0 n/a n/a 100.0 100.0 100.0
---------------------- ------ ------ ------ ------ ------ ------
---------------------------------------
Leave a comment