β˜• Java Fundamentals

Complete Programming Guide for QA/SDET Engineers

Part 1 of 4

🎯 Welcome to Java - Part 1

Java is a powerful, object-oriented programming language that's essential for QA/SDET professionals. This course is designed specifically for testers who want to excel in test automation.

Why Java for QA/SDET?

  • Selenium WebDriver: The most popular automation tool uses Java
  • TestNG & JUnit: Leading testing frameworks are Java-based
  • REST Assured: API testing made easy with Java
  • Appium: Mobile test automation with Java
  • Industry Standard: Most companies use Java for automation
  • Career Growth: High demand for Java automation engineers

Part 1 Coverage

Hello World
Variables
Data Types
Type Casting
Arithmetic Operators
Comparison Operators
Logical Operators
Assignment Operators
πŸ’‘ Learning Approach: Each concept includes:
  • Clear explanations with QA/SDET context
  • Code examples you can run and modify
  • Interactive exercises to practice
  • Solutions to verify your understanding

Java Development Setup

Before we begin, you should have:

  1. JDK (Java Development Kit) - Version 11 or higher
  2. IDE - IntelliJ IDEA, Eclipse, or VS Code
  3. Text Editor - For quick code experiments
πŸš€ Quick Start: Don't worry if you don't have Java installed yet! You can follow along with the interactive examples in this course and set up your environment later.

πŸš€ Your First Java Program

Hello World Explained

Let's break down the classic "Hello World" program line by line:

public class HelloWorld {
    // Main method - entry point of the program
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
πŸ” Code Breakdown:
  • public class HelloWorld - Defines a public class (file must be HelloWorld.java)
  • public - Access modifier (visible everywhere)
  • static - Can be called without creating an object
  • void - Method returns no value
  • main - Method name (entry point)
  • String[] args - Command-line arguments
  • System.out.println() - Prints text and adds new line

Java Program Structure

Component Description Example
Package Groups related classes package com.test.automation;
Import Uses classes from other packages import java.util.List;
Class Blueprint for objects public class LoginTest { }
Method Block of code that performs an action public void login() { }

Print Statements

public class PrintExamples {
    public static void main(String[] args) {
        // println - prints and moves to next line
        System.out.println("Test 1: Login");
        System.out.println("Test 2: Logout");
        
        // print - prints without new line
        System.out.print("Test 3: ");
        System.out.print("Dashboard");
        System.out.println();  // Empty line
        
        // Printing numbers
        System.out.println(100);
        System.out.println(3.14);
        
        // Printing boolean
        System.out.println(true);
    }
}

Comments in Java

// Single-line comment - use for brief explanations

/*
 * Multi-line comment
 * Use for longer explanations
 * or temporarily disabling code
 */

/**
 * JavaDoc comment - for documentation
 * @author Automation Team
 * @version 1.0
 * @since 2024-01-01
 */
public class TestRunner {
    // TODO: Add test execution logic
    public static void main(String[] args) {
        System.out.println("Running tests...");
    }
}

Interactive Exercise: Hello World

πŸ’» Customize Your First Program

Modify the code to print your name and "I am learning Java for Test Automation":

πŸ’‘ Best Practices:
  • Class names use PascalCase: LoginTest, UserRegistration
  • File name must match class name: LoginTest.java
  • One public class per file
  • Use meaningful names, not Test1, Test2

πŸ“¦ Data Types & Variables

Java is strongly typed, meaning every variable must be declared with a specific data type. This ensures type safety and helps catch errors at compile time rather than runtime - crucial for writing reliable test automation code.

Understanding Data Types

In Java, data types are divided into two categories:

