My python apps testing is performed on the remote server with command nosetests. I cannot modify the way tests are started nor can I add options to it. I have Django app with tests, but tests are not working properly.
My project structure:
project
├── README.md
├── setup.py
├── mysite
│ ├── blog
│ │ ├── __init__.py
│ │ ├── models.py
│ │ ├── tests.py
| | ├── ...
│ ├── db.sqlite3
│ ├── manage.py
│ ├── mysite
│ │ ├── __init__.py
│ │ ├── settings.py
| | ├── ...
Command nosetests is executed in project directory. I want it to properly run tests.py which has 2 Django testcases. I tried creating tests directory in project root and invoke tests with DiscoverRunner):
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
test_dir = os.path.dirname(os.path.dirname(__file__)) # one level up
sys.path.insert(0, os.path.join(test_dir, 'mysite'))
class ServerTest(unittest.TestCase):
def test_runtests(self):
django.setup()
self.test_runner = DiscoverRunner(verbosity=1, interactive=True, failfast=False)
failures = self.test_runner.run_tests(['mysite'])
self.assertEqual(failures, 0)
It works but the problem is all the tests are considered as a single test and wrong reports are produced by the server.
Another solution: if I add empty __init__.py to project/mysite nose discovers tests.py but the tests fail because 'Apps are not loaded yet' which probably means I have to invoke django.setup() earlier but I don't know how to do it. I found a plugin for the nose which does it but I cannot install plugins or alter options on the remote machine.
Any ideas how to make any of my approaches solve the problem?
Firsts things first, you should install and configure django-nose if you haven't done so already:
pip install django-nose
Then add it on your INSTALLED_APPS:
INSTALLED_APPS = (
...
'django_nose'
)
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
Now for the nosetests command to run correctly, you can create a folder named tests with the following structure:
project
├── mysite
│ ├── blog
│ │ ├── __init__.py
│ │ ├── models.py
| | ├── ...
│ ├── mysite
│ │ ├── __init__.py
│ │ ├── settings.py
| | ├── ...
│ ├── tests
│ │ ├── __init__.py
│ │ ├── test_a_whole_class_of_methods.py
│ │ ├── test_a_whole_view.py
│ │ ├── test_one_of_my_methods.py
│ │ ├── test_another_one_of_my_methods.py
| | ├── ...
│ ├── db.sqlite3
│ ├── manage.py
├── README.md
├── setup.py
DON'T FORGET THE __init__.py FILE INSIDE THE tests FOLDER!!!
Now when you run nosetests from the root of your project, it will run every test in the tests folder:
~ $ cd path/to/project
path/to/project $ nosetests
Since you can add files to the root of your project, you could try adding a setup.cfg file there that nose will look for when executing, and in it specify where to look for tests:
# setup.cfg
[nosetests]
where=mysite/blog/
(See the documentation for what parameters you can put here).
I'm not sure that this will work (it is possible that the command that starts nose has already specified a different configuration file to use), but it seems worth a shot.
Related
Hello I am trying to develop a few tests with python in order to do this I have the following folder structure:
.
├── Pipfile
├── Pipfile.lock
├── src
│ ├── adapters
│ │ ├── __init__.py
│ │ ├── orm.py
│ │ └── repository.py
│ ├── app.py
│ ├── bootstrap.py
│ ├── db.py
│ ├── domain
│ │ ├── __init__.py
│ └── settings.py
└── test
├── conftest.py
├── __init__.py
├── integration
│ ├── test_orm.py
│ └── test_repository.py
├── pytest.ini
└── unit
├── test_account.py
├── test_client.py
├── test_commerce.py
└── test_move.py
The pytest.ini contains:
[pytest]
pythonpath = src
The tests are launched with the following command:
python -m pytest -s -v test/
The problem is about import, in the conftest.py I have the following code:
import pytest
from sqlalchemy.orm import clear_mappers
from adapters.orm import start_mappers
#pytest.fixture
def mappers():
start_mappers()
yield
clear_mappers()
The line from adapters.orm import start_mappers fails if I doesn't set src before like this from src.adapters.orm import start_mappers
but if do that, the file inside orm module fails, because it has the relative import:
from domain import Move, Account, Client, Commerce
instead of
from src.domain import Move, Account, Client, Commerce
but if I use this, of course, another thing fails, and the idea is not to use src. suffix in the src code.
So how can I solve this, in order to avoid installing src as a python package, or fill all folders with init.py or put src. in all places?
Thanks.
I have this structure for my project:
├── Dockerfile
├── app
│ ├── __init__.py
│ ├── __pycache__
│ ├── config
│ ├── database
│ ├── logging.py
│ ├── main.py
│ ├── routers
│ ├── services
│ ├── static
│ ├── templates
│ ├── utils
│ └── worker
├── k6.js
├── poetry.lock
├── prestart.sh
├── pyproject.toml
├── pytest.ini
└── run.py
Inside app, I have this worker folder that I also open as a kind of separate project.
├── __init__.py
├── database
│ ├── __init__.py
│ └── conn.py
├── engine
│ ├── __init__.py
│ ├── core
│ ├── data
│ ├── main.py
│ └── utils
├── main.py
├── poetry.lock
├── pyproject.toml
└── run.sh
The issue that I have when I open worker project which uses code from upper directory, pylance gives me an error of an import that could not be resolved. However, this code runs fine and perfect.
I created .vscode/settings.json for the worker project and add these options:
"python.analysis.extraPaths": ["../../app"],
"python.autoComplete.extraPaths": ["../../app"]
But I am still getting these errors! How can I fix this?
These paths fixed my issue:
"python.analysis.extraPaths": ["${workspaceFolder}\\..\\.."],
"python.autoComplete.extraPaths": ["${workspaceFolder}\\..\\.."]
(In the interest of transparency, this is a follow up to a question asked here)
I'm dealing with related files in which a namespace package seems a good fit. I'm following the guide from the packaging authority, which places a setup.py in each namespace package;
mynamespace-subpackage-a/
setup.py
mynamespace/
subpackage_a/
__init__.py
mynamespace-subpackage-b/
setup.py
mynamespace/
subpackage_b/
__init__.py
module_b.py
In my tests, created a similar project. Apart from setup.py, I placed my unit tests, docs, and other stuff per namespace (I left out some of the directories for compactness.). I used pyscaffold to generate the namespaces.
├── namespace-package-test.package1
│ ├── LICENSE.txt
│ ├── README.md
│ ├── setup.cfg
│ ├── setup.py
│ ├── src
│ │ └── pkg1
│ │ ├── cli
│ │ │ ├── __init__.py
│ │ │ └── pkg1_cli.py
│ │ └── __init__.py
│ └── tests
├── namespace-package-test.package2
│ ├── AUTHORS.rst
However, I then noticed that pyscaffold has the option to create namespaces packages in the putup command.
(venv) steve#PRVL10SJACKSON:~/Temp$ putup --force my-package -p pkg1 --namespace namespace1
(venv) steve#PRVL10SJACKSON:~/Temp$ putup --force my-package -p pkg1 --namespace namespace2
This creates a folder structure like this;
├── AUTHORS.rst
├── CHANGELOG.rst
├── LICENSE.txt
├── README.rst
├── requirements.txt
├── setup.cfg
├── setup.py
├── src
│ ├── namespace1
│ │ ├── __init__.py
│ │ └── pkg1
│ │ ├── __init__.py
│ │ └── skeleton.py
│ └── namespace2
│ ├── __init__.py
│ └── pkg1
│ ├── __init__.py
│ └── skeleton.py
└── tests
├── conftest.py
└── test_skeleton.py
So I'm conflicted; I trust the team at pyscaffold, but it goes against the example from the packaging authority.
Are both approaches valid?
Is there a reason to choose one approach over the other?
The idea behind the namespace option in PyScaffold is to share/reuse namespaces across projects (in opposite of having more than one namespace inside a single project). Or in other words, to split a larger project in independently maintained/developed projects.
To my best understanding, having an structure like the one you showed in the 4th code block will not work. Using putup --force twice with 2 different namespaces for the same root folder is not the intended/supported usage.
The approach of PyScaffold is the same as the package authority, the only difference is that PyScaffold will assume you have only one package contained in a single project and git repository (PyScaffold also uses a src directory for the reasons explained in Ionel's blog post)
The reason behind adopting one setup.py per namespace+package is that it is required for building separated distribution files (i.e. you need one setup.py per *.whl).
My Django project has a few app each with their respective tests. It also has a utils package that has its own tests.
The package utils is in a folder at the same level as manage.py and its tests are in a subfolder called tests in files called test_xxx.py
When I run python manage.py test Django runs all tests for all the apps in my project but it does not run the tests for the utils package. I can run the tests for the utils package by running python manage.py test utils.
What I would like to do is that tests for utils are also run when I run python manage.py test so that single command tests the whole suite for my project. I haven't been able to find anything in the documentation or searching google or here on how to do it. Any ideas?
Thanks for your help!!
--- Additional details ---
Directory structure
├── project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── ...
├── app1
│ ├── __init__.py
│ ├── urls.py
│ ├── views.py
│ ├── ...
│ └── tests
│ ├── test_views.py
│ └── test_models.py
├── app2
│ ├── __init__.py
│ ├── urls.py
│ ├── views.py
│ ├── ...
│ └── tests
│ ├── test_views.py
│ └── test_models.py
└── utils
├── __init__.py
├── code.py
└── tests
└── test_utils.py
Command to execute tests
python manage.py test
... that executes ...
nosetests --with-coverage --cover-package=app1,app2, utils --cover-html --cover-erase --logging-filter='selenium' --verbosity=1
And the coverage report shows that all the tests for app1 and app2 have been executed but not the tests for utils
Django uses the DiscoverRunner to run your tests harness. As you can see here: https://docs.djangoproject.com/en/2.1/topics/testing/advanced/#defining-a-test-runner
The first option is:
top_level can be used to specify the directory containing your
top-level Python modules. Usually Django can figure this out
automatically, so it’s not necessary to specify this option. If
specified, it should generally be the directory containing your
manage.py file.
Therefore your test should be run by the test harness because are in the same folder of your manage.py. Did you add the __init__.py in the tests folder?
I have a Django project in which certain environment variables are set in manage.py which later serve as the values defined in settings.py. Therefore, in order to run pytest-django, I'd like to run manage.py first.
I'm trying to follow the instructions in https://pytest-django.readthedocs.io/en/latest/faq.html#how-can-i-use-manage-py-test-with-pytest-django, but I'm running into an unexpected error. I have the following directory structure:
.
├── lucy
│ ├── settings
│ ├── base.py
│ ├── development.py
│ ├── production.py
│ └── staging.py
│ ├── staticfiles
│ ├── urls.py
│ └── wsgi.py
├── lucy_web
│ ├── __init__.py
│ ├── actions.py
│ ├── admin
│ ├── apps.py
│ ├── fixtures
│ ├── forms
│ ├── lib
│ ├── management
│ ├── migrations
│ ├── models
│ ├── runner.py
│ ├── serializers.py
│ ├── static
│ ├── templates
│ ├── templatetags
│ ├── tests
│ ├── urls.py
│ └── views
├── manage.py
├── pytest.ini
The contents of runner.py are taken exactly from the FAQ:
class PytestTestRunner(object):
"""Runs pytest to discover and run tests."""
def __init__(self, verbosity=1, failfast=False, keepdb=False, **kwargs):
self.verbosity = verbosity
self.failfast = failfast
self.keepdb = keepdb
def run_tests(self, test_labels):
"""Run pytest and return the exitcode.
It translates some of Django's test command option to pytest's.
"""
import pytest
argv = []
if self.verbosity == 0:
argv.append('--quiet')
if self.verbosity == 2:
argv.append('--verbose')
if self.verbosity == 3:
argv.append('-vv')
if self.failfast:
argv.append('--exitfirst')
if self.keepdb:
argv.append('--reuse-db')
argv.extend(test_labels)
return pytest.main(argv)
Finally, in lucy/settings/base.py I add the following line:
TEST_RUNNER = 'lucy_web.runner.PytestTestRunner'
Finally, the pytest.ini file is as in the example in the docs:
# -- FILE: pytest.ini (or tox.ini)
[pytest]
DJANGO_SETTINGS_MODULE = lucy.settings.production
# -- recommended but optional:
python_files = tests.py test_*.py *_tests.py
The problem is that pytest doesn't seem able to find the tests. If I run the command
python manage.py test lucy_web.tests
I get
(venv) Kurts-MacBook-Pro:lucy-web kurtpeek$ python manage.py test lucy_web.tests
============================================ test session starts ============================================
platform darwin -- Python 3.6.4, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /Users/kurtpeek/Documents/Dev/lucy/lucy-web, inifile: pytest.ini
======================================= no tests ran in 0.00 seconds ========================================
ERROR: file not found: lucy_web.tests
However, if I comment out the TEST_RUNNER line in base.py and run the same command, the tests run successfully:
(venv) Kurts-MacBook-Pro:lucy-web kurtpeek$ python manage.py test lucy_web.tests
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
....E.F................
----------------------------------------------------------------------
Ran 23 tests in 15.974s
FAILED (failures=1, errors=1)
Destroying test database for alias 'default'...
What am I doing wrong here? Do I need to put runner.py in a different location?
Maybe it's because of __init__.py
I experienced a similar situation when using pytest. I deleted __init__.py in tests dir and it tested well.
It's little bit different situation, but I hope this helps.
links that I got help.
https://docs.pytest.org/en/latest/pythonpath.html
`py.test` and `__init__.py` files