Complete Programming Guide for QA/SDET Engineers
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.
Before we begin, you should have:
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!"); } }
public class HelloWorld - Defines a public class (file must be HelloWorld.java)
public - Access modifier (visible everywhere)static - Can be called without creating an objectvoid - Method returns no valuemain - Method name (entry point)String[] args - Command-line argumentsSystem.out.println() - Prints text and adds new line| 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() { } |
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); } }
// 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..."); } }
Modify the code to print your name and "I am learning Java for Test Automation":
LoginTest, UserRegistrationLoginTest.javaTest1, Test2Java 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.
In Java, data types are divided into two categories:
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; |
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); } }
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]); } }
Following proper naming conventions makes your test code more readable and maintainable. Here are the Java standards:
expectedTitle instead of titleloginPageUrl instead of urlmaxWaitTime instead of timeisTestPassed instead of flagType casting is converting a variable from one data type to another. Java supports two types:
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); } }
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 } }
Create variables for: testName (String), totalTests (int), passRate (double), isAutomated (boolean). Print them all.
float price = 99.99; β Missing 'f' β float price = 99.99f; βlong id = 9876543210; β Missing 'L' β long id = 9876543210L; β
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.
Java provides several types of 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 } }
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 (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 |
= 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 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 |
Understanding how logical operators work with different input combinations:
| A | B | A && B |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
| A | B | A || B |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
| A | !A |
|---|---|
| true | false |
| false | true |
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); } }
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); } }
| 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 |
Create a program that performs all arithmetic operations on two numbers and shows the results: