How do I see stdout when running Django tests? - python

When I run tests with ./manage.py test, whatever I send to the standard output through print doesn't show. When tests fail, I see an "stdout" block per failed test, so I guess Django traps it (but doesn't show it when tests pass).

Checked TEST_RUNNER in settings.py, it's using a project-specific runner that calls out to Nose. Nose has the -s option to stop it from capturing stdout, but if I run:
./manage.py test -s
manage.py captures it first and throws a "no such option" error. The help for manage.py doesn't mention this, but I found that if I run:
./manage.py test -- -s
it ignores the -s and lets me capture it on the custom runner's side, passing it to Nose without a problem.

Yeah, this issue is caused by NoseTestSuiteRunner. Adding -- -s is tricky and not the best solution.
Try to add the following lines in the settings.py:
NOSE_ARGS = ['--nocapture',
'--nologcapture',]
This solved my problems.

There are several levels of verbosity available which affects the amount of details we see:
You can try:
python manage.py test -v 2
Other levels available are:
-v 0 : Least amount of details
-v 1: Default
-v 2 : More details e.g. print statements included.

Using current versions of all the relevant packages (Django==1.11.2, django-nose==1.4.5 and nose==1.3.7) it is sufficient to add the --nocapture flag when running your tests. Thus a simple
./manage.py test --nocapture
will suffice.
Granted of course that you have
TEST_RUNNER = "django_nose.NoseTestSuiteRunner"
in your settings.py

You probably have some intermediate test runner, such as Nose, intercepting and storing stdout. Try either running the Django tests directly, or write to stderr instead.

Related

How to use pytest-custom_exit_code plugin

Need help!
I have a job on Gitlab ci, that runs tests and reruns failed ones. If there are no failed tests, job fails with exit code 5, that means that there are no tests for running. I found out that there is plugin "pytest-custom_exit_code", but I don't know how to correctly use it.
I need just to add command 'pytest --suppress-no-test-exit-code' to my runner.sh?
It looks like this now:
#!/bin/sh
/usr/local/bin/pytest -m test
/usr/local/bin/pytest -m --last-failed --last-failed-no-failures none test
Assumption here is that plugin is installed first using
pip install pytest-custom_exit_code
command like option pytest --suppress-no-test-exit-code should work after that.
If configuration file like .pytest.ini is used , following lines should be added in it
[pytest]
addopts = --suppress-no-test-exit-code

Django how do I get a command to execute when all tests pass?

I'm trying to find out if there is a way to have a function fire when all the tests pass.
trying to do something along the lines of:
call(["say", "all tests have passed Dave"])
When you run ./manage.py test, the exit status of the command is zero (success) if all tests have passed and non-zero (failure) otherwise. In Unix/Linux, you can do this:
./manage.py test && echo "All tests have passed"
For Windows, see another stackoverflow question.

nose get list of test without running them

Is there a way to get a list of all the tests currently recognized by nose, without running them?
According to the doc
--collect-only Enable collect-only: Collect and output test names only, don't run any tests. [COLLECT_ONLY]
However when I do nosetests --collect-only I get:
Ran 101 tests in 0.642s
OK
How can I get names those tests?
Try with the -v option:
nosetests -v --collect-only
If you're trying to debug how nose actually finds your tests, go for -vv

DJANGO_SETTINGS_MODULE is defined, project settings do import via `python manage.py `, yet django-pytest does not find the django settings

