Registry / testing / webtest

webtest

JSON →
library3.0.7pypypi✓ verified 24d ago

WebTest is a Python library that wraps any WSGI application, making it easy to send test requests without starting an HTTP server. It provides convenient full-stack testing for WSGI-compatible frameworks. An extraction of `paste.fixture.TestApp`, rewritten to use `WebOb`, it is under active development as part of the Pylons cloud of packages and is currently at version 3.0.7.

pip install WebTest
INSTALL
IMPORT
SIG · WEBTEST
W
webtest
testingpythonv3.0.7
Install
1.9s avg
Import
403ms
Disk
19MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v3.0.7 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.416s · 20.7MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.9s · import 0.390s · 21MB
19MB installed
● package 19MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

TestApp
from webtest import TestApp
from webtest.app import TestApp
While `webtest.app.TestApp` works, the idiomatic and stable import is directly from the `webtest` package.

Initializes `TestApp` with a basic WSGI application and performs a GET request, asserting the response status and content.

from webtest import TestApp def simple_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return [b'Hello, world!'] app = TestApp(simple_app) resp = app.get('/') assert resp.status == '200 OK' assert 'Hello, world!' in resp.text print(f"Status: {resp.status}") print(f"Body: {resp.text}")
Debug
Known issues
breakingVersion 3.0.0 dropped support for Python 2.7 and Python 3.5. Applications must use Python 3.6+ (3.9+ officially supported).
fix
Upgrade Python environment to 3.6 or newer (preferably 3.9+). Review code for Python 2/3.5 specific syntax.
affects: 3.0.0 and later
breakingVersion 2.0 introduced several breaking changes, including the removal of `anchor` from `TestResponse.click` and `button` from `TestResponse.clickbutton`. The cookiejar API changed for Python 3.3. Selenium and CasperJS integrations were moved to separate, optional packages (`webtest-selenium`, `webtest-casperjs`).
fix
Update usage of `click` methods, adapt to the new cookiejar API if targeting Python 3.3+, and install `webtest-selenium` or `webtest-casperjs` if those integrations are still required.
affects: 2.0 and later
gotchaBy default, `TestApp.get()`, `post()`, and other request methods raise an `AppError` if the response status code is not 2xx or 3xx (success or redirect).
fix
If expecting an error status (e.g., 404, 500), pass `status=EXPECTED_STATUS_CODE` (e.g., `status=404`) or `expect_errors=True` to the request method (e.g., `app.get('/nonexistent', status=404)` or `app.post('/error', expect_errors=True)`).
affects: All versions
gotchaAccessing parsed response attributes like `resp.html`, `resp.xml`, `resp.lxml`, `resp.pyquery`, or `resp.json` requires the respective parsing library (BeautifulSoup4, lxml, PyQuery, or `json` module for `json`) to be installed. An `ImportError` or `AttributeError` may be raised if the library is missing or the content-type is incorrect.
fix
Ensure the necessary parsing library is installed (`pip install beautifulsoup4 lxml pyquery`) and that the response's `Content-Type` header matches the expected format (e.g., `text/html` for `.html`, `application/json` for `.json`).
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'webtest'
The 'webtest' library is not installed in the current Python environment.
fix
pip install webtest
AttributeError: 'TestApp' object has no attribute 'post_json'
The `webtest.TestApp` class does not have a `post_json` method. JSON data should be passed using the `json` keyword argument to the `post` method.
fix
response = app.post('/api/endpoint', json={'key': 'value'})
TypeError: post() got an unexpected keyword argument 'data'
The `webtest.TestApp.post` method expects standard form data to be passed via the `params` keyword argument, not `data`.
fix
response = app.post('/form_submit', params={'field1': 'value1', 'field2': 'value2'})
webtest.app.AppError: Bad response: 302 Found (not 2xx)
By default, `webtest` does not automatically follow HTTP redirects (like 302, 303, 307). After a successful POST, many web applications redirect the client to another URL, which `webtest` returns as a 3xx response.
fix
To follow the redirect, call the `.follow()` method on the response object, optionally allowing non-2xx statuses for the initial request:
response = app.post('/submit', params={'data': 'value'}, status='*')
final_response = response.follow()

# Or more concisely:
final_response = app.post('/submit', params={'data': 'value'}).follow()
Upgrade
Version history
3.0.7latest on PyPI · released Oct 6, 2025
Audit
Dependencies
webobrequiredCore dependency for request and response objects.
beautifulsoup4optionalUsed for parsing HTML forms in responses (e.g., `response.html`, form handling).
lxmloptionalUsed for parsing HTML/XML responses via `response.lxml`.
pyqueryoptionalUsed for parsing HTML responses via `response.pyquery`.
wsgiproxy2optionalUsed for proxying requests to actual HTTP servers when `TestApp` is instantiated with a URL.
Agent activity
17 hits · last 30 days
node
14
OpenAI (training)
1
Resources
webtest — pip install webtest · libregistry