Python 3.7 Unit Tests - python-3.x

So I tried many things (from SO and more) getting my tests running but nothing worked this is my current code:
test.py which I call to run the tests: python3 ./src/preprocess/python/test.py
import unittest
if __name__ == '__main__':
testsuite = unittest.TestLoader().discover('.')
unittest.TextTestRunner(verbosity=2).run(testsuite)
the test file looks like this:
import unittest
from scrapes.pdf import full_path_to_destination_txt_file
print(full_path_to_destination_txt_file)
class PreprocessingTest(unittest.TestCase):
def path_txt_appending(self):
self.assertEqual(full_path_to_destination_txt_file(
"test", "/usr/test"), "/usr/test/test.txt")
if __name__ == '__main__':
unittest.main(verbosity=2)
But the output is always like this:
python3 ./src/preprocess/python/test.py
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Additional Information:
As you can see I call this not from my root directory. The test folder is in ./src/preprocess/python/test/ and has a __init__.pyfile included (there is also a init file on the level of test.py)
it would be okay for me if I have to code down all the calls for all the tests I just want to finish this
automatic search with -t does not work either so I thought the more robust method here with test.py would work...
using this framework is a requirement I have to follow
test_preprocessing.py is in the test folder and from scrapes.pdf import full_path_to_destination_txt_filescrapes is a module folder on the same level as test
When I call the single unit test directly in the command line it fails because of the relative import. But using the test.py (obviously) finds the modules.
What is wrong?

By default, unittest will only execute methods whose name starts with test:
testMethodPrefix
String giving the prefix of method names which will be interpreted as test methods. The default value is 'test'.
This affects getTestCaseNames() and all the loadTestsFrom*() methods.
from the docs.
Either change that attribute or (preferably) prefix your method name with test_.

Related

how to import a python class from different mains at different level of indentation

I am trying to structure a program with several modules as it is customary for python.
I have several modules containing classes and functions, and a usual main entry point.
Now I have built a different main that serves another (larger) purpose.
My structure is something like this:
-----main.py
|---module1
| |---subMain.py
| |---script1.py
| |---script2.py
| |---submodule1
| |---script3.py
|---module2
|---script4.py
Currently subMain.py imports all scripts from module1 with no problems.
Yet, if I try to run main.py by importing module1 files it fails.
#This works
#subMain.py
from script1 import *
#########
#script1.py
from submodule1.script3 import *
#This does not work
#main.py
#So far so good
from module1.script1 import *
#########
#script1.py
#this fails
from submodule1.script3 import *
#If I change it to the following, it works
from module1.submodule1.script3 import *
Is there a way to have script1 always work (no failure when including script3) without changing the import line?
In the end I figured the best way to do what I wanted was to build a wheel.
I need to import that same class into several projects and a wheel enables me to fix bugs only in one convenient location and reimport the de-bugged package on each project.
I actually found a workaround, maybe not the cleanest, but I got inspired by C++ #ifdef guards.
Basically I check the __name__ variable.
if __name__ == "__main__" :
from script1 import scriptObject as scriptObject
elif __name__ == "__main__" :
from module1.script1 import scriptObject as scriptObject
else :
raise Exception(f"__name__ = {__name__} is not a valid guard! Make sure project indentation is correct.")

pytest-benchmark: Run setup on each benchmark iteration

I'm trying to benchmark the bundling process of our js bundles using pytest-benchmark. For accurate processing the target directory needs to empty. I've tried cleaning this on each run using the pedantic setup argument, but this only runs on initialization of the benchmark, and not in between runs. This is the code of my last try:
import shutil
import os
import pytest
def clean_bundles():
print("Cleaning bundles")
shutil.rmtree(os.path.abspath('precompiled'), True)
def bundle(gulpfile):
os.system("gulp --gulpfile %s createBundles" % gulpfile)
def test_bundle(benchmark):
benchmark.pedantic(lambda: bundle("gulpfile.js"), setup=clean_bundles(), rounds=5, iterations=1)
Is there anyway to run a clean between each iteration without making it part of the benchmark results?

Set testing options while django doctesting

Following these posts, I have managed to run my doctest within django with:
# myapp/tests.py
import doctest
def load_tests(loader, tests, ignore):
tests.addTests(doctest.DocTestSuite())
return tests
Then running:
python manage.py tests
However, since I am used to test my (non-django) scripts with the simple command:
py.test --doctest-modules -x
I am now quite confused about:
testing procedure not stopping after first failure (my good'ol -x) (so I get flooded with results and I need to scroll back all the way up to the first problem each time)
option # doctest: +ELLIPSIS not being set by default.
How do I set this kind of options from this django load_tests() hook?
Okay, I've got it. Options flags like ELLIPSIS or FAIL_FAST can be
provided as an optionflags argument to DocTestSuite.
The right way to combine them, as reported here, is to bitwise OR them :)
So the following does work:
# myapp/tests.py
import doctest
def load_tests(loader, tests, ignore):
tests.addTests(doctest.DocTestSuite(
optionflags=doctest.ELLIPSIS | doctest.FAIL_FAST))
return tests

py.test : do something just after a test

For my tests, I build temporary files that I would like to remove whatever the result of the test is (failure or test passed).
Is there a way to "tell" to py.test to do something just after it finishes to test my Python file ?
Here is a canvas found in the official documentation.
from pytest import fixture
#fixture(scope="module")
def or_datas(request):
# Something done before a test.
def fin():
# Here, just do something after the test.
...
request.addfinalizer(fin)
# How to use it ?
def test_something(or_datas):
# Note the argument corresponding the function decorated
# by fixture.
...

Loading python modules in Python 3

How do I load a python module, that is not built in. I'm trying to create a plugin system for a small project im working on. How do I load those "plugins" into python? And, instaed of calling "import module", use a string to reference the module.
Have a look at importlib
Option 1: Import an arbitrary file in an arbiatrary path
Assume there's a module at /path/to/my/custom/module.py containing the following contents:
# /path/to/my/custom/module.py
test_var = 'hello'
def test_func():
print(test_var)
We can import this module using the following code:
import importlib.machinery
myfile = '/path/to/my/custom/module.py'
sfl = importlib.machinery.SourceFileLoader('mymod', myfile)
mymod = sfl.load_module()
The module is imported and assigned to the variable mymod. We can then access the module's contents as:
mymod.test_var
# prints 'hello' to the console
mymod.test_func()
# also prints 'hello' to the console
Option 2: Import a module from a package
Use importlib.import_module
For example, if you want to import settings from a settings.py file in your application root folder, you could use
_settings = importlib.import_module('settings')
The popular task queue package Celery uses this a lot, rather than giving you code examples here, please check out their git repository

Resources