What does this code in .cicleci/config.yml mean? - flask

My coworkers are trying to write unit test code and test API by using Circleci2.0 and Flake8. But I don't understand how I should write test code because this line pytest --flake8 in the below code does not mean.
What does this code in .cicleci/config.yml mean ?
Do we need to write test code in another xx.py file and execute this .py file like pytest xx.py?
If we should, does this line pytest --flake8 mean execution of xx.py file in another directly or the same directly even though this code dose not mention file path which execute test code file ?
- run:
name: Flake8 Check
command: |
. venv/bin/activate
pytest --flake8

You don't need to specify a filename. To quote the Pytest docs:
By default, pytest will run all files of the form test_*.py or *_test.py in the current directory and its subdirectories. More generally, it follows standard test discovery rules.

Related

How to structure unit tests in Nim?

I am looking at the unittest docs and I see that I could put multiple suite blocks in one test file.
However, I would like to have multiple test files and run them all with a single command. I could write a bash script to compile and run each script one after another:
#!/bin/bash
nim c -r test1.nim
nim c -r test2.nim
...
But is there a better way? For example in Python I can automatically discover and run all files of the form test*.py.
Put all your unit tests in a tests directory, running nimble test will run all of them.

pytest: robust file path of a txt file used in tests

During a pytest fixture, what is the best way to robustly get the location of a text file for users that may specify different working directories at runtime e.g. I want a person using the cmd line in the test fixture directory find the file as well as an integration server which may work in the project's root. Can I somehow include the text file in a module? What are best practices for including and getting access to non .py files?
I am aware of BASE_DIR = os.path.dirname(os.path.dirname(__file__)), but I am not sure if this will always refer to the same directory given a particular way of running the test suite.
os.path.dirname(os.path.abspath(__file__)) (which is what I think you meant above) worked fine for me so far - it should work as long as Python can figure the path of the file, and with pytest I can't imagine a scenario where that wouldn't be true.

nose2 vs nose test discovery (nose2 not finding tests)

I just started a python project and I'm trying out different test frameworks.
The problem I have is that nose2 does not find my tests:
$ nose2 --verbose
Ran 0 tests in 0.000s
OK
while nosetests find them all
$ nosetests --collect-only
.................................
Ran 33 tests in 0.004s
OK
Otherwhise I can execute a single test with nose2 from same directory:
$ nose2 myproj.client.test.mypkg.mymodule_test
.
Ran 1 test in 0.007s
OK
where myproj.client.test.mypkg.mymodule_test is like:
'''
Created on 18/04/2013
#author: julia
'''
from unittest import TestCase, main
import os
from myproj.client.mymodule import SUT
from mock import Mock
import tempfile
class SUTTest(TestCase):
def setUp(self):
self.folder = tempfile.mkdtemp(suffix='myproj')
self.sut = SUT(self.folder, Mock())
self.sut.init()
def test_wsName(self):
myfolder = os.path.join(self.folder, 'myfolder')
os.mkdir(myfolder)
self.sut.change_dir(myfolder)
self.assertEquals(self.SUT.name, 'myfolder')
if __name__ == "__main__":
main()
I've been looking at documentation and I cannot find a possible cause for this.
Running python 2.7.3 on MacOs 10.8.3
Adding to MichaelJCox's answer, another problem is that nose2, by default, is looking for your test file names to begin with 'test'. In other words, 'testFilePattern == test*.py' (you can find that in nose2/session.py).
You can fix this in two ways:
Specify a different test file pattern in a configuration file:
Create a configuration file somewhere in your project (the base directory is a good place, or wherever you will run nose2). nose2 will look for and load any file called nose2.cfg or unittest.cfg.
Add this to that configuration file.
[unittest]
test-file-pattern=*.py
Now run nose2 again and it'll find those old test cases. I'm unsure if this could adversely affect nose2 performance or what, but so far so good for me.
Rename your test files so that they begin with test.
For example, if you have a project like this:
/tests/
__init__.py
fluxcapacitor.py
Rename /tests/fluxcapacitor.py to /tests/test_fluxcapacitor.py, now nose2 will find the tests inside fluxcapacitor.py again.
More verbose output
Finally, this is unrelated to your question but might be helpful in the future: If -verbose doesn't output enough info, you can also pass the following additional arg --log-level debug for even more output.
It looks like nose2 needs 1 of 3 things to find the test:
Your tests need to be in packages (just create __init__.py files in each dir of your test structure)
You need a directory named 'test' in the same directory in which nose2 is being run
It needs to be in the same directory
nose2's _discovery method (in nose2.plugins.loader.discovery.py) is explicitly looking for directories named 'test' or directories that are packages (if it doesn't just pick up your test files from the same directory):
if ('test' in path.lower()
or util.ispackage(entry_path)
or path in self.session.libDirs):
for test in self._find_tests(event, entry_path, top_level):
yield test
If I set up a similar test file (called tests.py) and run nose2 in the same directory, it gives me the 1 test OK back.
If I create a directory named 'test', move the file to it, and run nose2 from the top directory, I get an error stating that it can't import my py file. Creating an __init__.py in that directory fixes that error.
If I make a directory 'blah' instead and move the file there, then I see the issue you list above:
Ran 0 tests in 0.000s
OK
However, if I then create an __init__.py in directory 'blah', the test runs and I get my 1 test found and OK'd.

