I create modern web applications and custom digital tools to help businesses grow through technological innovation. My passion is combining computer science and economics to generate real value.
My passion for computer science was born at the Technical Commercial Institute of Maglie, where I discovered the power of programming and the fascination of creating digital solutions. From the start, I understood that computer science was not just code, but an extraordinary tool for turning ideas into reality.
During my studies in Business Information Systems, I began to interweave computer science and economics, understanding how technology can be the engine of growth for any business. This vision accompanied me to the University of Bari, where I obtained my degree in Computer Science, deepening my technical skills and passion for software development.
Today I put this experience at the service of businesses, professionals and startups, creating tailor-made digital solutions that automate processes, optimize resources and open new business opportunities. Because true innovation begins when technology meets the real needs of people.
My Skills
Data Analysis & Predictive Models
I transform data into strategic insights with in-depth analysis and predictive models for informed decisions
Process Automation
I create custom tools that automate repetitive operations and free up time for value-added activities
Custom Systems
I develop tailor-made software systems, from platform integrations to customized dashboards
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Democratizzare la Tecnologia
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
Unire Informatica ed Economia
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
Creare Soluzioni su Misura
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Trasforma la Tua Attività con la Tecnologia
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Bari, Puglia, Italy · Hybrid
Analysis and development of computer systems through the use of Java and Quarkus in Health and Public Sector. Continuous training on modern technologies for creating customized and efficient software solutions and on agents.
💼
06/2022 - 12/2024
Software analyst and Back End Developer Associate Consultant
Links Management and Technology SpA
Experience analyzing as-is software systems and ETL flows using PowerCenter. Completed Spring Boot training for developing modern and scalable backend applications. Backend developer specialized in Spring Boot, with experience in database design, analysis, development and testing of assigned tasks.
💼
02/2021 - 10/2021
Software programmer
Adesso.it (prima era WebScience srl)
Experience in AS-IS and TO-BE analysis, SEO evolutions and website evolutions to improve user performance and engagement.
🎓
2018 - 2025
Degree in Computer Science
University of Bari Aldo Moro
Bachelor's degree in Computer Science, focusing on software engineering, algorithms, and modern development practices.
📚
2013 - 2018
Diploma - Corporate Information Systems
Technical Commercial Institute of Maglie
Technical diploma specializing in Business Information Systems, combining IT knowledge with business management.
Contattami
Hai un progetto in mente? Parliamone! Compila il form qui sotto e ti risponderò al più presto.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
Testing and Code Quality with Copilot
Tests are the foundation of a maintainable project. They're not just a safety net
against bugs, but also executable documentation that describes how the code
should behave. GitHub Copilot can drastically accelerate test writing,
from TDD to guided refactoring, from assisted debugging to edge case coverage.
In this article, we'll explore how to leverage Copilot for every level of the
testing pyramid, with specific prompts, practical examples, and best practices
for obtaining robust and maintainable tests.
Series Overview
#
Article
Focus
1
Foundation and Mindset
Setup and mindset
2
Ideation and Requirements
From idea to MVP
3
Backend Architecture
API and database
4
Frontend Structure
UI and components
5
Prompt Engineering
Prompts and MCP Agents
6
You are here - Testing and Quality
Unit, integration, E2E
7
Documentation
README, API docs, ADR
8
Deploy and DevOps
Docker, CI/CD
9
Evolution
Scalability and maintenance
The Testing Pyramid
The testing pyramid defines the optimal strategy to balance speed,
coverage, and maintainability. Copilot can help you at all levels.
Testing Pyramid
/\
/ \
/ E2E\ - Few (5-10%)
/------\ Slow, expensive, fragile
/ \ Test complete user flows
/Integration\ - Moderate (15-25%)
/------------\ Medium speed
/ \ Test interactions between components
/ Unit Tests \ - Many (70-80%)
/------------------\ Fast, isolated, stable
/ \ Test individual units
/______________________\
Characteristics by Level
Level
Speed
Isolation
Cost
Confidence
Unit
~1ms
High
Low
Internal logic
Integration
~100ms
Medium
Medium
Interactions
E2E
~5s
Low
High
Complete system
Unit Tests: The Base of the Pyramid
Unit tests verify individual functions or classes in complete isolation.
They're fast, reliable, and provide immediate feedback during development.
Prompts for Generating Unit Tests
Prompt - Generate Comprehensive Unit Tests
Generate comprehensive unit tests for this service:
```typescript
[PASTE SERVICE CODE HERE]
```
TESTING REQUIREMENTS:
- Framework: Jest with TypeScript
- Coverage target: >90% for this critical service
- Mock ALL external dependencies (repositories, external services)
TEST CATEGORIES TO COVER:
1. Happy Path: Normal successful operations
2. Validation: Invalid inputs, edge cases
3. Error Handling: Expected errors are thrown correctly
4. Edge Cases: Empty arrays, null values, boundary conditions
5. State Changes: Verify side effects (calls to dependencies)
OUTPUT FORMAT:
- Complete test file with all imports
- Use describe/it blocks with clear descriptions
- Include beforeEach for setup
- Group tests by method
- Use AAA pattern (Arrange, Act, Assert)
- Add comments explaining non-obvious test cases
NAMING CONVENTION:
- Describe: "ServiceName"
- Nested describe: "methodName"
- It: "should [expected behavior] when [condition]"
Integration tests verify that components work correctly together.
They test the complete API, including routing, middleware, validation, and database access.
Prompt for Integration Tests
Prompt - Generate Integration Tests
Generate integration tests for this API:
ENDPOINTS:
- POST /api/users - Create user (requires auth)
- GET /api/users/:id - Get user by ID
- PATCH /api/users/:id - Update user (owner only)
- DELETE /api/users/:id - Soft delete (admin only)
TESTING REQUIREMENTS:
- Framework: Jest + Supertest
- Database: Test PostgreSQL (use transactions, rollback after each test)
- Auth: JWT tokens (mock or real test tokens)
TEST SCENARIOS FOR EACH ENDPOINT:
1. Success case with valid request
2. Validation errors (400) - invalid body, missing fields
3. Authentication errors (401) - missing/invalid token
4. Authorization errors (403) - wrong role/permissions
5. Not found errors (404) - resource doesn't exist
6. Conflict errors (409) - duplicate resources
SETUP/TEARDOWN:
- beforeAll: Create test database, run migrations
- beforeEach: Start transaction
- afterEach: Rollback transaction
- afterAll: Close database connection
Include helper functions for:
- Creating authenticated requests
- Generating test users
- Cleaning up test data
Complete Example: Users API Integration Tests
TypeScript - users.integration.spec.ts
import request from 'supertest';
import {{ '{' }} app {{ '}' }} from '../app';
import {{ '{' }} db {{ '}' }} from '../database';
import {{ '{' }} createTestUser, getAuthToken, cleanupTestData {{ '}' }} from './helpers';
import {{ '{' }} UserRole {{ '}' }} from '@shared/types';
describe('Users API Integration Tests', () => {{ '{' }}
let adminToken: string;
let userToken: string;
let testUserId: string;
beforeAll(async () => {{ '{' }}
await db.connect();
await db.migrate();
// Create test users and get tokens
const admin = await createTestUser({{ '{' }} role: UserRole.ADMIN {{ '}' }});
const user = await createTestUser({{ '{' }} role: UserRole.USER {{ '}' }});
adminToken = await getAuthToken(admin);
userToken = await getAuthToken(user);
testUserId = user.id;
{{ '}' }});
afterAll(async () => {{ '{' }}
await cleanupTestData();
await db.disconnect();
{{ '}' }});
// ===============================================================
// POST /api/users - Create User
// ===============================================================
describe('POST /api/users', () => {{ '{' }}
const validPayload = {{ '{' }}
name: 'Integration Test User',
email: 'integration@test.com',
password: 'SecurePass123!',
{{ '}' }};
describe('success cases', () => {{ '{' }}
it('should create user with valid data (201)', async () => {{ '{' }}
const response = await request(app)
.post('/api/users')
.set('Authorization', `Bearer
End-to-end tests simulate real user behavior, testing
the entire application from browser to database.
Prompt for E2E Tests
Prompt - Generate E2E Tests (Playwright)
Generate E2E tests for user registration and login flow:
FLOW TO TEST:
1. User visits homepage
2. Clicks "Sign Up" button
3. Fills registration form (name, email, password)
4. Submits form
5. Sees success message
6. Is redirected to dashboard
7. Can log out and log back in
FRAMEWORK: Playwright with TypeScript
TEST SCENARIOS:
1. Happy path: Complete registration and login
2. Validation: Form shows errors for invalid input
3. Duplicate email: Shows appropriate error
4. Login with wrong password: Shows error
5. Remember me: Session persists after browser close
INCLUDE:
- Page Object Model for reusable selectors
- Helper functions for common actions
- Screenshot on failure
- Retry logic for flaky network requests
Existing tests allow you to refactor safely.
Copilot can suggest improvements while maintaining behavior.
Prompt - Refactoring with Safety Net
I want to refactor this code. I have tests that cover its behavior:
CURRENT CODE:
```typescript
[PASTE CODE]
```
EXISTING TESTS (passing):
```typescript
[PASTE TESTS]
```
REFACTORING GOALS:
1. Reduce cyclomatic complexity
2. Extract reusable functions
3. Improve naming
CONSTRAINTS:
- All existing tests MUST still pass
- Don't change public interface
- No new dependencies
Provide:
1. Refactored code
2. Explanation of each change
3. Any new tests needed for extracted functions
Assisted Debugging with Tests
Prompt - Debug Failing Test
This test is failing and I can't figure out why:
TEST:
```typescript
it('should apply discount to order total', async () => {{ '{' }}
const order = await orderService.createOrder({{ '{' }}
items: [{{ '{' }} productId: 'prod-1', quantity: 2 {{ '}' }}],
couponCode: 'SAVE10',
{{ '}' }});
expect(order.total).toBe(90); // Expected $90 after 10% discount
expect(order.discount).toBe(10);
{{ '}' }});
```
ERROR:
```
Expected: 90
Received: 100
```
IMPLEMENTATION:
```typescript
async createOrder(dto: CreateOrderDto): Promise<Order> {{ '{' }}
const items = await this.getOrderItems(dto.items);
const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
let discount = 0;
if (dto.couponCode) {{ '{' }}
const coupon = await this.couponRepository.findByCode(dto.couponCode);
if (coupon) {{ '{' }}
discount = subtotal * (coupon.percentage / 100);
{{ '}' }}
{{ '}' }}
return this.orderRepository.create({{ '{' }}
items,
subtotal,
discount,
total: subtotal - discount,
{{ '}' }});
{{ '}' }}
```
Help me:
1. Identify why the test is failing
2. Determine if it's a test bug or implementation bug
3. Provide the fix
Testing Best Practices
Anti-Patterns
Tests that depend on order
Shared state between tests
Vague names: "should work"
Multiple unrelated assertions
Too granular tests
Excessive mocking (testing mocks)
Slow tests without reason
Ignoring flaky tests
Best Practices
Independent and isolated tests
Fresh setup for each test
Descriptive names: "should return 404 when user not found"
One logical assertion per test
Test behavior, not implementation
Only mock external dependencies
Optimize shared setup
Fix or remove flaky tests
Test Quality Checklist
Before Merging
All tests pass locally
Coverage >= 80% for critical code
No flaky tests (run 3 times)
Test names are descriptive
Edge cases are covered
Error paths are tested
No console.log in tests
Fixtures are clean and reusable
Mocks are realistic
Tests are fast (unit < 10s total)
Conclusion and Next Steps
Testing is where Copilot truly shines. It can generate complete tests from
existing code, suggest edge cases you might not have considered,
and help you maintain high coverage without sacrificing development speed.
Remember: tests generated by Copilot must always be verified.
AI can generate tests that pass but don't actually test the important behavior,
or that are too tied to implementation rather than behavior.
In the next article we'll see how to use Copilot for
professional documentation: complete READMEs, API documentation
with OpenAPI, Architecture Decision Records, and JSDoc.