Add testing for PyPi releases

This commit is contained in:
Jon Grace-Cox
2022-08-13 12:30:58 -07:00
parent ff0ee0d5e0
commit 9b2ffea8f3
8 changed files with 161 additions and 20 deletions

1
.gitignore vendored
View File

@@ -117,3 +117,4 @@ htmlcov/
**/*.svg
!anybadge/templates/*.svg
test_files/

View File

@@ -145,12 +145,16 @@ Invoke tasks are defined in the `tasks/` directory in the project. Feel free to
## Running tests
### Local tests
You can run tests locally using:
```bash
inv test.local
```
### Containerised tests
When running locally, you will be running tests against the code in the project. This has some disadvantages,
specifically running locally may not detect files that are not included in the package build, e.g. sub-modules,
templates, examples, etc. For this reason we have a containerised test. This can be run using:
@@ -163,6 +167,34 @@ This will clean up the project `dist` directory, build the package locally, buil
spin up a docker container, install the package and run the tests. The tests should run using the installed
package and not the project source code, so this method should be used as a final test before pushing.
### PyPi tests
It is useful to validate PyPi releases when a new version is deployed. This should be done after every
release.
#### Running tests
To test the latest available PyPi package, run:
```bash
inv test.pypi>
```
To test a specific version of a PyPi package, run:
```bash
inv test.pypi --version=\<VERSION>
```
When the tests run they will output test files into a `\<VERSION>_\<DATETIME>` directory under `test_files/`.
After running tests, inspect the console output to see if there were any errors then inspect each file in the
`test_files` directory.
#### Adding tests
The PyPi tests are implemented in `docker/test/run_pypi_tests.sh`. If you find a bug, then adding a test to this script
could be useful, and quicker than adding a unittest.
## Documentation
The `README.md` file contains a table showing example badges for the different built-in colors. If you modify the

View File

@@ -6,3 +6,4 @@ RUN apt update && pip install -U pip
COPY requirements.txt ./
RUN pip install -r ./requirements.txt
COPY run_docker_tests.sh ./
COPY run_pypi_tests.sh ./

78
docker/test/run_pypi_tests.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
error() {
echo "==============================================================================="
echo " An error was encountered."
echo "==============================================================================="
}
check_rc() {
if [[ $? -ne 0 ]]; then
error
exit 1
fi
}
TEST_FILES="/test_files"
if [[ -z {$VERSION} ]] || [[ ${VERSION} = latest ]]; then
version_str=""
else
version_str="==$VERSION"
fi
echo -n "Installing anybadge${version_str}... "
pip install anybadge${version_str} > "${TEST_FILES}/pip_install.log" 2>&1
check_rc
echo "OK"
installed_version=$(pip freeze | grep -e "^anybadge==" | sed 's/^.*==//' )
datestamp=$(date '+%Y-%m-%d_%H%M%S')
TEST_FILES="${TEST_FILES}/${installed_version}_${datestamp}"
echo -n "Creating test directory: ${TEST_FILES} "
mkdir -p ${TEST_FILES}
check_rc
echo "OK"
# Command line tests
anybadge --help > "${TEST_FILES}/test_help_text.txt" && check_rc
anybadge --label="Label" --value="Value" --file "${TEST_FILES}/test_command_line.svg" && check_rc
# Python tests
python > "${TEST_FILES}/test_python_console.log" <<EOF
import anybadge
badge = anybadge.Badge(label="Label", value="Value")
badge.write_badge(file_path="${TEST_FILES}/test_python_1.svg")
print(badge)
EOF
check_rc
# Start server
echo -n "Starting server... "
anybadge-server > "${TEST_FILES}/server_start.log" 2>&1 &
server_pid=$!
echo "OK - Started server with pid ${server_pid}"
sleep 1
kill -0 ${server_pid}
check_rc
# Test server
echo -n "Testing server badge... "
curl "http://localhost:8000/?label=Project%20Awesomeness&value=110%" -o "${TEST_FILES}/test_server.svg" --silent
check_rc
echo "OK"
echo -n "Testing server index page... "
curl "http://localhost:8000" -o "${TEST_FILES}/test_server_index.html" --silent
check_rc
echo "OK"
# Stop server
echo -n "Stopping server... "
kill $server_pid
check_rc
echo "OK"

View File

@@ -5,7 +5,7 @@ import subprocess
from pathlib import Path
from invoke import task, Collection
from tasks import test, server
from tasks import test, server, housekeeping
PROJECT_DIR = Path(__file__).parent.parent
@@ -28,20 +28,6 @@ def examples(c):
main()
def delete_files(files: str):
for file in glob.glob(files):
print(f" Deleting {file}")
subprocess.run(["rm", "-rf", file])
@task()
def clean(c):
"""Clean up the project area."""
print("Cleaning the project directory...")
delete_files("dist/*")
delete_files("tests/test_*.svg")
namespace = Collection(test, server)
for fn in [build, examples, clean]:
namespace = Collection(test, server, housekeeping)
for fn in [build, examples]:
namespace.add_task(fn)

18
tasks/housekeeping.py Normal file
View File

@@ -0,0 +1,18 @@
import glob
import subprocess
from invoke import task
def delete_files(files: str):
for file in glob.glob(files):
print(f" Deleting {file}")
subprocess.run(["rm", "-rf", file])
@task()
def clean(c):
"""Clean up the project area."""
print("Cleaning the project directory...")
delete_files("dist/*")
delete_files("tests/test_*.svg")
delete_files("test_files/*")

View File

@@ -5,12 +5,14 @@ from invoke import task
@task
def docker_build(c):
"""Build docker image for anybadge server."""
print("Building Docker image...")
subprocess.run("docker build . -t anybadge:latest", shell=True)
@task
def docker_run(c, port=8000):
"""Run containerised anybadge server."""
print("Running server in Docker container...")
subprocess.run(
f"docker run -it --rm -p{port}:{port}/tcp anybadge:latest --port={port}",
@@ -20,5 +22,6 @@ def docker_run(c, port=8000):
@task
def run(c, port=8000):
"""Run local anybadge server."""
print("Running server locally...")
subprocess.run(f"python3 anybadge_server.py --port={port}", shell=True)

View File

@@ -3,6 +3,8 @@ from pathlib import Path
from invoke import task
from tasks.housekeeping import clean
PROJECT_DIR = Path(__file__).parent.parent
@@ -16,6 +18,12 @@ def local(c):
)
def build_test_docker_image():
subprocess.run(
f"(cd docker/test && docker build . -t test-anybadge:latest)", shell=True
)
@task
def docker(c):
"""Run dockerised tests."""
@@ -23,10 +31,24 @@ def docker(c):
subprocess.run("invoke clean", shell=True)
subprocess.run("invoke build", shell=True)
subprocess.run(
f"(cd docker/test && docker build . -t test-anybadge:latest)", shell=True
)
build_test_docker_image()
subprocess.run(
f"docker run -v {PROJECT_DIR}:/app test-anybadge:latest /work/run_docker_tests.sh",
shell=True,
)
@task
def pypi(c, version="latest"):
"""Run tests against Pypi version."""
print("Running tests against pypi version...")
clean(c)
test_files = PROJECT_DIR / Path("test_files")
test_files.mkdir(exist_ok=True)
build_test_docker_image()
subprocess.run(
f"docker run -e VERSION={version} -v {test_files.absolute()}:/test_files test-anybadge:latest /work/run_pypi_tests.sh",
shell=True,
)