Name | pytest-smtpd JSON |
Version |
0.1.0
JSON |
| download |
home_page | |
Summary | An SMTP server for testing built on aiosmtpd |
upload_time | 2023-05-15 21:24:02 |
maintainer | |
docs_url | None |
author | |
requires_python | <4,>=3.7 |
license | |
keywords |
email
pytest
smtp
testing
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# pytest-smtpd
⚠ **Not intended for use with production systems.** ⚠
This fixture is intended to address cases where to test an application that sends an email, it needs to be intercepted for subsequent processing. For example, sending an email with a code for password reset or two-factor authentication. This fixture allows a test to trigger the email being sent, ensure that it's sent, and read the email.
## Installing
To install using pip, first upgrade pip to the latest version to avoid any issues installing `cryptography`:
```bash
python -m pip install --upgrade pip
pip install pytest-smtpd
```
Or, if you're using setuptools, it can be included in the `extras_require` argument of a `setup.py` file:
```python
setup(
...
extras_require={
"test": [
"pytest",
"pytest-smtpd",
],
},
)
```
and then installed with pip (-e assumes that you want your project to be editable):
```bash
python -m pip install --upgrade pip
pip install -e .[test]
```
## Using
The `SMTPDFix` plugin, `smtpd`, automatically registers for use with pytest when you install smtpdfix. To use it simply add to your test method.
```python
from smtplib import SMTP
def test_sendmail(smtpd):
from_addr = "from.addr@example.org"
to_addrs = "to.addr@example.org"
msg = (f"From: {from_addr}\r\n"
f"To: {to_addrs}\r\n"
f"Subject: Foo\r\n\r\n"
f"Foo bar")
with SMTP(smtpd.hostname, smtpd.port) as client:
client.sendmail(from_addr, to_addrs, msg)
assert len(smtpd.messages) == 1
```
To use STARTTLS:
```python
from smtplib import SMTP
def test_sendmail(smtpd):
smptd.config.use_starttls = True
from_ = "from.addr@example.org"
to_ = "to.addr@example.org"
msg = (f"From: {from_}\r\n"
f"To: {to_}\r\n"
f"Subject: Foo\r\n\r\n"
f"Foo bar")
with SMTP(smtpd.hostname, smtpd.port) as client:
client.starttls() # Note that you need to call starttls first.
client.sendmail(from_addr, to_addrs, msg)
assert len(smtpd.messages) == 1
```
To use TLS encryption on the connections:
```python
from smtplib import STMP_SSL # Note the different client class.
def test_custom_certificate(smtpd):
smtpd.config.use_ssl = True
from_ = "from.addr@example.org"
to_ = "to.addr@example.org"
msg = (f"From: {from_}\r\n"
f"To: {to_}\r\n"
f"Subject: Foo\r\n\r\n"
f"Foo bar")
with SMTP_SSL(smtpd.hostname, smtpd.port) as client:
client.sendmail(from_addr, to_addrs, msg)
assert len(smtpd.messages) == 1
```
The certificates included with the fixture will work for addresses localhost, localhost.localdomain, 127.0.0.1, 0.0.0.1, ::1. If using other addresses the key (key.pem) and certificate (cert.pem) must be in a location specified under `SMTP_SSL_CERTS_PATH`.
### Configuration
Configuration is handled through properties in the `config` of the fixture and are initially set from environment variables:
Property | Variable | Default | Description
-----------------|------------------------|----------------------|------------
`host` | `SMTPD_HOST` | `127.0.0.1` or `::1` | The hostname that the fixture will listen on.
`port` | `SMTPD_PORT` | `a random free port` | The port that the fixture will listen on.
`ready_timeout` | `SMTPD_READY_TIMEOUT` | `10.0` | The seconds the server will wait to start before raising a `TimeoutError`.
`login_username` | `SMTPD_LOGIN_NAME` | `user` | Username for default authentication.
`login_password` | `SMTPD_LOGIN_PASSWORD` | `password` | Password for default authentication.
`use_ssl` | `SMTPD_USE_SSL` | `False` | Whether the fixture should use fixed TLS/SSL for transactions. If using smtplib requires that `SMTP_SSL` be used instead of `SMTP`.
`use_starttls` | `SMTPD_USE_STARTTLS` | `False` | Whether the fixture should use StartTLS to encrypt the connections. If using `smtplib` requires that `SMTP.starttls()` is called before other commands are issued. Overrides `use_tls` as the preferred method for securing communications with the client.
`enforce_auth` | `SMTPD_ENFORCE_AUTH` | `False` | If set to true then the fixture refuses MAIL, RCPT, DATA commands until authentication is completed.
`ssl_cert_path` | `SMTPD_SSL_CERTS_PATH` | `./certs/` | The path to the key and certificate in PEM format for encryption with SSL/TLS or StartTLS.
`ssl_cert_files` | `SMTPD_SSL_CERT_FILE` and `SMTPD_SSL_KEY_FILE` | `("cert.pem", None)` | A tuple of the path for the certificate file and key file in PEM format.
## Alternatives
Many libraries for sending email have built-in methods for testing and using these methods should generally be prefered over pytest-smtpd. Some known solutions:
+ **fastapi-mail**: has a `record_messsages()` method to intercept the mail. Instructions on how to suppress the sending of mail and implement it can be seen at [https://sabuhish.github.io/fastapi-mail/example/#unittests-using-fastapimail](https://sabuhish.github.io/fastapi-mail/example/#unittests-using-fastapimail)
+ **flask-mail**: has a method to suppress sending and capture the email for testing purposes. [Instructions](https://pythonhosted.org/Flask-Mail/#unit-tests-and-suppressing-emails)
## Developing
To develop and test smtpdfix you will need to install [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) to run asynchronous tests, [isort](https://pycqa.github.io/isort/) to sort imports and [flake8](https://flake8.pycqa.org/en/latest/) to lint. To install in a virtual environment for development:
```bash
python -m venv venv
./venv/scripts/activate
pip install -e .[dev]
```
Code is tested using tox:
```bash
tox
```
Quick tests can be handled by running pytest directly:
```bash
pytest
```
We include a [pre-commit](https://pre-commit.com/) configuration file to automate checks and clean up imports before pushing code. In order to install pre-commit git hooks:
```bash
pip install pre-commit
pre-commit install
```
## Known Issues
+ Firewalls may interfere with the operation of the smtp server.
+ Authenticating with LOGIN and PLAIN mechanisms fails over TLS/SSL, but works with STARTTLS. [smtpdfix Issue #10](https://github.com/bebleo/smtpdfix/issues/10)
+ Currently no support for termination through signals. [smtpdfix Issue #4](https://github.com/bebleo/smtpdfix/issues/4)
Written with ☕ and ❤ in Montreal, QC
Raw data
{
"_id": null,
"home_page": "",
"name": "pytest-smtpd",
"maintainer": "",
"docs_url": null,
"requires_python": "<4,>=3.7",
"maintainer_email": "",
"keywords": "email,pytest,smtp,testing",
"author": "",
"author_email": "James Warne <bebleo@yahoo.com>",
"download_url": "https://files.pythonhosted.org/packages/8d/35/57de31ff2bd745aafa940839125104c5150ea1d4c472946c18d99e6813fd/pytest_smtpd-0.1.0.tar.gz",
"platform": null,
"description": "# pytest-smtpd\n\n\u26a0 **Not intended for use with production systems.** \u26a0\n\nThis fixture is intended to address cases where to test an application that sends an email, it needs to be intercepted for subsequent processing. For example, sending an email with a code for password reset or two-factor authentication. This fixture allows a test to trigger the email being sent, ensure that it's sent, and read the email.\n\n## Installing\n\nTo install using pip, first upgrade pip to the latest version to avoid any issues installing `cryptography`:\n\n```bash\npython -m pip install --upgrade pip\npip install pytest-smtpd\n```\n\nOr, if you're using setuptools, it can be included in the `extras_require` argument of a `setup.py` file:\n\n```python\nsetup(\n ...\n extras_require={\n \"test\": [\n \"pytest\",\n \"pytest-smtpd\",\n ],\n },\n)\n```\n\nand then installed with pip (-e assumes that you want your project to be editable):\n\n```bash\npython -m pip install --upgrade pip\npip install -e .[test]\n```\n\n## Using\n\nThe `SMTPDFix` plugin, `smtpd`, automatically registers for use with pytest when you install smtpdfix. To use it simply add to your test method.\n\n```python\nfrom smtplib import SMTP\n\n\ndef test_sendmail(smtpd):\n from_addr = \"from.addr@example.org\"\n to_addrs = \"to.addr@example.org\"\n msg = (f\"From: {from_addr}\\r\\n\"\n f\"To: {to_addrs}\\r\\n\"\n f\"Subject: Foo\\r\\n\\r\\n\"\n f\"Foo bar\")\n\n with SMTP(smtpd.hostname, smtpd.port) as client:\n client.sendmail(from_addr, to_addrs, msg)\n\n assert len(smtpd.messages) == 1\n```\n\nTo use STARTTLS:\n\n```python\nfrom smtplib import SMTP\n\n\ndef test_sendmail(smtpd):\n smptd.config.use_starttls = True\n from_ = \"from.addr@example.org\"\n to_ = \"to.addr@example.org\"\n msg = (f\"From: {from_}\\r\\n\"\n f\"To: {to_}\\r\\n\"\n f\"Subject: Foo\\r\\n\\r\\n\"\n f\"Foo bar\")\n\n with SMTP(smtpd.hostname, smtpd.port) as client:\n client.starttls() # Note that you need to call starttls first.\n client.sendmail(from_addr, to_addrs, msg)\n\n assert len(smtpd.messages) == 1\n```\n\nTo use TLS encryption on the connections:\n\n```python\nfrom smtplib import STMP_SSL # Note the different client class.\n\n\ndef test_custom_certificate(smtpd):\n smtpd.config.use_ssl = True\n\n from_ = \"from.addr@example.org\"\n to_ = \"to.addr@example.org\"\n msg = (f\"From: {from_}\\r\\n\"\n f\"To: {to_}\\r\\n\"\n f\"Subject: Foo\\r\\n\\r\\n\"\n f\"Foo bar\")\n\n with SMTP_SSL(smtpd.hostname, smtpd.port) as client:\n client.sendmail(from_addr, to_addrs, msg)\n\n assert len(smtpd.messages) == 1\n```\n\nThe certificates included with the fixture will work for addresses localhost, localhost.localdomain, 127.0.0.1, 0.0.0.1, ::1. If using other addresses the key (key.pem) and certificate (cert.pem) must be in a location specified under `SMTP_SSL_CERTS_PATH`.\n\n### Configuration\n\nConfiguration is handled through properties in the `config` of the fixture and are initially set from environment variables:\n\nProperty | Variable | Default | Description\n-----------------|------------------------|----------------------|------------\n`host` | `SMTPD_HOST` | `127.0.0.1` or `::1` | The hostname that the fixture will listen on.\n`port` | `SMTPD_PORT` | `a random free port` | The port that the fixture will listen on.\n`ready_timeout` | `SMTPD_READY_TIMEOUT` | `10.0` | The seconds the server will wait to start before raising a `TimeoutError`.\n`login_username` | `SMTPD_LOGIN_NAME` | `user` | Username for default authentication.\n`login_password` | `SMTPD_LOGIN_PASSWORD` | `password` | Password for default authentication.\n`use_ssl` | `SMTPD_USE_SSL` | `False` | Whether the fixture should use fixed TLS/SSL for transactions. If using smtplib requires that `SMTP_SSL` be used instead of `SMTP`.\n`use_starttls` | `SMTPD_USE_STARTTLS` | `False` | Whether the fixture should use StartTLS to encrypt the connections. If using `smtplib` requires that `SMTP.starttls()` is called before other commands are issued. Overrides `use_tls` as the preferred method for securing communications with the client.\n`enforce_auth` | `SMTPD_ENFORCE_AUTH` | `False` | If set to true then the fixture refuses MAIL, RCPT, DATA commands until authentication is completed.\n`ssl_cert_path` | `SMTPD_SSL_CERTS_PATH` | `./certs/` | The path to the key and certificate in PEM format for encryption with SSL/TLS or StartTLS.\n`ssl_cert_files` | `SMTPD_SSL_CERT_FILE` and `SMTPD_SSL_KEY_FILE` | `(\"cert.pem\", None)` | A tuple of the path for the certificate file and key file in PEM format.\n\n## Alternatives\n\nMany libraries for sending email have built-in methods for testing and using these methods should generally be prefered over pytest-smtpd. Some known solutions:\n\n+ **fastapi-mail**: has a `record_messsages()` method to intercept the mail. Instructions on how to suppress the sending of mail and implement it can be seen at [https://sabuhish.github.io/fastapi-mail/example/#unittests-using-fastapimail](https://sabuhish.github.io/fastapi-mail/example/#unittests-using-fastapimail)\n+ **flask-mail**: has a method to suppress sending and capture the email for testing purposes. [Instructions](https://pythonhosted.org/Flask-Mail/#unit-tests-and-suppressing-emails)\n\n## Developing\n\nTo develop and test smtpdfix you will need to install [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) to run asynchronous tests, [isort](https://pycqa.github.io/isort/) to sort imports and [flake8](https://flake8.pycqa.org/en/latest/) to lint. To install in a virtual environment for development:\n\n```bash\npython -m venv venv\n./venv/scripts/activate\npip install -e .[dev]\n```\n\nCode is tested using tox:\n\n```bash\ntox\n```\n\nQuick tests can be handled by running pytest directly:\n\n```bash\npytest\n```\n\nWe include a [pre-commit](https://pre-commit.com/) configuration file to automate checks and clean up imports before pushing code. In order to install pre-commit git hooks:\n\n```bash\npip install pre-commit\npre-commit install\n```\n\n## Known Issues\n\n+ Firewalls may interfere with the operation of the smtp server.\n+ Authenticating with LOGIN and PLAIN mechanisms fails over TLS/SSL, but works with STARTTLS. [smtpdfix Issue #10](https://github.com/bebleo/smtpdfix/issues/10)\n+ Currently no support for termination through signals. [smtpdfix Issue #4](https://github.com/bebleo/smtpdfix/issues/4)\n\nWritten with \u2615 and \u2764 in Montreal, QC\n",
"bugtrack_url": null,
"license": "",
"summary": "An SMTP server for testing built on aiosmtpd",
"version": "0.1.0",
"project_urls": {
"Documentation": "https://github.com/bebleo/pytest-smtpd#readme",
"Issues": "https://github.com/bebleo/pytest-smtpd/issues",
"Source": "https://github.com/bebleo/pytest-smtpd"
},
"split_keywords": [
"email",
"pytest",
"smtp",
"testing"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "7bca509e8473e189e7c2702eaa8e0494f116cdb9aa5f4e4537f5dbaa93c3f096",
"md5": "8fbcb15d41e2d582d2c0d8f6b0a3d362",
"sha256": "1249e4d0ab77120eb53bce5123200b94ab6667b52a6cb5c741a3956a254c2dd8"
},
"downloads": -1,
"filename": "pytest_smtpd-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8fbcb15d41e2d582d2c0d8f6b0a3d362",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4,>=3.7",
"size": 4685,
"upload_time": "2023-05-15T21:24:00",
"upload_time_iso_8601": "2023-05-15T21:24:00.815472Z",
"url": "https://files.pythonhosted.org/packages/7b/ca/509e8473e189e7c2702eaa8e0494f116cdb9aa5f4e4537f5dbaa93c3f096/pytest_smtpd-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8d3557de31ff2bd745aafa940839125104c5150ea1d4c472946c18d99e6813fd",
"md5": "09712dbcc6b16c9ba9ec7d4638f86d26",
"sha256": "e80cd7818f45192ebd8ec517a38d20098378e397e664ec0649da5b98a6e3ff09"
},
"downloads": -1,
"filename": "pytest_smtpd-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "09712dbcc6b16c9ba9ec7d4638f86d26",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4,>=3.7",
"size": 5495,
"upload_time": "2023-05-15T21:24:02",
"upload_time_iso_8601": "2023-05-15T21:24:02.460335Z",
"url": "https://files.pythonhosted.org/packages/8d/35/57de31ff2bd745aafa940839125104c5150ea1d4c472946c18d99e6813fd/pytest_smtpd-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-15 21:24:02",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "bebleo",
"github_project": "pytest-smtpd#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "pytest-smtpd"
}