Time to put everything together. These exercises use the free JSONPlaceholder API (https://jsonplaceholder.typicode.com). Open Postman. Create a new collection called "Chapter 3 Practice." Work through each exercise. Don't skip ahead — each one builds on what you learned.
Create a GET request to /posts/1. Add these tests in the Post-response script.
// Exercise 1: GET https://jsonplaceholder.typicode.com/posts/1
// Write ALL of these tests:
// 1. Status code is 200
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// 2. Response time under 1 second
pm.test("Response time under 1s", function () {
pm.expect(pm.response.responseTime).to.be.below(1000);
});
// 3. Content-Type is JSON
pm.test("Content-Type is JSON", function () {
pm.response.to.have.header("Content-Type", /json/);
});
// 4. Response has all 4 fields
const post = pm.response.json();
pm.test("Has all required fields", function () {
pm.expect(post).to.have.all.keys("userId", "id", "title", "body");
});
// 5. ID is 1 and is a number
pm.test("ID is 1", function () {
pm.expect(post.id).to.be.a("number").and.to.eql(1);
});
// 6. Title is a non-empty string
pm.test("Title is non-empty string", function () {
pm.expect(post.title).to.be.a("string").and.not.be.empty;
});Create a GET request to /posts. This returns 100 posts. Validate the whole array.
// Exercise 2: GET https://jsonplaceholder.typicode.com/posts
const posts = pm.response.json();
// 1. Response is an array of 100 items
pm.test("Returns 100 posts", function () {
pm.expect(posts).to.be.an("array").with.lengthOf(100);
});
// 2. First post has ID 1
pm.test("First post ID is 1", function () {
pm.expect(posts[0].id).to.eql(1);
});
// 3. Last post has ID 100
pm.test("Last post ID is 100", function () {
pm.expect(posts[99].id).to.eql(100);
});
// 4. Every post has the 4 required fields
pm.test("All posts have required fields", function () {
posts.forEach(function (post) {
pm.expect(post).to.have.all.keys("userId", "id", "title", "body");
});
});
// 5. All IDs are unique
pm.test("All IDs are unique", function () {
const ids = posts.map(p => p.id);
pm.expect(new Set(ids).size).to.eql(ids.length);
});// Exercise 3: GET https://jsonplaceholder.typicode.com/users/1
const user = pm.response.json();
// 1. User name is "Leanne Graham"
pm.test("Name is correct", function () {
pm.expect(user.name).to.eql("Leanne Graham");
});
// 2. Address is an object with city
pm.test("Address has city", function () {
pm.expect(user.address).to.be.an("object");
pm.expect(user.address.city).to.be.a("string");
});
// 3. Geo has lat and lng
pm.test("Geo coordinates exist", function () {
pm.expect(user.address.geo).to.have.property("lat");
pm.expect(user.address.geo).to.have.property("lng");
});
// 4. Company name is not empty
pm.test("Company name exists", function () {
pm.expect(user.company.name).to.be.a("string").and.not.be.empty;
});
// 5. Email format is valid
pm.test("Email is valid format", function () {
pm.expect(user.email).to.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
});Create two requests. First one creates a post, second one fetches it.
// Request 1: POST https://jsonplaceholder.typicode.com/posts
// Body: { "title": "Test Post", "body": "Test Body", "userId": 1 }
const created = pm.response.json();
pm.test("Post created with 201", function () {
pm.response.to.have.status(201);
});
pm.test("Title matches input", function () {
pm.expect(created.title).to.eql("Test Post");
});
pm.environment.set("newPostId", created.id);// Request 2: GET https://jsonplaceholder.typicode.com/posts/{{newPostId}}
pm.test("Retrieved created post", function () {
pm.response.to.have.status(200);
const post = pm.response.json();
pm.expect(post.id).to.eql(parseInt(pm.environment.get("newPostId")));
});// Exercise 5a: GET https://jsonplaceholder.typicode.com/posts/999
pm.test("Non-existent post returns 404", function () {
pm.response.to.have.status(404);
});
pm.test("Response body is empty object", function () {
const body = pm.response.json();
pm.expect(Object.keys(body)).to.have.lengthOf(0);
});
// Exercise 5b: GET https://jsonplaceholder.typicode.com/posts/abc
pm.test("Invalid ID returns 404", function () {
pm.response.to.have.status(404);
});Ensure all 6 requests are in your "Chapter 3 Practice" collection
Arrange them in order: GET /posts/1, GET /posts, GET /users/1, POST /posts, GET /posts/{{newPostId}}, GET /posts/999
Open Collection Runner — click the Run button on the collection
Set iterations to 1 and delay to 200ms
Click Run and verify all tests pass (green checkmarks)
If any fail — read the error message, fix the assertion, and re-run
Don't copy-paste the exercises blindly. Type them out. Muscle memory is real. After typing pm.expect(response).to.have.property("id") twenty times, you'll write it in your sleep.
Key Point: Practice is the only way to internalize test patterns. Type the code, don't copy it. Run it, break it, fix it. That's how you learn.