Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
129: Behavior-Driven Testing with Cucumber Basics
Imagine you're hiring a contractor to renovate your kitchen. You don't hand them a 50-page technical manual on the chemical composition of grout or the specific voltage of the wiring. Instead, you give them a set of requirements in plain English: "When I flip this switch, the island lights should turn on," or "Given that the dishwasher is running, the sink should still have water pressure." You're describing the behavior of the kitchen, not the implementation details. If the lights turn on, you don't care if they used copper or silver wiring; the requirement was met.
That's exactly what Cucumber does for your Java code. It acts as a bridge between the "business speak" (what the software should actually do) and the "dev speak" (the JUnit or TestNG code that verifies it). It allows us to write tests in a language called Gherkin, which is essentially a structured way of writing English that a computer can actually parse.
Writing the Story in Gherkin
In Cucumber, we start with a .feature file. This is where the "contract" lives. I always tell my juniors to treat this file as the single source of truth—if a product manager can't read this and agree with it, your test is useless.
Let's look at a real scenario: a shopping cart total calculation. Instead of a method named testCartTotalWithTax(), we write this:
Feature: Shopping Cart Calculations
Scenario: Calculate total price for a single item
Given the shopping cart is empty
When I add a "Mechanical Keyboard" priced at 120.00
Then the total price should be 120.00
Notice the keywords: Given (the starting state), When (the action), and Then (the expected outcome). It's simple, but the magic happens when we map these specific sentences to Java methods.
Translating English into Java
Now, Cucumber needs a "translator." This is where the Step Definition class comes in. This is just a regular Java class where each method is annotated with a regex or a cucumber expression that matches the text in your feature file.
Here is how I'd implement the translation for the keyboard example:
public class ShoppingCartSteps {
private ShoppingCart cart;
private double finalTotal;
@Given("the shopping cart is empty")
public void the_shopping_cart_is_empty() {
cart = new ShoppingCart();
}
@When("I add a {string} priced at {double}")
public void i_add_a_priced_at(String item, Double price) {
cart.addItem(new Item(item, price));
}
@Then("the total price should be {double}")
public void the_total_price_should_be(Double expectedTotal) {
finalTotal = cart.calculateTotal();
assertEquals(expectedTotal, finalTotal, 0.01);
}
}
You'll notice the {string} and {double} placeholders. These are Cucumber expressions. They let us reuse the same Java method for different data. If I add a scenario for a "Gaming Mouse" priced at 50.00, I don't need to write a new Java method; Cucumber just passes those values as arguments to the existing method.
The Glue That Holds It Together
For this to actually run, you need a "Runner" class. I've seen people struggle here because they forget that Cucumber needs to know where the feature files are and where the step definitions live. In modern Java setups, we typically use a JUnit runner.
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "com.myapp.steps"
)
public class RunCucumberTest {
// This class stays empty; it's just a trigger for the framework.
}
One thing to keep in mind: don't put your actual business logic inside the Step Definition methods. The step definitions should be thin. They should call methods in your actual service classes. If you start writing complex if/else blocks inside your @When methods, you've just moved the mess from your production code to your test code, which is a trap I've seen many developers fall into.
📋 Practical Task
Build a Behavior-Driven Validator for a Bookstore Discount System
You need to implement a BDD test suite for a bookstore's discount logic. The business rule is: "If a customer buys more than 3 books, they get a 10% discount on the total price."
Your requirements:
- Create a
.featurefile nameddiscount.featurewith a scenario that describes adding 4 books (each priced at $10.00) and verifying the total is $36.00 (after the 10% discount). - Implement the
BookstoreStepsJava class. You must use Cucumber expressions (like{int}or{double}) to capture the number of books and their prices. - Create a simple
BookstorePOJO that handles the internal logic of adding books and calculating the discounted total. - Write the JUnit Runner class to link the feature file and the step definitions.
Verification: When you run the test, the Cucumber report should show the "Then" step passing, confirming that the 10% discount was applied correctly to the bulk order.
There are no comments for now.