  • Primitive Types: Store simple values directly in memory (int, boolean, char, etc.)
  • Reference Types: Store references (memory addresses) to objects (String, Arrays, Classes)
🎯 Why This Matters for QA:
  • Choosing the right data type prevents memory waste in large test suites
  • Understanding primitives vs objects helps debug null pointer exceptions
  • Type safety catches errors before tests run, saving debugging time

Primitive Data Types

Primitive types are the building blocks of data manipulation. They store actual values and are more memory-efficient than objects. Here's a complete reference:

Type Size Range Default Example
byte 8 bits -128 to 127 0 byte age = 25;
short 16 bits -32,768 to 32,767 0 short year = 2024;
int 32 bits -2Β³ΒΉ to 2Β³ΒΉ-1 0 int count = 100;
long 64 bits -2⁢³ to 2⁢³-1 0L long userId = 123456789L;
float 32 bits Β±3.4E38 0.0f float price = 99.99f;
double 64 bits Β±1.7E308 0.0d double pi = 3.14159;
char 16 bits 0 to 65,535 '\u0000' char grade = 'A';
boolean 1 bit true or false false boolean passed = true;

Variable Declaration

public class VariableExample {
    public static void main(String[] args) {
        // Declaration only
        int testCount;
        
        // Initialization
        testCount = 50;
        
        // Declaration + Initialization
        String browserName = "Chrome";
        double version = 120.5;
        boolean isHeadless = false;
        char environment = 'D';  // D = Dev, S = Stage, P = Prod
        
        // Multiple variables of same type
        int passed = 45, failed = 3, skipped = 2;
        
        // Print all variables
        System.out.println("Browser: " + browserName);
        System.out.println("Version: " + version);
        System.out.println("Total Tests: " + testCount);
        System.out.println("Passed: " + passed);
        System.out.println("Failed: " + failed);
    }
}

Reference Types (Objects)

public class ReferenceTypes {
    public static void main(String[] args) {
        // String - most commonly used reference type
        String username = "admin@test.com";
        String password = "Test@123";
        
        // Arrays
        String[] browsers = {"Chrome", "Firefox", "Edge"};
        int[] testScores = {85, 92, 78, 95};
        
        // Print
        System.out.println("Username: " + username);
        System.out.println("First browser: " + browsers[0]);
        System.out.println("First score: " + testScores[0]);
    }
}

Variable Naming Conventions

Following proper naming conventions makes your test code more readable and maintainable. Here are the Java standards:

  • camelCase: Variables and methods start with lowercase (testName, browserVersion)
  • UPPER_SNAKE_CASE: Constants use all caps with underscores (MAX_TIMEOUT, BASE_URL)
  • Meaningful Names: Use descriptive names that explain purpose (loginButton vs btn1)
  • Avoid Single Letters: Except for loop counters (i, j, k)
βœ… Good Variable Names for QA:
  • expectedTitle instead of title
  • loginPageUrl instead of url
  • maxWaitTime instead of time
  • isTestPassed instead of flag

Type Casting

Type casting is converting a variable from one data type to another. Java supports two types:

  • Widening (Implicit): Automatic conversion from smaller to larger type (int β†’ double)
  • Narrowing (Explicit): Manual conversion from larger to smaller type (double β†’ int) - may lose data

In test automation, you'll often need to convert strings from web elements to numbers for assertions, or parse configuration values.

public class TypeCasting {
    public static void main(String[] args) {
        // Widening (Automatic) - smaller to larger type
        int testCount = 100;
        double testCountDouble = testCount;  // int β†’ double
        System.out.println("Count as double: " + testCountDouble);  // 100.0
        
        // Narrowing (Manual) - larger to smaller type
        double percentage = 95.7;
        int rounded = (int) percentage;  // Explicit casting
        System.out.println("Rounded: " + rounded);  // 95
        
        // String to primitive conversions
        String strNumber = "123";
        int num = Integer.parseInt(strNumber);
        double decimal = Double.parseDouble("45.67");
        boolean bool = Boolean.parseBoolean("true");
        
        // Primitive to String
        int value = 456;
        String strValue = String.valueOf(value);
        String strValue2 = Integer.toString(value);
        
        System.out.println("Converted number: " + num);
        System.out.println("String value: " + strValue);
    }
}

Constants (final keyword)

public class Constants {
    public static void main(String[] args) {
        // Constants - cannot be changed once assigned
        final String BASE_URL = "https://example.com";
        final int MAX_RETRY_COUNT = 3;
        final int TIMEOUT_SECONDS = 30;
        
        System.out.println("Base URL: " + BASE_URL);
        System.out.println("Max Retries: " + MAX_RETRY_COUNT);
        
        // BASE_URL = "https://new-url.com";  // ❌ Error: cannot reassign
    }
}

Interactive Exercise: Variables

πŸ’» Practice with Variables

Create variables for: testName (String), totalTests (int), passRate (double), isAutomated (boolean). Print them all.

⚠️ Common Mistakes:
  • float price = 99.99; ❌ Missing 'f' β†’ float price = 99.99f; βœ“
  • long id = 9876543210; ❌ Missing 'L' β†’ long id = 9876543210L; βœ“
  • Using variables before initialization
  • Trying to change final variables

βš™οΈ Operators

Operators are special symbols that perform operations on variables and values. They are fundamental to writing test logic, performing calculations, and making decisions in your automation code.

Operator Categories

Java provides several types of operators:

