How to test IPython magic with nosetests - python

I use nosetests for unit testing so as team, developing IPython. There are tests for built-in magic functions https://github.com/ipython/ipython/blob/master/IPython/core/tests/test_magic.py
The problem is that writing tests as usual, when I try to initiate IPython with something like
from IPython import get_ipython
ip = get_ipython()
ip.register_magics(MyMagic)
nosetests fail with error that 'NoneType' object has no attribute 'register_magics'. This is because get_ipython() returns None.
In IPython tests some custom plugins solve the problem. Command iptest runs IPython tests, including magics. The problem is I don't understand how exactly should I run test, or where the plugin is located and how to modify it for custom magic testing. Any help will be appreciated
P.S.: I also tried to use InteractiveShellEmbed(), but it does not work as expected.

For now this may be done by calling from terminal:
PYTHONPATH=<path/to/folder/with/test> iptest <file_with_tests_without_py>

Related

ModuleNotFoundError when running unittest with subprocess

I'm writing tests in python's unittest and decided to use the module parameterized to deal with test parameterization. Now all's fine and dandy when I'm running tests directly with unittest's CLI - simply running python -m unittest in root directory launches all the tests as expected. However, I decided for my script to have it's own command flag to run the tests, so when you run, say, python ./main.py -t [additional arguments for unittest], the script itself runs python -m unittest [additional arguments for unittest]. For that to happen, I'm using subprocess.run. And this also works... well, to some extent. The problem is the following - when I'm using python -m unittest, no errors (except for the ones being tested) are raised, but using my script to run the tests raises ModuleNotFoundError: No module named 'parameterized', along with a few other dependencies my code is using. I'm clueless why is that happening.
To be honest I'm not that familiar with unittest, so maybe my approach is the problem, maybe I should handle this in completely different way. Any feedback would be much appreciated.

Pycharm is not letting me run my script 'test_splitter.py' , but instead 'Nosetests in test_splitter.py'?

I see many posts on 'how to run nosetests', but none on how to make pycharm et you run a script without nosetests. And yet, I seem to only be able to run or debug 'Nosetests test_splitter.py' and not ust 'test_splitter.py'!
I'm relatively new to pycharm, and despite going through the documentation, I don't quite understand what nosetests are about and whether they would be preferrable for me testing myscript. But I get an error
ModuleNotFoundError: No module named 'nose'
Process finished with exit code 1
Empty suite
I don't have administartive access so cannot download nosetests, if anyone would be sugesting it. I would just like to run my script! Other scripts are letting me run them just fine without nosetests!
I found the solution: I can run without nosetests from the 'Run' dropdown options in the toolbar, or Alt+Shift+F10.
It is probably because you are using an interpreter which doesn't have the nosetests installed.
You can configure your project interpreter from: File > Settings > Project Interpreter

Run pytest in PDB with pipenv

I saw this question: Can I debug with python debugger when using py.test somehow? but it doesn't really help, because I need to debug hooks, some of them not written by me, where modifying the code of the hook is really cumbersome.
Also, pytest runs through pipenv run. It's already difficult to make them both work together. I couldn't so far find a combination of pdb, pipenv and pytest that would launch each other.
Another way I could do it is by calling pytest.main() from my code, however, this means that other people who want to run my tests will have to use this "trampoline" to run other tests. I can live with this, but it still feels like it shouldn't be necessary.
I guess this is what you need, invoke pdb as early as possible:
`pipenv --py` -c 'import pdb, pytest; pdb.set_trace(); pytest.main()'

How to run arbitrary code when django shell starts?

This question: Automatically import models on Django shell launch has answers explaining how to import models upon start by using shell_plus, but no answer about how to run code in general.
But is there an easy way to just run a python script?
python manage.py shell [or shell_plus] --run=script.py
Would just run the script as if you'd typed the whole thing in as the shell started.
I realize that you can import things in the shell, but then they're stuck within a namespace.
I would think ipython should have a way to run a script, and then import its locals() into the toplevel namespace. In that case you could just do %magic script.py and we'd be down to just one step, which would be good.
Changing the way you start the shell should be fine - the main goal is to just be able to create a file that's run on startup of the shell.
You can create your own custom command just like shell_plus has done: see the source of the shell_plus command to see how. In that code you can specify and run the file that needs to be executed before starting the shell. Also useful is Django's documentation on creating custom commands.
You can try to use environment variable PYTHONSTARTUP.
Also try django-extensions: django-extensions
See django-extensions/management/commands/shell_plus.py command.
From source code of this command I see that it respects PYTHONSTARTUP env variable.
shell_plus uses a limited form of IPython which doesn't process its startup & configuration, which defeats most normal attempts to run things at django+ipython shell startup. You can switch it to use the full version which will solve most problems.
Modify django_extensions/management/commands/shell_plus.py
remove:
embed(user_ns=imported_objects)
and replace it with:
from IPython import start_ipython
start_ipython(argv=[], user_ns=imported_objects)
Then your python code in the startup directories will be loaded.
Not sure if there's a flag you can use, but if you have ipython installed it should be as simple as:
ipython
Then when you're in the prompt:
run script.py
Then:
run manage.py shell
It seems that the easiest way is to run
cat myscript.py | awx-manage shell
For reference, see https://github.com/ansible/awx-operator/blob/7d2d1b3c5e3766966bfec0f9f58037f654b93b59/roles/installer/tasks/initialize_django.yml#L21-L24

How to use `pytest` from Python?

I'm working in a project that recently switched to the pytest unittest framework. I was used to calling my tests from Eclipse, so that I can use the debugger (e.g. placing breakpoints to analyze how a test failure develops). Now this is no longer possible, since the only way to run the tests is via the command line blackbox.
Is there some way to use pytest from within Python, so that one is not forced to drop out of the IDE? The tests should of course not be run in a separate process.
I think I can now answer my own question, it's pretty simple:
import pytest
pytest.main(args)
which is documented in the Section "Calling pytest from Python code".
Then I can run this module and/or start it with the integrated debugger.
args is the list of command-line arguments, so for example to run only particular tests I can use something like:
args_str = "-k test_myfavorite"
args = args_str.split(" ")
pytest.main(args)
It seems that now (py.test version 2.0+) someone can also do this :
import pytest
pytest.main('-x {0}'.format(argument))
# Or
# pytest.main(['-x', 'argument'])
Ref
This is now supported by pytest and described nicely in the documentation.
You can invoke pytest from Python code directly:
import pytest
pytest.main()
this acts as if you would call “pytest” from the command line. It will not raise SystemExit but return the exitcode instead. You can pass in options and arguments:
pytest.main(["-x", "mytestdir"])
For me it was this:
pytest.main(["-x", "path to test file", "args"])
For example:
import pytest
pytest.main(["-x", "/api/test", "-vv"])
Maybe you could give a try to pycharm it has direct integration with py.test (I use it at work) and debugger runs perfectly.
I have not tried with eclipse, but as was suggested in a related question, it is possible to use the --pdb command line option with py.test. Maybe it is possible to configure eclipse that way.
However, calling the standard import pdb;pdb.set_trace() will not directly call the debugger. First it will issue an error which in turn will activate the debugger. This might or might not make things work differently.
You can just run py.test --pdb if you just want to a debugger and don't need the IDE

Categories