Unit 4: Various Testing Frameworks Available in Java
I. Orientation — The Java Automated-Testing Ecosystem
Automated testing uses executable code to verify that software behaves as expected. In Java, test frameworks such as JUnit and TestNG define tests, Maven manages dependencies and execution, Jenkins automates the pipeline, and Gherkin expresses behavior in business-readable scenarios.
Defining characteristics:
- Repeatability: The same test should produce the same result when executed under identical conditions.
- Isolation: A unit test normally checks one class or method without depending on databases, networks, or other external systems.
- Automation: Tools discover tests, execute them, compare actual and expected results, and publish reports.
- Fast feedback: Developers run focused tests locally, while continuous integration servers run broader suites after code changes.
- Traceability: Test names, reports, and failure messages connect requirements with verified behavior.
- Test pyramid:
- Unit tests: Numerous, fast tests of individual units.
- Integration tests: Fewer tests of interactions between components.
- End-to-end tests: A small number of broader, slower workflow tests.
II. Tool Evaluation — Choosing an Appropriate Testing Stack
A. Testing Tools Selection Criteria
Testing tools should be selected according to project requirements, technical compatibility, maintainability, and total operating cost.
- Testing level: Match the tool to unit, integration, API, UI, performance, security, or acceptance testing; JUnit 5 primarily supports Java unit and integration tests.
- Technology compatibility: Verify support for the Java version, build system, operating system, application framework, and IDE used by the team.
- Automation support: Confirm that tests can run non-interactively through commands such as
mvn testand return meaningful process exit codes. - CI integration: Prefer tools that Jenkins or another CI server can execute and whose XML or HTML reports it can publish.
- Learning curve: Consider team knowledge, documentation quality, debugging facilities, and readability of test code.
- Maintainability: Assess test discovery, reusable fixtures, parameterized tests, tagging, parallel execution, and extension mechanisms.
- Reliability: A suitable tool should minimize nondeterministic or “flaky” results and clearly identify failed assertions.
- Cost and support: Include licensing, infrastructure, training, maintenance, community activity, and vendor support rather than considering purchase price alone.
III. Jenkins — Continuous Integration and Test Automation
A. Fundamentals of Jenkins
Jenkins is an open-source automation server used to build, test, and deliver software whenever a defined event occurs.
- Continuous integration: A repository push can trigger compilation and automated tests, allowing defects to be detected soon after introduction.
- Job: A configured unit of work, such as checking out a Git repository and running
mvn test. - Pipeline: A version-controlled workflow stored conventionally in a
Jenkinsfile. - Agent: A machine or container that provides the workspace and executes pipeline stages.
- Plugins: Extensions integrate Jenkins with Git, Maven, credentials stores, test reports, and notification systems.
- Test reporting: Jenkins can read Maven-generated JUnit XML files and display test counts, failures, and historical trends.
- Declarative pipeline example:
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'mvn clean test'
}
}
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}- Pipeline result: A failed Maven test normally produces a nonzero exit status, causing the Jenkins stage and build to fail.
IV. TestNG — Configurable Java Testing
A. TestNG
TestNG is a Java testing framework inspired by JUnit that emphasizes flexible configuration, grouping, parameterization, dependencies, and parallel execution.
- Test declaration: Methods annotated with
@Testare discovered and executed by TestNG. - Lifecycle annotations:
@BeforeMethodand@AfterMethodsurround each test, while@BeforeClassand@AfterClassoperate at class level. - Groups:
@Test(groups = "smoke")categorizes tests so selected groups can be included or excluded. - Data-driven testing:
@DataProvidersupplies multiple argument sets to one test method. - Dependencies:
dependsOnMethodscontrols execution relationships, although excessive dependencies can reduce test isolation. - Parallelism: TestNG can run methods, classes, or suites concurrently through its XML configuration.
- Assertions:
Assert.assertEquals(actual, expected)records a failure when the values differ. - Suite configuration: A
testng.xmlfile can identify packages, classes, groups, parameters, and thread counts.
V. Maven — Build and Dependency Management
A. Maven
Maven is a Java build tool that uses a Project Object Model, stored in pom.xml, to define dependencies, plugins, and lifecycle operations.
- Standard layout: Production code belongs in
src/main/java, while test code belongs insrc/test/java. - Dependency management: Maven downloads declared test libraries and their required transitive dependencies from repositories.
- Scope:
<scope>test</scope>makes JUnit available during test compilation and execution without packaging it with the application. - Lifecycle:
mvn testperforms earlier phases such as compilation and then runs tests. - Surefire plugin: Maven Surefire normally executes unit tests and writes reports under
target/surefire-reports. - Failsafe plugin: Maven Failsafe is commonly used for integration tests during the
integration-testandverifyphases. - JUnit 5 dependency:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>- Reproducibility: Versioned dependencies and plugins allow local machines and Jenkins agents to use the same test components.
VI. JUnit — Java Unit-Testing Framework
A. Introduction to JUnit Framework
JUnit is a framework for defining, executing, and reporting automated tests for Java code, with each test expressing expected observable behavior.
- Test case: A method containing setup, an action, and assertions about the result.
- Fixture: The objects and input data required to place the system under test in a known state.
- Assertion: A comparison that fails the test when an expectation is not satisfied.
- Test runner: The framework component that discovers test classes, invokes lifecycle methods, and records outcomes.
- Independence: Tests should not rely on execution order or state left by another test.
- Result states: A test may pass, fail through an assertion, abort because an assumption is unmet, or fail with an unexpected exception.
B. JUnit 5
JUnit 5 is a modular generation of JUnit composed of the Platform, Jupiter, and Vintage components.
- JUnit Platform: Provides the launcher and test-engine interface used by IDEs, Maven, and build servers.
- JUnit Jupiter: Supplies the JUnit 5 programming model, including
@Test, lifecycle annotations, and assertions. - JUnit Vintage: Runs JUnit 3 and JUnit 4 tests when the Vintage engine is installed.
- Parameterized tests:
@ParameterizedTestexecutes one test with values from sources such as@ValueSource. - Display names:
@DisplayName("rejects a negative balance")provides readable report text. - Organization:
@Nested,@Tag, and package selection support structured and filtered test execution. - Extensions:
@ExtendWithregisters reusable behavior such as dependency injection or temporary resource management.
C. Define a Test in JUnit
A JUnit test is a discoverable method annotated with @Test that invokes production code and verifies its behavior with assertions.
- Structure: Arrange inputs and fixtures, Act by calling the target method, and Assert the expected outcome.
- Method form: In JUnit Jupiter, a test method is usually package-private, returns
void, and need not bepublic. - Assertions: Common methods include
assertEquals,assertTrue,assertNull,assertThrows, andassertAll. - Exception verification:
@Test
void divideByZeroThrowsException() {
assertThrows(ArithmeticException.class, () -> calculator.divide(8, 0));
}- Failure meaning: The test passes only if
calculator.divide(8, 0)throwsArithmeticException.
D. JUnit Naming Conventions
JUnit naming conventions make test intent visible even though most names are recommendations rather than framework requirements.
- Class names: Use forms such as
CalculatorTestfor unit tests andPaymentServiceIntegrationTestfor integration tests. - Method names: Describe behavior, for example
divideByZeroThrowsExceptionorwithdrawRejectsInsufficientFunds. - Behavior pattern: Names may follow
method_condition_expectedResult, such asdivide_zeroDivisor_throwsException. - Readability: Prefer domain behavior over vague names such as
test1orcheckMethod. - Discovery distinction: Modern JUnit discovery relies on annotations; naming patterns may still matter to Maven plugin configuration.
- Consistency: A project should adopt one naming style so failures remain easy to scan in IDE and CI reports.
E. JUnit Test Suites
A JUnit test suite groups selected tests so they can be launched together as one logical testing unit.
- Suite API: JUnit Platform Suite annotations require the
junit-platform-suitedependency. - Package selection:
@SelectPackages("com.example.payment")includes tests found in a package. - Class selection:
@SelectClasses({CalculatorTest.class, TaxTest.class})names explicit test classes. - Tag filtering:
@IncludeTags("smoke")runs only tests carrying the matching@Tag. - Suite example:
@Suite
@SelectPackages("com.example")
@IncludeTags("smoke")
class SmokeTestSuite {
}- Use: Suites support release checks and subsystem runs, but ordinary build-wide discovery often requires no explicit suite class.
F. Example JUnit Test
A focused JUnit test demonstrates fixture creation, method execution, and verification of one behavior.
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void addTwoPositiveNumbersReturnsSum() {
int actual = calculator.add(2, 3);
assertEquals(5, actual, "2 + 3 should equal 5");
}
}- Arrange:
setUp()creates a freshCalculatorbefore each test. - Act:
calculator.add(2, 3)produces the actual value. - Assert:
assertEquals(5, actual, ...)compares expected value5with the observed result. - Isolation: Recreating the fixture prevents mutable state from leaking between test methods.
G. JUnit Code Constructs
JUnit code constructs provide annotations and assertions for lifecycle control, grouping, conditional execution, and validation.
- Lifecycle:
@BeforeEachand@AfterEachexecute around every test.@BeforeAlland@AfterAllexecute once per test class and are normallystatic.
- Core annotations:
@Testdeclares a test,@Disabledskips it, and@RepeatedTest(3)repeats it three times. - Assertions:
assertEquals(expected, actual),assertSame,assertFalse, andassertIterableEqualscheck specific conditions. - Grouped assertions:
assertAllevaluates several assertions and reports all failures together. - Timeouts:
assertTimeoutverifies that an operation completes within a specifiedDuration. - Assumptions:
assumeTrue(condition)aborts a test when an environmental prerequisite is absent. - Dynamic tests:
@TestFactoryproduces test cases at runtime asDynamicTestobjects.
VII. Gherkin — Executable Behavior Specifications
A. Gherkin
Gherkin is a structured language used by behavior-driven development tools such as Cucumber to describe features through examples understandable to technical and nontechnical participants.
- Feature: Names a capability, such as
Feature: Account withdrawal. - Scenario: Describes one concrete behavior or business rule.
- Given: Establishes initial context, such as an account balance.
- When: Identifies the event or action being performed.
- Then: States the expected observable outcome.
- And/But: Extends a preceding step without changing its semantic category.
- Scenario Outline: Runs a scenario repeatedly with rows from an
Examplestable. - Concrete specification:
Feature: Calculator addition
Scenario: Add two positive numbers
Given the calculator is available
When I add 2 and 3
Then the result should be 5- Step definitions: Java methods connect these sentences to automation code; Gherkin alone describes behavior but does not execute application logic.
VIII. JUnit Development Environment — IDE Support and Setup
A. Eclipse Support for JUnit
Eclipse integrates JUnit execution, debugging, navigation, and result reporting into the Java development environment.
- Running tests: A class, method, package, or project can be launched through Run As → JUnit Test.
- JUnit view: Eclipse displays executed tests, elapsed time, failures, errors, and stack traces.
- Status indicators: Green represents a successful run, while red indicates at least one failure or error.
- Failure navigation: Selecting a stack-trace entry opens the corresponding source line.
- Debugging: Debug As → JUnit Test runs tests with breakpoints, variable inspection, and step controls.
- Rerunning: The JUnit view can repeat the entire run or only failed tests.
- Build integration: Maven projects imported into Eclipse obtain JUnit libraries from
pom.xml, keeping IDE and command-line configurations aligned.
B. Installation of JUnit
JUnit should normally be installed as a versioned build dependency rather than as a manually copied JAR file.
- Maven installation: Add the
org.junit.jupiter:junit-jupitertest dependency topom.xml, then refresh the Maven project. - Gradle installation: Declare
testImplementation("org.junit.jupiter:junit-jupiter:<version>")and enable the JUnit Platform:
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
}
test {
useJUnitPlatform()
}- Eclipse option: For a non-build-tool project, Build Path → Add Libraries → JUnit can add the IDE-provided library.
- Verification: Create a class under the test source folder with an
@Testmethod and run it through Eclipse ormvn test. - Version control: Commit
pom.xmlorbuild.gradle, but do not commit Maven’stargetdirectory or downloaded dependency files.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →