Python testing framework — test runner, assertions, API testing, browser automation (EasyTesting/CSTesting port)
Project description
CSTesting (Python)
Python port of CSTesting — a simple testing framework with a test runner, assertions, API testing, and browser automation (Playwright).
Install
# Core only (describe, it, expect, request — no browser)
pip install -e .
# With browser support (Playwright)
pip install -e ".[browser]"
playwright install chromium
CLI reference
Full command-line options (tags, debug, browser, config): docs/CLI.md.
Quick start
1. Create a test file (e.g. math_test.py):
from cstesting import describe, it, expect
def _suite():
it("adds numbers", lambda: expect(1 + 1).to_be(2))
it("compares objects", lambda: expect({"a": 1}).to_equal({"a": 1}))
describe("Math", _suite)
2. Run tests:
python -m cstesting
python -m cstesting "**/*.test.py"
python -m cstesting tests/
python -m cstesting example/math_test.py
API
Test structure
describe(name, fn)— define a suiteit(name, fn)— define a test (sync or async)describe.only(name, fn)/it.only(name, fn)— run only this suite/testdescribe.skip(name, fn)/it.skip(name, fn)— skip
Hooks
before_all(fn)— run once before all tests in the suiteafter_all(fn)— run once after all testsbeforeEach(fn)/afterEach(fn)— run before/after each test
Assertions (expect(value))
| Matcher | Example |
|---|---|
to_be(expected) |
strict equality |
to_equal(expected) |
deep equality |
to_be_truthy() / to_be_falsy() |
boolean |
to_be_null() / to_be_defined() / to_be_undefined() |
null/defined |
to_throw(message?) |
expect(fn).to_throw() |
to_be_greater_than(n) / to_be_less_than(n) |
numbers |
to_contain(item) |
list or string |
to_have_length(n) |
length |
expect(x).not_.to_be(y) |
negate (use not_ in Python) |
API testing (Rest-Assured style)
from cstesting import describe, it, request
def _suite():
it("GET", lambda: (
request.get("https://api.example.com/users/1")
.expect_status(200)
.expect_json("name", "John")
))
it("verifyStatus", lambda: request.verify_status("GET", "https://api.example.com/health", 200))
describe("API", _suite)
request.get(url),request.post(url, body),request.put,request.patch,request.delete- Chain:
.expect_status(200),.expect_header('content-type', pattern),.expect_body({}),.expect_json('path', value) request.verify_status(method, url, expected_status, body=None)res.get_response()for rawApiResponse(status, headers, body, raw_body)
Browser automation (optional)
Requires: pip install playwright && playwright install chromium
import asyncio
from cstesting import describe, it, expect, before_all, after_all, create_browser
browser = None
def _suite():
def _before():
global browser
browser = asyncio.get_event_loop().run_until_complete(create_browser(headless=True))
def _after():
global browser
if browser:
asyncio.get_event_loop().run_until_complete(browser.close())
before_all(_before)
after_all(_after)
async def _test():
await browser.goto("https://example.com")
html = await browser.content()
expect(html).to_contain("Example Domain")
it("loads the page", _test)
describe("Browser", _suite)
create_browser(headless=True, browser='chromium')— async, returns browser APIbrowser.goto(url),browser.click(selector),browser.type(selector, text)browser.locator(selector)→.click(),.type(text),.first,.nth(n)browser.wait_for_selector(selector),browser.content(),browser.evaluate(expr)browser.check(selector),browser.uncheck(selector),browser.select(selector, option)
Config-driven tests
Run flows from a .conf file without writing code:
# Login (one test case)
headed=true
goto:https://example.com/login
username:#email=value:user@test.com
password:#password=value:secret
click=button[type="submit"]
python -m cstesting run login.conf
python -m cstesting login.conf --headed
Programmatic: from cstesting import run_config_file; result = run_config_file('login.conf')
Init (Page Object Model)
python -m cstesting init
Creates pages/ and tests/ with sample HomePage and test.
Report
After a run, an HTML report is written to report/report.html (searchable, expandable steps, errors).
Programmatic run
from cstesting import describe, it, expect, run
def _suite():
it("works", lambda: expect(1).to_be(1))
describe("My tests", _suite)
result = run()
print(result) # passed, failed, skipped, total, duration, errors
Publish to PyPI
-
Create accounts (if needed):
-
Install build tools:
python -m pip install build twine
(If
piporpythonisn’t recognized, use the full path to your Python executable, or on Windows trypy -m pip install build twine.) -
Build the package:
python -m build
On Windows, if
pythonisn’t recognized, usepy -m buildinstead. This createsdist/cstesting-0.1.1.tar.gzand a wheel. -
Upload to PyPI:
python -m twine upload dist/*
On Windows, if
pythonisn’t recognized, usepy -m twine upload dist/*. Use your PyPI username and password (or API token).To try Test PyPI first:
python -m twine upload --repository testpypi dist/*
-
Bump version in
pyproject.tomlfor each new release, then repeat steps 3–4.
License
MIT. Port of EasyTesting (Node.js) to Python.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file cstesting-0.1.1.tar.gz.
File metadata
- Download URL: cstesting-0.1.1.tar.gz
- Upload date:
- Size: 26.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2b8c8b24816cd7d62b981e8b1f8853a811db9d5f9f4e55dc2f51609f6af5c8d
|
|
| MD5 |
a9e30ce4d249d24be58874f8e79dbb19
|
|
| BLAKE2b-256 |
5d821a93a2296cb67629cd148f0cb5f9e652ef347dd55fdeaee53c2a7b5ecc38
|