Question: I have my unittests in a top level tests/ folder for my Python project that uses poetry (link to code). When I run my tests locally, I simply run: poetry run python -m unittest discover -s tests/  Now, I want to run this as CI in Github Actions. I added the following workflow file: name: Tests on: push: branches: [ "master" ] pull_request: branches: [ "master" ] permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 with: python-version: "3.9" - name: Install dependencies run: | python -m pip install --upgrade pip pip install pylint poetry - name: Run tests run: poetry run python -m unittest discover -s tests/ -p '*.py' - name: Lint run: pylint $(git ls-files '*.py')  But, this fails (link to logs): Run poetry run python -m unittest discover -s tests/ -p '*.py' Creating virtualenv fixed-income-annuity-WUaNY9r8-py3.9 in /home/runner/.cache/pypoetry/virtualenvs E ====================================================================== ERROR: tests (unittest.loader._FailedTest) ---------------------------------------------------------------------- ImportError: Failed to import test module: tests Traceback (most recent call last): File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/unittest/loader.py", line 436, in _find_test_path module = self._get_module_from_name(name) File "/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/unittest/loader.py", line 377, in _get_module_from_name __import__(name) File "/home/runner/work/fixed_income_annuity/fixed_income_annuity/tests/tests.py", line 3, in <module> from main import Calculator File "/home/runner/work/fixed_income_annuity/fixed_income_annuity/main.py", line 6, in <module> from dateutil.relativedelta import relativedelta ModuleNotFoundError: No module named 'dateutil' ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) Error: Process completed with exit code 1.  Why does this fail in Github Actions but works fine locally? I understand I can go down the venv route to make it work but I prefer poetry run since its a simple 1 liner.

Answer: You need to install the dependencies in your action in order for it to work. Adding poetry install after your pip statement is an immediate fix, but there are some further tweaks you should make. Your project needs to be tweaked for pytest to pick up your tests. pytest requires that your files be prefixed with test_, and all test classes should start with Test. You should have poetry manage pytest and pylint as dev dependencies so that they are installed within the venv only when you include them in your github actions (and locally) by running poetry install --with dev: # in pyproject.toml [tool.poetry.group.dev.dependencies] pytest = "^7.4.3" pylint = "^3.0.2"  You'll also want to include the current directory in your pythonpath for pytest: # in pyproject.toml [tool.pytest.ini_options] pythonpath = [ "." ]  You'll also want to add an init-hook for pylint to handle imports correctly while in the venv: [MASTER] init-hook='import sys; sys.path.append(".")' # ...  From there, you can just use poetry to manage both pytest and pylint. # snippet of test.yml # ... - name: Install dependencies run: | python -m pip install --upgrade pip pip install poetry poetry install --with dev - name: Run tests run: poetry run pytest - name: Lint run: poetry run pylint $(git ls-files '*.py')