I'm using GNU Emacs 24.5.1 to work on Python code. I often want to run just a single unit test. I can do this, for example, by running:
test=spi.test_views.IndexViewTest.generate_select2_data_with_embedded_spaces make test
with M-X compile. My life would be simpler if I could give some command like "Run the test where point is", and have emacs figure out the full name of the test for me. Is possible?
Update: with the folowing buffer, I'd like some command which runs M-X compile with:
test=spi.test_views.IndexViewTest.test_unknown_button make test
where spi is the name of the directory test_views.py is in. Well, technically, I need to construct the python path to my test function, but in practice, it'll be <directory.file.class.function>.
This seems like the kind of thing somebody would have already invented, but I don't see anything in the python mode docs.
I believe you use the "default" python mode, while the so-called elpy mode (that I strongly recommend giving a try when doing Python developments within Emacs) seems to provide what you are looking for:
C-c C-t (elpy-test)
Start a test run. This uses the currently configured test runner to discover
and run tests. If point is inside a test case, the test runner will run exactly
that test case. Otherwise, or if a prefix argument is given, it will run all tests.
Extra details
The elpy-test function internally relies on the function (elpy-test-at-point), which appears to be very close to the feature you mentioned in the question.
See e.g. the code/help excerpt in the following screenshot:
Related
When a script is invoked explicitly with python, the argv is mucked with so that argv[0] is the path to the script being run. This is the case if invoked as python foo/bar.py or even as python -m foo.bar.
I need a way to recover the original argv (ie. the one received by python). Unfortunately, it's not as easy as prepending sys.executable to sys.argv because python foo/bar.py is different than python -m foo.bar (the implicit PYTHONPATH differs, which can be crucial depending on your module structure).
More specifically in the cases of python foo/bar.py some other args and python -m foo.bar some other args, I'm looking to recover ['python', 'foo/bar.py', 'some', 'other', 'args'] and ['python', '-m', 'foo.bar', 'some', 'other', 'args'], respectively.
I am aware of prior questions about this:
how to get the ORIGINAL command line in python? with spaces, tabs, etc
Full command line as it was typed
But these seem to have a misunderstanding of how shells work and the answers reflect this. I am not interested in undoing the work of the shell (eg. evaluated shell vars and functions are fine), I just want to get at the original argv given to python.
The only solution I've found is to use /proc/<PID>/cmdline:
import os
with open("/proc/{}/cmdline".format(os.getpid()), 'rb') as f:
original_argv = f.read().split('\0')[:-1]
This does work, but it is Linux-only (no OSX, and Windows support seems to require installing the wmi package). Fortunately for my current use case this restriction is fine. But, it would be nice to have a cleaner, cross platform approach.
The fact that that /proc/<PID>/cmdline approach works gives me hope that python isn't execing before it runs the script (at least not the syscall exec, but maybe the exec builtin). I remember reading somewhere that all of this argument handling (ex. -m) is done in pure python, not C (this is confirmed by the fact that python -m this.does.not.exist will produce an exception that looks like it came from the runtime). So, I'd venture a guess that somewhere in pure python the original argv is available (perhaps this requires some spelunking through the runtime initialization?).
tl;dr Is there a cross platform (builtin, preferably) way to get at the original argv passed to python (before it remove the python executable and transforms -m blah into blah.py)?
edit From spelunking, I discovered Py_GetArgcArgv, which can be accessed via ctypes (found it here, links to several SO posts that mention this approach):
import ctypes
_argv = ctypes.POINTER(ctypes.c_wchar_p)()
_argc = ctypes.c_int()
ctypes.pythonapi.Py_GetArgcArgv(ctypes.byref(_argc),
ctypes.byref(_argv))
argv = _argv[:_argc.value]
print(argv)
Now this is OS-portable, but not python implementation portable (only works on cpython and ctypes is yucky if you don't need it). Also, peculiarly, I don't get the right output on Ubunutu 16.04 (python -m foo.bar gives me ['python', '-m', '-m']), but I may just be making a silly mistake (I get the same behavior on OSX). It would be great to have a fully portable solution (that doesn't dig into ctypes).
Python 3.10 adds sys.orig_argv, which the docs describe as the arguments originally passed to the Python executable. If this isn't exactly what you're looking for, it may be helpful in this or similar cases.
There were a bunch of possibilities considered, including changing sys.argv, but this was, I think, wisely chosen as the most effective and non-disruptive option.
This seems XY problem and you are getting into the weeds in order to accommodate some existing complicated test setup (I've found the question behind the question in your comment). Further efforts would be better spent writing a sane test setup.
Use a better test runner, not unittest.
Create any initial state within the test setup, not in the external environment before entering the Python runtime.
Use a plugin for the randomization and seed stuff, personally I use this one but there are others.
For example if you decide to go with pytest runner, all the test setup can be configured within a [tool.pytest.ini_options] section of the pyproject.toml file and/or with a fixture defined in conftest.py. Overriding the default test configuration can be done with environment variables and/or command line arguments, and neither of these approaches will get mucked around by the shell or during Python interpreter startup.
The manner in which to execute the test suite can and should be as simple as executing a single command:
pytest
And then your perceived problem of needing to recover the original sys.argv will go away.
Your stated problem is:
User called my app with environment variables and arguments.
I want to display a "run like this" diagnostic that will exactly reproduce the results of the current run.
There are at least two solutions:
Abandon the "reproduction" aspect, since the original bash calling command is lost to the portable python app, and instead go for "same effect".
Use a wrapper to capture the original calling command, as suggested by Jean-François Fabre.
With (1) you would be willing to accept ['-m', 'foo'] becoming ['foo.py'], or even turning it into ['/some/dir/foo.py'] in case PYTHONPATH could cause trouble. Displaying ['a', 'b c'] as "a" "b c", or more concisely as a "b c", is straightforward. If environment variables like SEED are an important part of the command line interface then you'll need to iterate over envp and output them, as well. For true reproducibility, you might choose to convert input args to canonical form, compare with observed input args, and exec using the canonical form if they're not identical, so there's no way to execute the bulk of your code using "odd" syntax.
With (2) you would bury the app in some inconveniently named file, advertise the wrapper program far and wide, and enjoy the benefits of seeing args before they're munged.
I am trying to use PyCharm for unit testing (with unittest), and am able to make it work: the test runner nicely shows the list of test cases and nested test functions.
However, once the tests have been discovered, I cannot find any way to (re)run a specific test function: the only button available will run the whole list of tests, and right clicking on a single test function doesn't show any meaningful action for this purpose.
As you can imagine, it can take a long time unnecessarily when the purpose is to debug a single test.
How to achieve this? It is possible in Visual Studio for example, and seems like a basic feature so I assume I must be missing something.
Check the default test framework of the project...
You're perhaps used to 'unittest' being the default. Its enables me to put the cursor on the test definition and hit "SHIFT-CTRL-R" to run that one test.
The default seems to have changed to 'py.test' which has different behaviour and keyboard shortcuts. I'm on OSX so ymmv.
On Linux:
File -> Settings -> Tools -> Python Integrated Tools -> Testing / "Default Test Runner"
On OSX:
Preferences -> Tools -> Python Integrated Tools -> "Default test runner:"
With recent versions of PyCharm the availability of the 'right click' option seems intermittent.
One replacement is to go to Edit Configurations... and type the name of the class and method yourself. That's worked well for me, even if not quite as convenient
Under pycharm 2017.2.3:
the key step:
change the default test runner(unittests) to (nosetests or py.test), both ok.
then the IDE can run single test function now.
follow the steps of the below screenshots.
1. change settings:
2. run single test function:
3. run all test functions:
In Pycharm 2018.1: restart, delete the existing run configrations - suddently right-click provides an option to run a single test. :-/
Have you tried right clicking the test in the actual class? It should be possible to run the single test from there. I'd suggest a re-install if this is not available.
Please check whether you have the same test name repeated in two or more locations in the test fixture. I had the same problem and resolving the naming conflicts enabled me to right click on the test name and run it individually.
I had this problem with PyCharm 2018.3.
It seemed to be because I had a breakpoint in a strange place (at function declaration, instead of inside the function).
Clearing all the breakpoints seemed to restore the ability to debug individual tests
While writing an application parsing command line arguments I would like to run it with various parameters.
I don't want to create a Run Configuration for every possible command line argument that I want my script to test with. Is there a way in PyCharm (and I guess with any JetBrains IDE) to make a Run Configuration that asks for the Script parameters when executed?
I am currently using PyCharm 3.1 (EAP).
Currently the only possibility is to use the "Before launch | Show this page" option.
I've found today that now is possible to ask for parameters using the "Prompt" macro on the "Run configuration" parameters field.
https://www.jetbrains.com/help/pycharm/code-running-assistance-tutorial.html#parameter-with-macros
Although yole's answer is the de facto way to be prompted for thw arguments before running a program, it is slightly annoying because:
the dialog is visually overwhelming and cluttered instead of focused on what you want to do;
you have to tab to reach the arguments field if you want to use the keyboard exclusively (and why not?);
Nothing you could do about that. (Except maybe file a ticket. Have you done that?)
I'm just adding what I used to do before I knew about Googled for this option for the sake of completeness (obvously, this is a hack in the least glamorous sense of the term). But it did suit my workflow as I often only had discrete lines to test with, and didn't switch that often.
Create a new configuration set to the same file, but with a special 'magic' parameter;
Add code to your script to check if the magic is there;
Use a string variable instead of sys.argv (pass it through lambda args: [__name__] + args.split() to reduce the boilerplate);
???
Profit;
I'm doing this on a Mac, but hopefully this will be helpful for Windows or Linux.
Go to Run > Edit Configurations
There will be a dialog box that opens.
Script: file you want to run (ending with .py)
Script Parameters: the command line arguments
Working Directory: directory where your project is.
My simple answer is adding another wrapper as the cover in the source code which will run on the selection you made through code branch or external command or file, so choosing different branch is just a 'ddp' tap distance in vim(line change for parameter settings). You dont have to depend on pycharm updating by building your own code world:)
I'm working on a system that needs to be able to test python files with py.test, and use the output (what tests passed and failed) within the program. Is there anyway to call py.test from within python, tell it to run the testing code in [name].py on the code in [otherName].py, and have it return the results of the test?
I think you are looking for Calling pytest from Python code at Usage and Invocations page.
Also limiting tests to the specific file could be done by Specifying tests / selecting tests.
In other words, this should do the trick:
pytest.main(['my_test_file.py'])
P.S.: Py.test Documantation is pretty good, you can find most of the answers there ;).
I wrote a python module. Running python filename.py, only checks for syntax errors. Is there a tool, which checks for runtime errors also, like concatenating int with string etc..
Thank you
Bala
Update:
Scripts are mainly about setting up a hadoop cluster in the cloud. I am not sure how I can write a unit test, because everything runs in the cloud. You can think of code as legacy code, and I just added more logging and some extra conditions a few places
Traditionally, if not writing full-fledged unit-tests and/or doc-tests (writing lots of tests is of course best practice!), one at least puts in every module a def main(): function to exercise it and ends the module with
if __name__ == '__main__':
main()
so main() won't get in the way if the module's just imported, but it will execute if you run the module as your main script. Of course, you need to actually exercise the code in the module from within main(), for this to catch all kinds of semantic problems such as the type error you mention -- doing a really thorough job this way is often as hard as writing real unit tests and doc tests would be, but you can at least get started!
You could write a unit test for your module. That way it will execute your code and any runtime errors (or even better, test failures) will be reported.
If you choose to go down this route, http://docs.python.org/library/unittest.html would probably be a good place to start. Alternatively, as Alex wrote, you can just put code at the bottom of your module that will execute when the module is run directly. This is more expedient and probably a better first approach, although if you have a lot of modules you may want a more structured approach.
You can give a try to pyanalyze. It is able to detect possible run-time errors without running the program.
pip3 install pyanalyze
python3 -m pyanalyze file.py