What is the simplest way to make manage.py test app.TestCase work again after replacing tests.py with tests/ directory?

I have replaced project/app/tests.py with a project/app/tests/ directory. The directory contains several Python files (call them apples.py, bananas.py, etc.), each of which defines one or more classes derived from TestCase (call them TestApples, TestBananas, etc.). The file project/app/tests/__init__.py contains
from apples import TestApples
from bananas import TestBananas
The command manage.py test app still works, but manage.py test app.bananas and manage.py test app.tests.bananas do not, e.g.:
ValueError: Test label 'app.bananas' does not refer to a test
manage.py test app.tests.bananas fails with the same error, but manage.py test app.tests.bananas.TestBananas is more hopeful:
ValueError: Test label 'store.tests.bananas.TestBananas' should be of the form app.TestCase or app.TestCase.test_method
The Django docs and Python docs suggest that the solution is to write a custom test runner or test collector and plug it in; this StackOverflow question goes down the same route, then seems to recommend switching to django-nose. I'd rather not unless I have to, and I'm curious to see how to make this work with Django's standard tools. Anyone have a simple(ish) solution?
In your example, if you run manage.py test app.TestBananas then you can run that specific test.
You can get everything working by making sure all your tests are imported into __init__.py but when you have lots of tests this becomes difficult to manage. If you want to run the tests in PyCharm then django-nose isn't an option.
To make this easier we can have the test suite automatically find all tests in the tests package. Just put this in __init__.py (Be sure to replace "appname"):
def suite():
return unittest.TestLoader().discover("appname.tests", pattern="*.py")
This still won't allow us to run specific tests. To do that you'll need to add this code at the top of __init__.py:
import pkgutil
import unittest
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
module = loader.find_module(module_name).load_module(module_name)
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
exec ('%s = obj' % obj.__name__)
Now you can run all your tests via manage.py test app or specific ones via manage.py test app.TestApples
I just do this tutorial.
Edit: after django 1.6, the test discovery mechanism changed. You just have to create a folder tests with an __init__.py file inside, and put your test files there.
Your test files should match test*.py pattern.
I use django-nose! Don't be scared of packages.
Did you try renaming your test files to "test_foo.py", instead of "foo.py", for example?

How to spread django unit tests over multiple files?

