My Background
I am K. Ramesh, a Full Stack Developer from India specialising in the MERN stack and Java Spring Boot. I recently completed my Executive PG Certification in Full Stack Web Development from IIT Roorkee and I am currently building my portfolio to crack my first developer job.
As part of the Specmatic Full Stack AI Engineering Internship assessment, I was asked to:
Integrate Specmatic into a real project
Write about what I built and what I learnt
This blog post is my honest account of that journey — the struggles, the breakthroughs, and the real learnings.
What is Specmatic? Why Should You Care?
Before I started the Specademy course, I had never heard of contract testing. I knew about unit testing and integration testing, but contract testing was completely new to me.
After completing the course, one analogy stuck with me permanently:
Contract testing is compiler safety for API calls.
Let me explain this with a simple example.
In a traditional monolithic application, if Service A calls a function in Service B with the wrong parameters, the compiler immediately catches it and refuses to build. You cannot even run the app with a type mismatch.
But in microservices, Service A and Service B talk over HTTP. They are separate applications, often written in different programming languages. When Service A sends a request to Service B with the wrong schema — maybe a field name changed, maybe a data type changed — no compiler catches it. It only fails at runtime, often in production, causing real damage.
This is what Specmatic solves. It reads your OpenAPI specification and uses it as an executable contract. It fires test requests at your API and checks:
- Does the response match the documented schema?
- Are the HTTP status codes correct?
- Are the response headers correct?
- Are all documented endpoints actually implemented?
If anything breaks the contract, the test fails — just like a compiler error.
About My Project: ValueMeters
ValueMeters is an online banking system I built from scratch. It is a full-stack application with:
- Backend: Java Spring Boot with JWT authentication, MySQL database, Spring Data JPA
- Frontend: React 18 with Vite and Tailwind CSS
- Deployment: Backend on Railway/Render, Frontend on Vercel
-
API Documentation: springdoc-openapi (auto-generates OpenAPI spec at
/v3/api-docs)
The application has 13 REST API endpoints across 5 controllers:
| Controller | Endpoints |
|---|---|
| AuthController | POST /auth/register, POST /auth/login |
| AccountController | GET /account/user/{userId}, GET /account/{accountNumber} |
| TransactionController | POST /transaction/deposit/{accountId}, POST /transaction/withdraw/{accountId}, POST /transaction/transfer/{fromAccountId}, GET /transaction/history/{accountId} |
| ExpenseController | POST /expense/add/{accountId}, GET /expense/list/{accountId}, GET /expense/summary/{accountId} |
| BudgetController | POST /budget/set/{accountId}, GET /budget/get/{accountId} |
Since I already had springdoc-openapi integrated, my OpenAPI spec was available at:
http://localhost:8080/v3/api-docs
This made ValueMeters a perfect candidate for Specmatic integration.
The Challenge: JWT Security Was Blocking Specmatic
The biggest challenge I faced was that ValueMeters uses JWT authentication. Every endpoint (except register and login) requires a valid JWT token in the Authorization header.
When Specmatic tries to hit these endpoints during contract testing, it sends requests without any token. Spring Security was returning 403 Forbidden before Specmatic could even read the OpenAPI spec.
I had to solve this without breaking the production security setup. I did not want to hardcode any test bypasses into the main codebase.
Solution: Spring Profiles
I used Spring's profile system to create a completely separate security configuration for testing.
Step 1: Added @Profile("!test") to the existing SecurityConfig.java so it only loads when the test profile is NOT active:
@Configuration
@EnableWebSecurity
@Profile("!test") // Does not load during tests
public class SecurityConfig {
// ... existing JWT security configuration
}
Step 2: Created a new TestSecurityConfig.java that only loads during tests and permits all requests:
@Configuration
@Profile("test") // Only loads during tests
public class TestSecurityConfig {
@Bean
public SecurityFilterChain testFilterChain(HttpSecurity http) throws Exception {
http
.securityMatcher("/**")
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.disable())
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
.httpBasic(basic -> basic.disable())
.formLogin(form -> form.disable());
return http.build();
}
}
Step 3: Created src/test/resources/application-test.properties:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
spring.profiles.active=test
springdoc.api-docs.enabled=true
This approach keeps production security completely untouched while giving Specmatic full access during testing.
Setting Up Specmatic
Step 1: Added Maven Dependency
<dependency>
<groupId>io.specmatic</groupId>
<artifactId>junit5-support</artifactId>
<version>2.0.18</version>
<scope>test</scope>
</dependency>
Step 2: Created specmatic.yaml in Project Root
sources:
- provider: "web"
test:
- "http://localhost:8080/v3/api-docs"
This tells Specmatic to fetch the OpenAPI specification from the live application during testing.
Step 3: Created the Contract Test Class
package com.banking;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import io.specmatic.test.SpecmaticJUnitSupport;
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
properties = {"server.port=8080"}
)
@ActiveProfiles("test")
public class BankingContractTest extends SpecmaticJUnitSupport {
static {
System.setProperty("host", "localhost");
System.setProperty("port", "8080");
System.setProperty("endpointsAPI", "http://localhost:8080/v3/api-docs");
}
@Override
public void contractTest() throws Throwable {
super.contractTest();
}
}
When this test runs:
- Spring Boot starts the full application on port 8080 with the test profile
-
TestSecurityConfigloads instead ofSecurityConfig— all endpoints are open - Specmatic fetches the OpenAPI spec from
/v3/api-docs - Specmatic automatically generates test scenarios for all 13 endpoints
- It fires requests and validates responses against the contract
- It generates an HTML coverage report
Results and What They Mean
API Coverage Report
|-----------------------------------------------------------------------------------------------------|
| SPECMATIC API COVERAGE SUMMARY |
|-----------------------------------------------------------------------------------------------------|
| coverage | path | method | response | result |
|----------|---------------------------------------|--------|----------|-----------------|
| 50% | /account/user/{userId} | GET | 200 | not implemented |
| | | | 400 | missing in spec |
| 50% | /account/{accountNumber} | GET | 200 | not implemented |
| | | | 400 | missing in spec |
| 50% | /auth/login | POST | 200 | not implemented |
| | | | 400 | missing in spec |
| 50% | /auth/register | POST | 200 | not implemented |
| | | | 400 | missing in spec |
| 100% | /expense/list/{accountId} | GET | 200 | not implemented |
| 100% | /transaction/history/{accountId} | GET | 200 | not implemented |
|-----------------------------------------------------------------------------------------------------|
| 56% API Coverage reported from 13 Paths |
|-----------------------------------------------------------------------------------------------------|
Tests run: 20, Successes: 0, Failures: 20
Understanding Why Tests Failed
At first I was confused — all 20 tests failed? Did I do something wrong?
Then I understood. These are not ordinary test failures. These are contract gaps — differences between what the API documentation promises and what the API actually delivers. Let me explain each finding:
Finding 1: Missing 400 Error Responses in OpenAPI Spec
Specmatic sent random test data (fake account IDs like 793, 283, 422) and received 400 Bad Request responses. But my OpenAPI spec only documented 200 OK responses for these endpoints.
Expected status 200, actual was status 400
Reason: Account not found!
This is a real documentation bug. My spec is incomplete — it does not tell consumers that these endpoints can fail with 400. Specmatic found it.
Finding 2: Content-Type Not Specified in Spec
Contract expected */* but response contained application/json
Some endpoints return application/json but the OpenAPI spec did not explicitly declare the response content type. Another spec gap.
Finding 3: Schema Mismatch in Budget Summary
Contract expected JSON object but response contained 0 (number)
The monthlySpent field in /expense/summary returns a plain number (0), but the OpenAPI spec described it as a JSON object. A genuine schema mismatch caught by Specmatic.
The key insight: These failures are findings, not errors. Specmatic is doing exactly what a compiler does — it found real gaps between the contract and the implementation.
Key Learnings From This Journey
1. Your OpenAPI Spec is Probably Incomplete
Before Specmatic, I thought my spec was fine because Swagger UI looked correct. After Specmatic, I realised my spec was missing:
- All 400/404 error response schemas
- Explicit Content-Type declarations
- Proper schema definitions for complex response objects
2. Contract Testing Needs Zero Domain Knowledge
As I learnt in the Specademy course, contract tests do not care about business logic. Specmatic does not know what a "bank account" is. It only checks HTTP semantics and JSON schema structure. This means:
- No test data setup required
- No understanding of business rules required
- Can be fully automated by AI agents
3. Profile-Based Security is the Professional Approach
Many developers (including me initially) think about disabling security globally for tests. The right approach is Spring profiles — keep production config untouched, create a separate test config. This is production-grade thinking.
4. The Integration Environment Problem is Real
Before this exercise, I had read about the "integration environment bottleneck" in the Specademy course. After running Specmatic against a real project, I understood it practically. My API had 13 endpoints. Only 56% were properly documented. If another team was building a frontend against my API spec, they would have incorrect assumptions about 44% of the endpoints.
5. Specmatic as Compiler Safety for AI Agents
The Specademy course mentioned that AI coding agents need reliable executable contracts to operate safely. After this exercise, I fully understand why. If an AI agent generates code that calls my /expense/summary endpoint, it might assume the response has a monthlySpent JSON object (as per spec). But the actual response has a plain number. The AI agent's code would crash. Specmatic prevents this by enforcing the contract.
What I Will Improve Next
- Add 400/404 error response schemas to all endpoints in the OpenAPI spec
- Add realistic example data to the spec so Specmatic generates meaningful test scenarios
- Integrate into GitHub Actions CI/CD — run contract tests on every pull request
- Explore Specmatic as a mock server for the React frontend during development
Repository
- GitHub Repository: github.com/KRameshr/valuemeters-specmatic
-
Specmatic Integration Branch:
mainbranch of the above repo - Specademy Certificate: Spec-First Engineering Course, completed 12 June 2026
Conclusion
When I started this assessment, I thought Specmatic would simply run some tests and show green ticks. Instead, it showed me 20 failures — and each failure was a real gap in my API documentation that I had never noticed before.
That is the power of contract-driven development. It does not just test your code — it holds your API accountable to its promises.
As the Specademy course taught: Contract testing is compiler safety for API calls. After integrating Specmatic into ValueMeters, I truly understand what that means.
Written by K. Ramesh — Full Stack Developer (MERN + Spring Boot), IIT Roorkee Executive PG Certification in Full Stack Web Development.
LinkedIn: linkedin.com/in/kurubaramesh*26.



Top comments (0)