Synopsis of problem:
I want to use django-pytest to test my django scripts yet py.test complains that it cannot find DJANGO_MODULE_SETTINGS. I have followed the documentation of django-pytest for setting DJANGO_MODULE_SETTINGS. I am not getting the expected behavior from py.test.
I would like help troubleshooting this problem. Thank you in advance.
References—django-pytest documentation
Setting the DJANGO_SETTINGS_MODULE in virtualevn postactivate script:
In a new shell, the $DJANGO_SETTINGS_MODULE is not set.
I expect that the $DJANGO_SETTINGS_MODULE would be None. It
is.
In: echo $DJANGO_SETTINGS_MODULE
Out:
Contents of .virtualenv/browsing/bin/postactivate
As documented in the django-pytest documents, one may set
$DJANGO_SETTINGS_MODULE by exporting it in the postactivate
script for virutalenv.
export DJANGO_SETTINGS_MODULE=automated_browsing.settings
At terminal cli:
As expected, $DJANGO_SETTING_MODULE is defined.
# activate the virtualenv
In: workon browsing
In: echo $DJANGO_SETTINGS_MODULE
Out: automated_browsing.settings
As expected, the settings module is set as shown when the server runs:
# cd into django project
In: cd ../my_django/automated_browsing
# see if server runs
In: python manage.py runserver
Out: # output
Validating models...
0 errors found
September 02, 2014 - 10:45:35
Django version 1.6.6, using settings 'automated_browsing.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
In: ^C
As NOT expected, py.test cannot find it.
In: echo $DJANGO_SETTINGS_MODULE
Out: automated_browsing.settings
In: py.test tests/test_browser.py
Out: …
_pytest.config.UsageError: Could not import settings
'automated_browsing.settings'
(Is it on sys.path? Is there an import error in the settings file?)
No module named automated_browsing.settings
installed packages
Django==1.6.6
EasyProcess==0.1.6
PyVirtualDisplay==0.1.5
South==1.0
argparse==1.2.1
ipython==2.2.0
lxml==3.3.6
psycopg2==2.5.4
py==1.4.23
pytest-django==2.6.2
pytest==2.6.1
selenium==2.42.1
test-pkg==0.0
wsgiref==0.1.2
Had the same problem today. In the project/settings/ you have to create init.py . Like this django recognize the folder.
In my case I just typed __inti__.py which was wrong. I corrected inti.py --> init.py and it works fine.
Hope it helps.
V.
Inspired by this answer, I have solved my problem.
According to the django-pytest documentation for managing the python path:
By default, pytest-django tries to find Django projects by
automatically looking for the project’s manage.py file and adding its
directory to the Python path.
I assumed that executing py.test tests/test_browser.py inside of the django project containing manage.py would handle the PYTHONPATH. This was an incorrect assumption in my situation.
I added the following to .virtualenv/$PROJECT/bin/postactivate:
export PYTHONPATH=$PYTHONPATH:$HOME/development/my_python/my_django/automated_browsing
And now py.test works as expected.

How to see which tests were run during Django's manage.py test command

After tests execution is finished using Django's manage.py test command only number of passed tests is printed to the console.
(virtualenv) G:\Project\>python manage.py test
Creating test database for alias 'default'...
True
..
----------------------------------------------------------------------
Ran 2 tests in 0.017s
OK
Destroying test database for alias 'default'...
Is there any way to see:
which tests were actually executed
from what module
in what order
I haven't found any solution in the doc.
You can pass -v 2 to the test command:
python manage.py test -v 2
After running this command you'll get something like this (I'm using django 2, feel free to ignore migrations/database stuff):
Creating test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
Operations to perform:
Synchronize unmigrated apps: messages, staticfiles
Apply all migrations: admin, auth, contenttypes, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying contenttypes.0001_initial... OK
...
Applying sessions.0001_initial... OK
System check identified no issues (0 silenced).
test_equal_hard (polls.tests.TestHard) ... ok <--------+
test_equal_simple (polls.tests.TestSimple) ... ok <--------+
|
|
That's your tests! >----------------------------+
By the way, v stands for verbosity (You can also use --verbosity=2):
python manage.py test --verbosity=2
Here's the excerpt from the python manage.py test --help:
-v {0,1,2,3}, --verbosity {0,1,2,3}
Verbosity level; 0=minimal output, 1=normal output,
2=verbose output, 3=very verbose output
Nigel's answer is great and definitely the lowest barrier to entry option. However, you can get even better feedback with django_nose (and it's not that difficult to setup ;).
The below is from: BDD with Python
First: install some requirements:
pip install nose pinocchio django_nose
Then add the following to settings.py
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
NOSE_ARGS = ['--with-spec', '--spec-color']
Then run your tests as per normal:
python manage.py test
Output should look something like this:
Note: The comments under your tests can be used to give even better output than just the name.
e.g.:
def test_something(self):
"""Something should happen"""
...
Will output "Something should happen" when running the test.
For extra points: You can also generate / output your code coverage:
pip install coverage
Add the following to your NOSE_ARGS in settings.py: '--with-coverage', '--cover-html', '--cover-package=.', '--cover-html-dir=reports/cover'
e.g.:
NOSE_ARGS = ['--with-spec', '--spec-color',
'--with-coverage', '--cover-html',
'--cover-package=.', '--cover-html-dir=reports/cover']
Then you'll get a nice code-coverage summary when you run python manage.py test as well as a neat html report in reports/cover

Categories

Resources