Things of Test

In this blog, I will explore the role and responsibilities of an SDET (Software Development Engineer in Test), providing insights into different types of testing and popular test automation frameworks. While I will introduce various testing frameworks, the main focus will be on Robot Framework and pytest, highlighting their features, use cases, and advantages in modern test automation.

Daily work

Bug Reporting

  1. Bug reporting system eg.Jira (ASSIGN, VIEW, TRIAGE, REPORT, CLOSE)
  2. Ticket include key as title, description, software version, steps to reproduce, expected result, actual result, screenshot, logs, prioriy/severity, status.

Test Planning + Execution

  1. Sheet include scenarios, expected, latest result, automate(bool); include happy path, sad path, and edge case

Build/Leverage Tool

  1. Use bash script/python3 to build hands-on tool
  2. Contribute to test frameworks(build as module instead of script)
  3. Use third-party to monitor acitivity such as Grafana to visualize networking data
  4. Build scalable application for large volume of data processing and data visualization, considering efficient data structure and algorithm to search/query output’s combination

Test Type

Test Framework

Framework Language(s) Type Best for Ease of Use Parallel Execution Integration Support
pytest Python Unit, API, UI Unit tests, API tests Easy Yes (pytest-xdist) CI/CD, Selenium
Cypress JavaScript UI, E2E Web UI automation Easy Yes (built-in) CI/CD, API Testing
Robot Multi UI, API, E2E Keyword-driven testing Moderate Yes Selenium, Appium
Selenium Multi UI, E2E Web UI automation Moderate No (requires setup) CI/CD, Appium
JUnit Java Unit Java Unit Testing Easy Yes (JUnit 5) CI/CD, Spring
Mocha JavaScript Unit, API JS Unit and API Testing Easy Yes (Mocha-parallel) CI/CD, Browser
Playwright JavaScript UI, E2E Fast UI testing Moderate Yes (built-in) CI/CD, API Testing
TestCafe JavaScript UI, E2E Cross-browser UI Testing Easy Yes (built-in) CI/CD
JMeter Java Performance Load and Stress Testing Hard Yes CI/CD, API Testing
Locust Python Performance Load Testing (Python) Moderate Yes API, Web Apps

Robot Overview

Robot Framework uses human-readable keywords to write test cases (instead of code-heavy scripts). It acts as a Python wrapper with libraries, providing:
✔ Clear pass/fail reports
✔ Automatic screenshots on failure (if configured)
✔ Detailed logs for every test case

The high-level architecture:

test.robot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
*** Settings ***
Resource common.robot
Library Collections

*** Variables ***
${DEFAULT_MTU} 1500

*** Test Cases ***
Single Host Test
${stats}= Check Network 8.8.8.8
Should Be Equal As Numbers ${stats} 0.0

Multi Host Test
${stats}= Check Network "8.8.8.8 192.168.1.1"
Should Be True ${stats} < 50.0

In common.robot

1
2
3
4
5
6
7
8
*** Settings ***
Library Robot_framework.py WITH NAME lib

*** Keywords ***
Check Network
[Arguments] ${target}=8.8.8.8
${results}= Run Fping ${target}
[Return] ${results}

In Robot_framework.py

1
2
3
4
5
6
7
8
9
10
11
12
import subprocess
import re
import logger

class Robot_framework:
def run_network_test(self, target):
"""Run fping for 1 hour and return summary"""
pass

def _parse_summary(self, output):
"""Extract just the packet loss percentage"""
pass

Run test:

1
$ robot test.robot

Pytest Overview

Key Features of Pytest
✔ Assertions – Detailed failure reports with assert statements.
✔ Fixtures – Reusable setup/teardown functions (more below).
✔ Parametrization – Run the same test with different inputs.
✔ Plugins – Extensible with a large ecosystem (e.g., pytest-cov for coverage).

Pytest Fixture Usage

In pytest, fixtures are functions that are executed before and after each test. We can use fixtures to prepare data and make it available to our test cases.

In api.py

1
2
3
4
5
6
7
8
9
10
11
class Calculator:
def __init__(self):
self.history = []

def add(self, a, b):
result = a + b
self.history.append(f"{a} + {b} = {result}")
return result

def clear_history(self):
self.history = []

In conftest.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pytest
from api import Calculator

@pytest.fixture
def calc():
"""Provides a fresh calculator instance for each test"""
calculator = Calculator()
yield
calculator.clear_history() # Teardown

@pytest.fixture(params=[
(1, 1, 2),
(0, 5, 5),
(-3, 3, 0)
])
def addition_cases(request):
"""Parametrized fixture for addition test cases"""
return request.param

In test.py

1
2
3
4
5
6
7
def test_basic_addition(calc):
assert calc.add(2, 3) == 5
assert calc.history == ["2 + 3 = 5"]

def test_parametrized_addition(calc, addition_cases):
a, b, expected = addition_cases
assert calc.add(a, b) == expected

Run test:

1
$ pytest test.py

Where Run Test

  1. Choice: In local, run isolated Dockers, write entry file to start Docker, begin setup, testing and teardown setup.
  2. Choice: Integrate with CICD(e.g, Jenkins), write jenkinsfile and start docker inside of Jenkin runner. If tests pass, teardown setup and docker container; otherwise, stuck there to let QA to troubleshoot failure point.
Author: Yu
Link: https://yurihe.github.io/2025/04/01/4.test/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.