Skip to main content

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 suite
  • it(name, fn) — define a test (sync or async)
  • describe.only(name, fn) / it.only(name, fn) — run only this suite/test
  • describe.skip(name, fn) / it.skip(name, fn) — skip

Hooks

  • before_all(fn) — run once before all tests in the suite
  • after_all(fn) — run once after all tests
  • beforeEach(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 raw ApiResponse (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 API
  • browser.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

  1. Create accounts (if needed):

  2. Install build tools:

    python -m pip install build twine
    

    (If pip or python isn’t recognized, use the full path to your Python executable, or on Windows try py -m pip install build twine.)

  3. Build the package:

    python -m build
    

    On Windows, if python isn’t recognized, use py -m build instead. This creates dist/cstesting-0.1.1.tar.gz and a wheel.

  4. Upload to PyPI:

    python -m twine upload dist/*
    

    On Windows, if python isn’t recognized, use py -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/*
    
  5. Bump version in pyproject.toml for each new release, then repeat steps 3–4.

License

MIT. Port of EasyTesting (Node.js) to Python.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cstesting-0.1.1.tar.gz (26.0 kB view details)

Uploaded Source

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

Hashes for cstesting-0.1.1.tar.gz
Algorithm Hash digest
SHA256 b2b8c8b24816cd7d62b981e8b1f8853a811db9d5f9f4e55dc2f51609f6af5c8d
MD5 a9e30ce4d249d24be58874f8e79dbb19
BLAKE2b-256 5d821a93a2296cb67629cd148f0cb5f9e652ef347dd55fdeaee53c2a7b5ecc38

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page