This guide collects automation engineering best practices applied throughout Dexter. Use it as a reference when writing or reviewing test code.
Keep tests and source code clearly separated:
tests/
├── api/ ← API test modules
├── ui/ ← UI (Selenium) test modules
└── conftest.py ← Shared fixtures and configuration
test_<feature>.py.test_<behaviour>_<condition> (e.g., test_create_order_returns_201).Use pytest.mark.parametrize to test multiple inputs without duplicating code:
import pytest
@pytest.mark.parametrize("item,price,qty,expected_status", [
("Widget", 9.99, 2, 201),
("", 9.99, 2, 400), # missing item
("Widget", -1, 2, 400), # negative price
])
def test_create_order_validation(client, item, price, qty, expected_status):
response = client.post("/api/orders", json={"item": item, "price": price, "qty": qty})
assert response.status_code == expected_status
Never use time.sleep. Use WebDriverWait with expected conditions:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, timeout=10)
# Wait until an element is visible
element = wait.until(EC.visibility_of_element_located((By.ID, "order-list")))
# Wait until text appears
wait.until(EC.text_to_be_present_in_element((By.ID, "status"), "Success"))
Set a sensible default timeout (10 seconds) and document why a longer timeout is needed if you use one.
Use Python’s built-in logging module instead of print statements in application code:
import logging
logger = logging.getLogger(__name__)
def create_order(order_data):
logger.info("Creating order: %s", order_data)
# ...
In tests, print is acceptable for quick debugging but should be removed before merging.
except Exception.# Good
try:
result = process_order(data)
except ValueError as exc:
logger.error("Invalid order data: %s", exc)
return {"error": str(exc)}, 400
# Avoid
try:
result = process_order(data)
except:
return {"error": "Something went wrong"}, 500
| Item | Convention | Example |
|---|---|---|
| Test file | test_<feature>.py |
test_orders_api.py |
| Test function | test_<behaviour>_<condition> |
test_delete_order_returns_204 |
| Fixture | descriptive noun | client, browser, sample_order |
| Variable | snake_case |
order_id, response_body |
| Constant | UPPER_SNAKE_CASE |
BASE_URL, DEFAULT_TIMEOUT |
Before submitting a PR, verify each item:
time.sleep in Selenium testsblack . applied — no formatting warnings@pytest.mark.api or @pytest.mark.uipytest fixtures over setUp/tearDown classes.