Pytest runs tests twice in the specific configuration - python-2.7

I started to use pytest.
I created testing environment:
When I run pytest with different options everything works well. For example in pytest.ini:
addopts = -rxs --full-trace -v --color=yes --durations=3 --junit-xml="c:\tmp\log.xml"
But when I want to run test by nodeID, for example:
addopts = -vv Unit/Flows/test_my1.py::TestClass1
pytest runs tests twice.
How can I avoid this?

Related

Django Running Particular Test

In My Project more than one test file and if i run
python manage.py tests
It takes huge time to complete the test and i don't want this way.
I want only run particular file of test like i have test
project/todo/tests/test_todo.py
project/accounts/tests/test_signup.py
project/todo/tests/test_archive.py
and lots more like above these:
Now i want to run only project/todo/tests/test_todo.py How can i do it?
you can simply do python manage.py test project.todo.tests.test_todo. Observe the difference here instead of giving it as a file, you can give it as a package. If you want to run a particular test case in a test suite, you can go ahead in the same way. python manage.py test project.todo.tests.test_todo.TestSuiteClass.TestCase.
You can run a particular test by using the following command.
python manage.py test -nk appname.test_folder.test_file
-n, --nomigrations Tells Django to NOT use migrations and create all
tables directly.
-k, --keepdb Preserves the test DB between runs.

What Django TEST_RUNNER supports xunit xml and logging capture?

I'm attempting to set up a new django project, and I've configured TEST_RUNNER in settings.py to be django_nose.NoseTestSuiteRunner.
I chose this test runner because it seems to be the only one I can find that has the following features:
writes xunit xml test report
captures logging/stdout and only displays for failed tests.
However I've heard that nose is unmaintained and I'm having a hard time finding a suitable replacement. The standard test runner doesn't capture logging nor writes xunit as far as I'm able to tell (would love to be proven wrong!)
I run tests like so:
python -m coverage run manage.py test --noinput
python -m coverage report --include="app/*" --show-missing --fail-under=100
python -m coverage xml --include="app/*" -o ./reports/coverage.xml
With this in settings.py:
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
And this setup.cfg:
[nosetests]
verbosity=0
with-xunit=1
xunit-file=./reports/xunit.xml
logging-clear-handlers=1
The last two lines are the real juicy bits I can't seem to find in other test runners. nose captures the logging and clears other logging handlers (eg, the handler that dumps on stdout) so the test runs output is much cleaner (you only see logging for tests that failed).
In other non-django projects I typically use nose2 but django-nose2 project appears to be 6 years old and lacking python3 support??
Please let me know which test runner is the "recommended" one (eg, most popular) with django support, thanks.
I have had success with unittest-xml-reporting:
TEST_RUNNER = 'xmlrunner.extra.djangotestrunner.XMLTestRunner'
https://github.com/xmlrunner/unittest-xml-reporting#django-support
The output directory can be configured with the TEST_OUTPUT_DIR setting.
You may still use nose runner:
INSTALLED_APPS += ['django_nose']
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
NOSE_ARGS = [
'--with-xunit',
'--xunit-file=nosetests.xml',
'--with-coverage',
'--cover-erase',
'--cover-xml',
'--cover-xml-file=nosecover.xml',
]
So pytest produces some very nice test output. I've unset TEST_RUNNER in settings.py and changed my test script to:
python -m coverage run -m pytest --junitxml=./reports/junit.xml
python -m coverage report --include="app/*" --show-missing --fail-under=100
python -m coverage xml --include="app/*" -o ./reports/coverage.xml
This works, and captures ALL logging output (nose was a little buggy and let one or two logging statements slip through, very strange behavior).
The only thing is that I'm a django novice so I don't know if there are any bad side-effects of not using manage.py test for testing django. Any guidance is appreciated, thanks!

Configure a django test with no migrations in pyCharm