  • Arithmetic: Mathematical operations (+, -, *, /, %)
  • Comparison (Relational): Compare values (==, !=, >, <,>=, <=)< /li>
  • Logical: Combine boolean conditions (&&, ||, !)
  • Assignment: Assign values (=, +=, -=, *=, /=)
  • Increment/Decrement: Increase or decrease by 1 (++, --)
🎯 Operators in Test Automation:
  • Arithmetic: Calculate test metrics (pass rate = passed / total * 100)
  • Comparison: Verify expected vs actual values (actualPrice == expectedPrice)
  • Logical: Combine multiple test conditions (isLoggedIn && hasPermission)
  • Assignment: Update test counters and variables

Arithmetic Operators

Used for mathematical calculations. The modulus operator (%) is particularly useful for checking even/odd numbers or cycling through arrays.

public class ArithmeticOps {
    public static void main(String[] args) {
        int a = 20, b = 3;
        
        System.out.println("Addition: " + (a + b));        // 23
        System.out.println("Subtraction: " + (a - b));     // 17
        System.out.println("Multiplication: " + (a * b));  // 60
        System.out.println("Division: " + (a / b));        // 6 (integer division)
        System.out.println("Modulus: " + (a % b));         // 2 (remainder)
        
        // For decimal division
        double result = (double) a / b;
        System.out.println("Decimal division: " + result);  // 6.666...
        
        // Increment and Decrement
        int count = 5;
        System.out.println("count++: " + (count++));  // 5, then count becomes 6
        System.out.println("++count: " + (++count));  // 7, count increments first
        System.out.println("count--: " + (count--));  // 7, then count becomes 6
        System.out.println("--count: " + (--count));  // 5, count decrements first
    }
}

Assignment Operators

public class AssignmentOps {
    public static void main(String[] args) {
        int x = 10;
        
        x += 5;   // x = x + 5;  β†’ 15
        System.out.println("x += 5: " + x);
        
        x -= 3;   // x = x - 3;  β†’ 12
        System.out.println("x -= 3: " + x);
        
        x *= 2;   // x = x * 2;  β†’ 24
        System.out.println("x *= 2: " + x);
        
        x /= 4;   // x = x / 4;  β†’ 6
        System.out.println("x /= 4: " + x);
        
        x %= 4;   // x = x % 4;  β†’ 2
        System.out.println("x %= 4: " + x);
    }
}

Comparison Operators

Comparison operators (also called relational operators) compare two values and return a boolean result (true or false). These are essential for test assertions and validations.

Operator Name Example Result QA Use Case
== Equal to 5 == 5 true Verify expected == actual
!= Not equal 5 != 3 true Check error message != null
> Greater than 5 > 3 true Verify response time > threshold
< Less than 3 < 5 true Check load time < max allowed
>= Greater or equal 5 >= 5 true Verify pass rate >= 90%
<= Less or equal 3 <= 5 true Check retry count <= max retries
⚠️ Common Mistake: Using = instead of == for comparison!
  • if (x = 5) ❌ Assignment (sets x to 5)
  • if (x == 5) βœ“ Comparison (checks if x equals 5)
public class ComparisonOps {
    public static void main(String[] args) {
        int testsPassed = 45;
        int totalTests = 50;
        
        System.out.println(testsPassed == totalTests);  // false (equal to)
        System.out.println(testsPassed != totalTests);  // true (not equal)
        System.out.println(testsPassed > 40);          // true (greater than)
        System.out.println(testsPassed < totalTests);   // true (less than)
        System.out.println(testsPassed >= 45);         // true (greater or equal)
        System.out.println(testsPassed <= 50);         // true (less or equal)
        
        // QA Example: Check if pass rate is acceptable
        double passRate = (double) testsPassed / totalTests * 100;
        boolean acceptable = passRate >= 90.0;
        System.out.println("Pass rate: " + passRate + "%");
        System.out.println("Acceptable: " + acceptable);
    }
}

Logical Operators

Logical operators combine multiple boolean expressions and return a boolean result. These are crucial for complex test conditions and validations.

Operator Name Description Example
&& AND Returns true if BOTH conditions are true isLoggedIn && hasPermission
|| OR Returns true if AT LEAST ONE condition is true isChrome || isFirefox
! NOT Reverses the boolean value !isDisabled

Truth Tables

Understanding how logical operators work with different input combinations:

AND (&&) Operator
A B A && B
true true true
true false false
false true false
false false false
OR (||) Operator
A B A || B
true true true
true false true
false true true
false false false
NOT (!) Operator
A !A
true false
false true
πŸ’‘ Short-Circuit Evaluation:
  • AND (&&): If first condition is false, second is NOT evaluated (already false)
  • OR (||): If first condition is true, second is NOT evaluated (already true)
  • Why it matters: Prevents null pointer exceptions in tests
    if (element != null && element.isDisplayed()) βœ“ Safe
    if (element.isDisplayed() && element != null) ❌ May crash if element is null
public class LogicalOps {
    public static void main(String[] args) {
        boolean isLoggedIn = true;
        boolean hasPermission = true;
        boolean isAdmin = false;
        
        // AND (&&) - both must be true
        boolean canAccess = isLoggedIn && hasPermission;
        System.out.println("Can access: " + canAccess);  // true
        
        // OR (||) - at least one must be true
        boolean canModify = isAdmin || hasPermission;
        System.out.println("Can modify: " + canModify);  // true
        
        // NOT (!) - inverts the boolean
        boolean notLoggedIn = !isLoggedIn;
        System.out.println("Not logged in: " + notLoggedIn);  // false
        
        // Complex conditions (QA example)
        int passed = 95, failed = 3, total = 100;
        boolean testSuitePassed = (failed == 0) || (passed >= 90 && total == 100);
        System.out.println("Test suite passed: " + testSuitePassed);
    }
}

Ternary Operator

public class TernaryOp {
    public static void main(String[] args) {
        // Syntax: condition ? valueIfTrue : valueIfFalse
        
        int score = 85;
        String result = (score >= 60) ? "Pass" : "Fail";
        System.out.println("Result: " + result);  // Pass
        
        // Nested ternary (be careful - can reduce readability)
        String grade = (score >= 90) ? "A" :
                      (score >= 80) ? "B" :
                      (score >= 70) ? "C" : "D";
        System.out.println("Grade: " + grade);  // B
        
        // QA Example: Set test status
        int expected = 10, actual = 10;
        String status = (expected == actual) ? "βœ“ PASS" : "βœ— FAIL";
        System.out.println(status);
    }
}

Operator Precedence

Priority Operator Description
1 (Highest) (), [] Parentheses, Array subscript
2 !, ++, -- Unary operators
3 *, /, % Multiplication, Division, Modulus
4 +, - Addition, Subtraction
5 <, <=,>, >= Relational operators
6 ==, != Equality operators
7 && Logical AND
8 || Logical OR
9 (Lowest) =, +=, -=, etc. Assignment operators

Interactive Exercise: Calculator

πŸ’» Build a Calculator

Create a program that performs all arithmetic operations on two numbers and shows the results:

πŸ’‘ QA Testing Tip: Operators are crucial for:
  • Calculating test pass/fail rates
  • Comparing expected vs actual values
  • Implementing retry logic with counters
  • Creating complex validation conditions