Dynamically create and run tests in Github Actions - python

I have a git project with directory structure similar to this:
.
├── .github/
│ └── workflows/
│ └── test.yml
└── my_packages/
├── package_1/
│ ├── tests/
│ │ └── test_package.py
│ ├── package_logic.py
│ ├── configurations.yml
│ └── requirements.py
├── package_2/
│ ├── tests/
│ │ └── test_package.py
│ ├── package_logic.py
│ ├── configurations.yml
│ └── requirements.py
├── ...
└── package_n/
├── tests/
│ └── test_package.py
├── package_logic.py
├── configurations.yml
└── requirements.py
There are n packages in this repository and every package is independent one from another with its own requirements.py, logic, and tests.
There is also test.yml file, which is currently not implemented, that needs to create a testing environment for every package separately and run its test (pytest). Another requirement is that every package defines its python version in the configurations.yml file in which the module test should run. And finally, the test should run only for modules which code was changed.
How can this be implemented in Github Actions? And is it possible to run every module in a separate job (or just in parallel)?

Related

Pytest: import in another test causing mocks to fail

I've been asked to take a look at some tests in our project. The component tests all run individually no problem, but when run together we get hundreds of errors. Given the scale of the problem I'm no longer actively looking into it, but I've become really frustrated trying to figure out why it's happening.
A section of the project layout is below. There are modules dealing with various aspects of the project defined in the 'lambdas' folder, with a 'common' folder that contains utilities used by other files. I'm specifically looking at some tests in the 'episodes/api' directory.
.
└── lambdas
├── access
├── ...
├── common
│ ├── dal
│ └── utils
│ │ ├── api_utils.py
│ │ ├── audit_utils.py
│ │ └── date_utils.py
│ └── ...
└── episodes
└── api
├── accept_participant
│ ├── component_tests
│ │ ├── __init__.py
│ │ └── accept_participant_test.py
│ ├── unit_tests
│ │ ├── __init__.py
│ │ └── accept_participant_test.py
│ ├── accept_participant.py
│ └── __init__.py
└── reject_participant
│ ├── component_tests
│ │ ├── __init__.py
│ │ └── reject_participant_test.py
│ ├── unit_tests
│ │ ├── __init__.py
│ │ └── reject_participant_test.py
│ ├── reject_participant.py
│ └── __init__.py
accept_participant.py imports two methods from common.utils.audit_utils, one of which uses a boto3.client to communicate with SQS. The component test accept_participant_test mocks out the boto3.client call, which all works fine when run on its own. It also works fine when run in conjunction with the other component test, as long as the unit tests are not physically present. If the unit tests are run, or even if they're present but not selected for run (using a pytest.mark), the accept_participant_test component test fails.
The unit test causing the problem is the reject_participant_test. It imports common.utils.audit_utils in order to check the value of an enum in it. When this line is commented out, the component test passes ok.
I'm probably missing a gotcha here somewhere, but why does this one import cause a problem? The unit test isn't even being run. I'm thinking I might need to change the boto3.client patch, but I've tried all sorts of different variations and it either tells me it's not a package or doesn't exist in the namespace.

ImportError attempted relative import beyond top-level package

This is my project structure:
.
├── connectapp
│ ├── __init__.py
│ ├── __pycache__
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── djangoproject
│ ├── __init__.py
│ ├── __pycache__
│ ├── asgi.py
│ ├── djangoproject.sqlite3
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── djangoproject.sqlite3
├── hackerapp
│ ├── Controllers
│ ├── Models
│ ├── Serializers
│ ├── __init__.py
│ ├── __pycache__
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ └── tests.py
├── manage.py
└── requirments.txt
When I do below being in top level folder:
python3 manage.py migrate hackerapp
I am getting this:
djangoproject/djangoproject/urls.py", line 19, in <module>
from ..hackerapp.Controllers import PersonViewSet, DepartmentViewSet
ImportError: attempted relative import beyond top-level package
To me looks import should work but it's not, can someone tell me why?
I guess (?) migrate hackerapp are cli params to the manage.py script. The error means that the top level folder is not a package. To make it into a package add an (empty) __init__.py file then from that folder run:
python -m manage migrate hackerapp # note no .py

Git remove ignored __pycache__ directory after Python package rename

I have a Python package in my Git repository called lib/requestAPI that contains a __pycache__ directory and three modules:
├── lib
│   ├── __init__.py
│   ├── requestAPI
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   ├── checkwx.py
│   │   ├── github.py
│   │   └── weatherflow.py
I have added __pycache__/ to my .gitignore file to ignore the contents of the __pycache__ directory.
I recently renamed the Python package to lib/request_api and the names of the three modules. I pushed these changes to the remote server and then pulled the changes to a second machine. On this second machine, however, the lib/requestAPI folder remains as it contains the local __pycache__ directory
├── lib
│ ├── __init__.py
│ ├── requestAPI
│ │ └── __pycache__
│ ├── request_api
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ ├── checkwx_api.py
│ │ ├── github_api.py
│ │ └── weatherflow_api.py
Is there a Git command I can use to remove this extra __pycache__ directory associated with the old package directory? I know I can use git clean -d -X to remove all ignored files and directories, but this also removes ignored configuration files which I don't want. Removing this folder manually is also not an option as the repository is distributed to many people

Run single folder of pytest tests in vscode

I have a sort of a "micro-service" Python repo with a setup similar to the following:
sample
├── bar
│ ├── src
│ │ └── main.py
│ └── tests
│ └── test_main.py
├── foo
│ ├── src
│ │ └── main.py
│ └── tests
│ └── test_main.py
└── shared
├── src
│ └── main.py
└── tests
└── test_main.py
In vscode I only have the option of running all tests in foo,bar,shared or running individual test methods in the subfolders. What I want to do is be able to quickly run just the foo/tests/.
Is there some way I can configure pytest/Python to do this? I don't want to split each top level folder into its own workspace because I regularly jump back and for between them and don't want to have multiple windows per workspace open.
You should be able to run the command pytest foo/tests/ in the terminal according to the
pytest documentation

Python module import issue subdir

I have the following directory structure in my Python3 project:
├── README.md
├── requirements.txt
├── schemas
│ ├── collector.sql
│ └── controller.sql
├── src
│ ├── controller.db
│ ├── controller.py
│ ├── measurement_agent.py
├── tests
│ ├── regression.py
│ ├── test-invalid-mac.py
│ ├── test-invalid-url.py
│ ├── test-register-ma-json.py
│ ├── test-register-ma-return-code.py
│ ├── test-send-capabilities-return-code.py
│ ├── test-valid-mac.py
│ └── test-valid-url.py
└── todo
In my tests folder I have some regression tests which are ran to check the consistency of the code from src/measurement_agent.py. The problem now is that I do not want to add to my path manually the measurement_agent.py to make an import from it. I would want to know if there is any trick how to tell Python to look in my root for the import I am trying to use.
Currently I am doing:
import os.path
ma = os.path.abspath('..') + '/src'
sys.path.append(ma)
from measurement_agent import check_hardware_address
and would want to have something just like
from measurement_agent import check_hardware_address
without using any os.path tricks.
Any suggestions?
Relative imports
Make sure there is an __init__.py in all folders including the top-most (the parent)
Use a relative import, like this:
from ..src import measurement_agent
Now to run your code, cd up to the parent of your parent directory and then
python -m parent.test.regression

Categories

Resources