remove-pythonpath-requirement #11
3 changed files with 81 additions and 8 deletions
76
README.md
76
README.md
|
|
@ -1,16 +1,88 @@
|
||||||
# pytest-abra
|
# pytest-abra
|
||||||
...description...
|
|
||||||
|
Pytest-Abra is an installable python package design to test instances created with [abra](https://docs.coopcloud.tech/abra/). After installation, you will have two things:
|
||||||
|
|
||||||
|
- `abratest` CLI command
|
||||||
|
|
||||||
|
- `pytest-abra` Pytest plugin
|
||||||
|
|
||||||
|
## CLI (abratest)
|
||||||
|
|
||||||
|
The easiest way to call abratest is via the helper script in `main.py`. You can also directly call abratest via terminal, but you will have to make sure that the requirements below are met. To do that, you can call `abratest` with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
abratest [arguments]
|
||||||
|
```
|
||||||
|
|
||||||
|
The cli command abratest has 3 **required arguments**:
|
||||||
|
|
||||||
|
- `--env_paths`: list of the .env files used in the test
|
||||||
|
- `--recipes_dir`: directory of all available abra recipes
|
||||||
|
- `--output_dir`: target directory for all test results
|
||||||
|
|
||||||
|
### env_paths [string]
|
||||||
|
|
||||||
|
The variable env_paths consists of one or more paths pointing at .env files. The paths are separated with ";". These .env files are actually configuration files for `abra` recipes, but `pytest-abra` uses the same files for test configuration.
|
||||||
|
|
||||||
|
To run `abratest` with these `.env` configuration files
|
||||||
|
|
||||||
|
```
|
||||||
|
/path/to/config_1.env
|
||||||
|
/path/to/config_2.env
|
||||||
|
/path/to/config_3.env
|
||||||
|
```
|
||||||
|
|
||||||
|
we simply call
|
||||||
|
|
||||||
|
```
|
||||||
|
abratest --env_paths /path/to/config_1.env;/path/to/config_2.env;/path/to/config_3.env
|
||||||
|
```
|
||||||
|
|
||||||
|
Under the hood, each `.env` file in `--env_paths` will create one instance of a `Runner` subclass. Let's say we have `wordpress_configuration.env` containing `TYPE=wordpress`. This will create an instance of `RunnerWordpress`. This class has to be imported from `recipes_dir`.
|
||||||
|
|
||||||
|
### recipes_dir [string]
|
||||||
|
|
||||||
|
The required argument `--recipes_dir` has to point to the directory, where all the abra recipes are stored. We can call `abratest` with
|
||||||
|
|
||||||
|
```
|
||||||
|
abratest --recipes_dir /path/to/abra/recipes
|
||||||
|
```
|
||||||
|
|
||||||
|
The expected dir structure inside of `recipes_dir` is as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
DIR recipes_dir [contains abra recipes]
|
||||||
|
│
|
||||||
|
├── DIR authentik [authentik recipe]
|
||||||
|
│ ├── [files from authentik recipe]
|
||||||
|
│ └── DIR tests_authentik [pytest tests for authentik]
|
||||||
|
│ ├── FILE runner_authentik.py # containing RunnerAuthentik class
|
||||||
|
│ └── [pytest_files]
|
||||||
|
│
|
||||||
|
└── DIR wordpress [wordpress recipe]
|
||||||
|
├── [files from wordpress recipe]
|
||||||
|
└── DIR tests_wordpress [pytest tests for wordpress]
|
||||||
|
├── FILE runner_wordpress.py # containing RunnerWordpress class
|
||||||
|
└── [pytest_files]
|
||||||
|
```
|
||||||
|
|
||||||
|
The class `RunnerWordpress` will be automatically imported by `importlib`, which is equivalent to
|
||||||
|
|
||||||
|
```python
|
||||||
|
from wordpress.tests_wordpress.runner_wordpress import RunnerWordpress
|
||||||
|
```
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
To use pytest-abra, follow these steps:
|
To use pytest-abra, follow these steps:
|
||||||
|
|
||||||
## 1. GIT Clone
|
## 1. GIT clone [with & without Docker]
|
||||||
|
|
||||||
To clone with submodules, use these git commands:
|
To clone with submodules, use these git commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --recurse-submodules <repository>
|
git clone --recurse-submodules <repository>
|
||||||
|
// optional:
|
||||||
git submodule update --init // add submodule after normal cloning
|
git submodule update --init // add submodule after normal cloning
|
||||||
git submodule update --remote // update submodules
|
git submodule update --remote // update submodules
|
||||||
```
|
```
|
||||||
|
|
|
||||||
6
main.py
6
main.py
|
|
@ -31,12 +31,6 @@ ENV_PATHS = ";".join([x.as_posix() for x in ENV_FILES])
|
||||||
RECIPES_DIR = Path("../recipes").resolve()
|
RECIPES_DIR = Path("../recipes").resolve()
|
||||||
OUTPUT_DIR = Path("./test-output").resolve()
|
OUTPUT_DIR = Path("./test-output").resolve()
|
||||||
|
|
||||||
# -------------------------------- pythonpath -------------------------------- #
|
|
||||||
|
|
||||||
# add recipes dir to pythonpath, so that python imports from there are possible
|
|
||||||
# the custom classes of Runner will be imported from there
|
|
||||||
os.environ["PYTHONPATH"] = RECIPES_DIR.as_posix()
|
|
||||||
|
|
||||||
# ------------------------------------ run ----------------------------------- #
|
# ------------------------------------ run ----------------------------------- #
|
||||||
|
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import importlib
|
import importlib
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
@ -90,11 +91,17 @@ class Coordinator:
|
||||||
"wordpress": RunnerWordpress,
|
"wordpress": RunnerWordpress,
|
||||||
"nextcloud": RunnerNextcloud,
|
"nextcloud": RunnerNextcloud,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
The Runner classes are automatically imported with importlib. The imports are successful
|
||||||
|
because recipes_dir is added to sys.path.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RUNNER_DICT: dict[str, type["Runner"]] = dict()
|
RUNNER_DICT: dict[str, type["Runner"]] = dict()
|
||||||
runner_discovery_pattern = re.compile("Runner.+")
|
runner_discovery_pattern = re.compile("Runner.+")
|
||||||
|
|
||||||
|
# make it possible to import modules from recipes_dir
|
||||||
|
sys.path.append(recipes_dir.as_posix())
|
||||||
|
|
||||||
for module_path in recipes_dir.rglob("*/runner*.py"):
|
for module_path in recipes_dir.rglob("*/runner*.py"):
|
||||||
rel_path = module_path.relative_to(recipes_dir).as_posix().replace("/", ".").replace(".py", "")
|
rel_path = module_path.relative_to(recipes_dir).as_posix().replace("/", ".").replace(".py", "")
|
||||||
module = importlib.import_module(rel_path)
|
module = importlib.import_module(rel_path)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue