Running pytest in VS code when needing to load modules beforehand - python

I am trying to use pytest within VS code, running in red hat linux. The environment that I am using means that I need to load modules such as pandas before running pytest. In the terminal I can run:
module load pandas
pytest
and the tests are successfully run. I can do this in both the standard terminal, in the Python Debug Console within VS code, and int he bash terminal within VS code. If, however, I press the "Run All Tests" button within VS code, then I just get an error telling me that it cannot find the pandas module.
How can I tell the test environment to run my module load pandas command before running pytest?

In this case I would create a file named conftest.py in the directory containing the tests. pytest automatically executes this file before the tests are run. In this file you could have Python execute shell commands. For the latter there are different options, but first try one of the easier ones.
More information on conftest.py:
In pytest, what is the use of conftest.py files?

Related

Execute pytest from another python script within docker

I have a test script written using pytest and it works fine when I execute it as standalone.
User:~my_workspace/python_project$ pytest path_to_script/my_script.py
Now I have to run this script with different parameters and hence I have created a python file (script_to_invoke_pytest.py) so that I can run the pytest script from this python file.
I tried below approaches within my script_to_invoke_pytest.py
#approach 1
import subprocess
subprocess.Popen(['pytest', r'path_to_script/my_script.py'], shell=True)
#approach 2
import pytest
pytest.main([r'path_to_script/my_script.py'])
Both the approaches didn't work and I get errors related no modules named xyz.
Im using pycharm ide and before running pytest, I execute the docker.
Please let me know how can I invoke my pytest from my python script script_to_invoke_pytest.py
In your second approach, you're not telling python where to find the tests. Try:
import pytest
pytest.main([r'path_to_script/my_script.py'])

Get pytest traceback for non-test modules

The traceback provided by pytest is great and super useful for debugging.
Is there a way to run a script using the pytest api even if the script itself does not contain any test modules? Essentially, I would like a way to pinpoint and run a certain function in a script as if it were a test, but get the pytest-formatted traceback.
The pytest documentation on test discovery states that normally only functions whose name begins with test_ are run. This behaviour can be changed however with the python_functions configuration option. Try entering in the command line:
pytest [script.py] -o python_functions=[script_function]
in which you should replace [script.py] with your python script file path and replace [script_function] with the name of the function that you want to be run.

Run single test using Python Unittest in Visual Studio Code Debug mode

I use the pylint extension in Visual Studio Code within the Debug module (see image) to run my tests using Python Unittest library.
Whenever I run my tests, I execute my test.py file in Debug and it runs all of the tests in the entire file. I have my tests broken up logically by classes with several tests per class.
To reduce the time it takes evaluate test results for a single test I am actively working on, is there a way to execute just that one test rather than wait for all the tests in the test.py file to execute while in VS Code Debug mode?
For example:
test.py
import unittest
class test_TestClass(unittest.TestCase):
def test_Test1(self):
x = 1
self.assertEqual(x, 1)
def test_Test2(self):
y = 2
self.assertEqual(y, 3)
If I want to only execute test_Test2() to make sure that it fails, how do I do that without running the entire file (i.e., test_Test1 and test_Test2)?
When your tests are discovered by Python: Run All Unit Tests (or clicking on the Run Tests button in the status bar and choosing Discover Unit Tests), a code lens is provided to run individual test functions, methods, and classes either normally or under the debugger.
Clicking on Debug Test will run open the debugger and run the unit test under it. Otherwise you can modify your launch.json to add a debug configuration and specify the arguments to your test runner to just run the test(s) you're interested in.

Using pytest, is it possible for a unit test to know that it is being run with code coverage monitoring on?

I am currently developing some tests using python py.test / unittest that, via subprocess, invoke another python application (so that I can exercise the command line options, and confirm that the tool is installed correctly).
I would like to be able to run the tests in such a way that I can get a view of the code coverage metrics (using coverage.py) for the target application using pytest_cov. By default this does not work as the code coverage instrumentation does not apply to code invoked with subprocess.
Code Coverage of the code does work if I update the tests to directly invoke the entry class for the target application (rather than running via the command line).
Ideally I want to have a single set of code which can be run in two ways:
If code coverage monitoring is not enabled then use command line
Otherwise execute the main class of the target application.
Which leads to my question(s):
Is it possible for a python unit test to determine if it is being run with code coverage enabled?
Otherwise: is there any easy way to pass a command line flag from the pytest invocation that can be used to set the mode within the code.
Coverage.py has a facility to automatically measure coverage in sub-processes that are spawned: http://coverage.readthedocs.io/en/latest/subprocess.html
Coverage sets three environment flags when running tests: COV_CORE_SOURCE, COV_CORE_CONFIG and COV_CORE_DATAFILE.
So you can use a simple if-statement to verify whether the current test is being run with coverage enabled:
import os
if "COV_CORE_SOURCE" in os.environ:
# do what yo need to do when Coverage is enabled

Setting startup script in PyCharm debugger console

In PyCharm, it is possible to set a script that runs upon opening a new console (through Settings -> 'Build, Execution, Deployment' -> Console -> Python Console -> Starting script).
Is there a way to similarly apply a startup script to the debugger console? I find myself importing the same packages over and over again, each time I run the code.
When you run Python Console inside PyCharm, it executes custom PyCharm script at <PYCHARM_PATH>/plugins/python/helpers/pydev/pydevconsole.py.
On the other hand, when you run PyCharm Debug Console while debugging, it executes custom PyCharm script at <PYCHARM_PATH>/Plugins/python/helpers/pydev/pydevd.py with command line parameter --file set to script you are debugging.
You can modify pydevd.py file if you want (Apache 2 license), but the easier approach would be to create startup script in which you import modules you need, functions and such and import ALL while inside PyCharm Debug Console. This would reduce all your imports to one.
Walkthrough:
Let's create 2 files:
main.py - Our main script which we will debug
startup.py - Modules, functions or something else that we would like to import.
main.py content:
sentence = 'Hello Debugger'
def replace_spaces_with_hyphens(s):
return s.replace(' ', '-')
replace_spaces_with_hyphens(sentence) # <- PLACE BREAKPOINT!
When breakpoint is hit, this is what we have inside scope:
If you always find yourself importing some modules and creating some functions, you can define all that inside startup.py script and import everything as from startup import *.
startup.py:
# Example modules you always find yourself importing.
import random
import time
# Some function you always create because you need it.
def my_imported_function():
print("Imported !")
Inside Python Debugger Console, use from startup import * as mentioned above and you would see all modules and function inside scope, ready for use.
you could just create a new debug configuration (run > edit configurations) and point it to a script in your project (e.g. called debug.py that you gitignore). Then when you hit debug it will run that script and drop you into a console.
Personally, I prefer to just launch ipython in the embedded terminal than using the debug console. On linux, you can create a bash alias in your .bashrc such as alias debug_myproject=PYTHONSTARTUP=$HOME/myproject/debug.py ipython. Then calling debug_myproject will run that script and drop you into an ipython console.

Categories

Resources