I am new to both django and pycharm! I can run the tests in my code on terminal using:
python manage.py test Repo/tests/testUnit1.py --failfast -n
and it works! Recently, I tried to use pycharm (professional) to run and debug the tests. The problem is that when I specify the option --nomigrations it gives the following error:
Usage: /Applications/PyCharm.app/Contents/helpers/pycharm/django_test_manage.py test [options]
[path.to.modulename|path.to.modulename.TestCase|path.to.modulename.TestCase.test_method]...
Discover and run tests in the specified modules or the current directory.
/Applications/PyCharm.app/Contents/helpers/pycharm/django_test_manage.py: error: no such option: --nomigrations
I found similar question here but it suggests the same thing that I have already tried. Does this happen because the test unit and the code that I want to test are not in the same folder? How can I run a test in pycharm without migrations?
In case this saves someone else some time here is how to set it up (took me awhile to figure out the first couple steps)...
Select Edit configurations
Create a new Python configuration (not a Django tests configuration)
In Script put manage.py
In Script parameters put test --nomigrations <optional test labels>
Optionally may need to specify a Working directory, depending on how PyCharm is started
As always, make sure your Environment variables, Python interpreter and Interpreter options are set to your project
This is on PyCharm 2016.2.3 and Django 1.8.9 with django-test-without-migrations installed
I figured out my mistake. I edited Python Run/Debug configuration and passed manage.py to Script. Also, I pasted the path that I used to use on command terminal (plus --failfast -n at the end) in Script parameters and it starts working!
Rather than use the configuration menu, I just edit the source.
You'll see when running tests that PyCharm that it uses its work test runner, something like
/Applications/PyCharm.app/Contents/helpers/pycharm/django_test_manage.py
Opening it up, I add the functional part that's taken from django-test-without-migrations
# added this class
class DisableMigrations(object):
def __contains__(self, item):
return True
def __getitem__(self, item):
return "notmigrations"
# ... right before this built-in
class PycharmTestCommand(Command):
def get_runner(self):
TEST_RUNNER = 'django_test_runner.run_tests'
test_path = TEST_RUNNER.split('.')
#....
Then, inside of the PycharmTestCommand.handle() method:
def handle(self, *test_labels, **options):
# Add this line
settings.MIGRATION_MODULES = DisableMigrations()
# That's it!
# ....
Now it works on all your projects, whether or not they have that lib installed. I still install the lib in case I need to run tests outside of PyCharm.

One summary for multiple test files using python unittest

I wanna make automated testing for my python project but I'm not sure about the correct way to use unittest module.
All of my test files are currently in one folder and have this format:
import unittest
class SampleTest(unittest.TestCase):
def testMethod(self):
# Assertion here
if __name__ == "__main__":
unittest.main()
Then I run
find ./tests -name "*_test.py" -exec python {} \;
When there are three test files, it outputs
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
It printed one summary for each test file. So the question is what can I do to make it print only one test summary, eg Ran 5 tests in 0.001s?
Thanks in advance
And I don't want to install any other module
You are invoking Python multiple times, and each process does not have any knowledge about rest of them. You need to run Python once and use unittest discover mechanism.
Run in shell:
python -m unittest discover
Depending on what is your project structure and naming conventions you may want to tweak discovery params, e.g. change --pattern option, as described in help:
Usage: python -m unittest discover [options]
Options:
-h, --help show this help message and exit
-v, --verbose Verbose output
-f, --failfast Stop on first fail or error
-c, --catch Catch Ctrl-C and display results so far
-b, --buffer Buffer stdout and stderr during tests
-s START, --start-directory=START
Directory to start discovery ('.' default)
-p PATTERN, --pattern=PATTERN
Pattern to match tests ('test*.py' default)
-t TOP, --top-level-directory=TOP
Top level directory of project (defaults to start
directory)
While you said I don't want to install any other module, I'd still recommend using another test runner. There are quite few out there, pytest or nose to name a few.

PhantomJS Ghostdriver and Nose --with-id

I am working with Selenium tests in python using Nose as a test runner. I run my tests like so
nosetests -a level=gold --with-id --with-xunit
Once tests are done, I usually run
nosetests --failed
So far we have run tests using FireFox and Chrome webdrivers with no issues. It is not uncommon for one or two tests to fail (as our website is undergoes frequent builds, which causes tests to briefly fail), and only these tests are retried.
When I use PhantomJS's Ghostdriver, behavior is similar to Chrome/FF as one or two tests fail. But when I run nosetests --failed ALL tests are rerun, not just the failed ones.
webdriver setup a such:
self.driver = webdriver.PhantomJS(executable_path='C:\\SeleniumTests\\phantomjs.exe')
nosetest.xml on the first pass with phantomjs outputs
<?xml version="1.0" encoding="UTF-8"?><testsuite name="nosetests" tests="37" errors="1" failures="0" skip="0">
but on the second pass all 37 tests are rerun.
Is this a known issue with Ghostdriver? Or is there some something I am missing?