I have a python-django application
I'm using the unit testing framework
The tests are arranged in the file "tests.py" in the module directory
I'm running the tests via ./manage.py test app
Now..
The tests.py file is getting rather large/complex/messy
I'd like to break tests.py up into smaller collections of tests...
How?
Note that this approach is no longer valid from Django 1.6, see this post.
You can create tests folder with ___init___.py inside (so that it becomes a package). Then you add your split test .py files there and import all of them in ___init___.py.
I.e: Substitute the test.py file with a module that looks and acts like the file:
Create a tests Directory under the app in question
app
app\models.py
app\views.py
app\tests
app\tests\__init__.py
app\tests\bananas.py
app\tests\apples.py
Import the submodules into app\tests\__init__.py:
from bananas import *
from apples import *
Now you can use ./manage.py as if they were all in a single file:
./manage.py test app.some_test_in_bananas
The behavior has changed in Django 1.6, so there is no longer a need to create a package. Just name your files test*.py.
From Django 1.7 documentation
When you run your tests, the default behavior of the test utility is
to find all the test cases (that is, subclasses of unittest.TestCase)
in any file whose name begins with test, automatically build a test
suite out of those test cases, and run that suite.
From Django 1.6 documentation,
Test discovery is based on the unittest module’s built-in test
discovery. By default, this will discover tests in any file named
“test*.py” under the current working directory.
Previous behavior, from Django 1.5 documentation:
When you run your tests, the default behavior of the test utility is
to find all the test cases (that is, subclasses of unittest.TestCase)
in models.py and tests.py, automatically build a test suite out of
those test cases, and run that suite.
There is a second way to define the test suite for a module: if you
define a function called suite() in either models.py or tests.py, the
Django test runner will use that function to construct the test suite
for that module. This follows the suggested organization for unit
tests. See the Python documentation for more details on how to
construct a complex test suite.
The answer as stated by Tomasz is correct. However, it can become tedious to ensure that the imports in __init__.py match your file structure.
To automatically detect all tests in the folder you can add this in __init__.py:
import unittest
def suite():
return unittest.TestLoader().discover("appname.tests", pattern="*.py")
This will allow you to run ./manage.py test appname but won't handle running specific tests. To do that you can use this code (also in __init__.py):
import pkgutil
import unittest
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
module = loader.find_module(module_name).load_module(module_name)
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
exec ('%s = obj' % obj.__name__)
Now you can run all your tests via manage.py test app or specific ones via manage.py test app.TestApples
Just make your directory structure like this:
myapp/
__init__.py
tests/
__init__.py
test_one.py
test_two.py
...
...
And python manage.py test myapp will work as expected.
http://docs.python.org/library/unittest.html#organizing-tests talks about splitting the files into modules, and the section right above it has an example.
With Django 2.2 a simple and fairly good solution could be to create a test folder inside an app, and you can put your related test_...py files into, just add __init__.py to the test folder.
No need to code anything in init.
Just create a subdirectory in your app. Only requirement is not to call it tests*
For exemple
app/
app/__init_.py
app/serializers.py
app/testing/
app/testing/__init__.py
app/testing/tests_serializers.py
If you have a more complicated setup, or don't want to use from ... import *-type statements, you can define a function called suite in your tests.py (or tests/__init__.py), which returns an instance of unittest.TestSuite.
I have two files. One is tests.py and another is test_api.py. I can run these individually as below.
manage.py test companies.tests
manage.py test companies.test_api
Refer #osa's response about file naming convention.
I think ./manage.py test simply does running all the tests trick (in django >= 1.7).
If your organizing tests is about grouping and cherrypicking and you are fan of nose use django nose:
python manage.py test another.test:TestCase.test_method
If you know nose, then you know how to "wildcard" much nicer over all your files.
PS
It is just a better practice. Hope that helps. The answer was borrowed from here: Running a specific test case in Django when your app has a tests directory
In django you can use below comman or can check documentation. Also using this command will pick up files with pattern you provide not just test*.py or test_*.py.
Documentation
You can specify a custom filename pattern match using the -p (or --pattern) option, if your test files are named differently from the test*.py pattern:
$ ./manage.py test --pattern="tests_*.py"
Just create different test files with tests_name in your app
Say you have following test files:
tests_admins.py
tests_staff.py
tests_others.py
# will run both test files
(venv)..yourapp$./manage.py test --keepdb -v 2 appname
Or in Windows, if you do not want to create a package (i.e folder with __init__.py) and just want to create a folder called "Tests" and this folder contains the test files then to run tests in cmd just enter
python manage.py test your_app_name/Tests
Since a path is expected