In my project I created a unittest test file for each Python file. For example, I have file component.py and its accompanying test_component.py. Similarly for path.py and test_path.py, etc.
However, since these files depend on each other it is possible that a change in one file affects another, thus if I change something I need to rerun all my testfiles. For now, I have to do this manually. Is it possible to run all these test files at once with only one handling? Maybe call them from an extra file? I want however still use the testsuite as before (see the image below).
I am using Python 2.7 and JetBrains' PyCharm.
It's possible to run all tests located in some folder.
Go to Run - Edit Configurations, select or create run configuration for tests and specify path to folder.
I would recommend using Pytest.
Another alternative is to have a separate file that calls tests or instantiates classes from each test file. Based on the returns it calls the next test.
You also might have a need store information in a .txt file. You could write and read to a file that holds your test variables, conditions, etc.
Related
Obviously, the same program is run, and the code is the same. Why do two of them appear the same
When you execute scripts with the same name but different file locations or run configurations this can happen.
It can be useful in a variety of situations; where you want to run the same script in multiple different versions of python. Each Run configuration can be setup to use a separate interpreter. Though, it would be wise to rename the run configuration.
In this case, pycharm simply took the name of the script and appended (1) when it saw another run configuration of that same name already existed.
When running Pylint on my file I am getting the following message.
refactor (R0915, too-many-statements, function) Too many statements (95/50)
I want to set the number of statements a function can have to 100 instead of 50 in order avoid the above message from Pylint.
Pylint works based on configured settings which are default PEP 8 standards. Now, if customizing them is good or bad can be taken for another discussion, as they are kept like that for a reason. For example, if you have a method with more than 50 lines of code, it simply means that you are increasing the cyclomatic-cognitive complexities as well as making it difficult to unit test and get coverage.
OK, arguments aside, I think the following approach can help you customize the linting rule.
Go to your Python site-packages directory (it might be inside the Python installation Libs folder or in your virtual environment.
For example, D:\Python37\Lib\site-packages
Open a command line here, and navigate to the Pylint directory. Execute the configuration generator like
lint.py --generate-rcfile > custom_standard.rc
Now you will have a file named custom_standard.rc in the folder. Let’s copy it to some place around your project, say, D:\lint_config\custom_standard.rc.
Open the configuration file. You can see a setting for most of the rules. Now, for your question of number of statements inside a method, find the setting called
max-statements=50
Change it to:
max-statements=100
Save the configuration file. Now when you run the Pylint executable, use the option --rcfile to specify your custom configuration:
pylint --rcfile=D:\lint_config\custom_standard.rc prject_dir
If you want to integrate this with your IDE like PyCharm there are plugins which allows configuring the same.
But again!, it is not a good decision to change the PEP 8 :-)
I currently have a Python scrip that runs through all Excel files in the current directory and generates a PDF report.
It works fine now but I don't want the users to be anywhere near frozen Python scripts. I created an MSI with cxFreeze which puts the EXE and scripts in the Program Files directory.
What I would like to be able to do is create a shortcut to this executable and pass the directory the shortcut was run from to the Python program so that can be set as the working directory. This would allow the user to move the shortcut to any folder of Excel files and generate a report there.
Does Windows send the location of a opened shortcut to the executable and is there a way to access it from Python?
When you launch a shortcut, Windows changes the working directory to the directory specified in the shortcut, in the Start in field. At this point, Windows has no memory of where the shortcut was stored.
You could change the Start in field to point to the directory that the shortcut is in. But you'd have to do that for every single shortcut, and never make a mistake.
The better approach is to use a script, rather than a shortcut. Place your actual Python script (which we'll call doit.py for sake of example) somewhere in your PYTHONPATH. Then create a single-line Python script that imports it:
import doit
Save it (but don't name it doit.py) and copy it to each directory from which you want to be able to invoke the main script. In doit.py you can use os.getcwd() to find out what directory you're being invoked from.
You could also do it with a batch file. This is a little more flexible in that you can specify the exact name of the script and which Python interpreter should be used, and don't need to store the script in a directory in PYTHONPATH. Also, you don't need to worry about the file's name clashing with the name of a Python module. Simply put this line in a file:
C:\path\to\your\python.exe C:\path\to\your\script.py
Save it as (e.g.) doit.bat and copy it into the directories from which you want to invoke it. As before, your Python script can call os.getcwd() to get the directory. Or you can write it so your Python script accepts it as the first argument, and write your batch file like:
C:\path\to\your\python.exe C:\path\to\your\script.py %cd%
Another thing you can do with the batch file approach is add a pause command to the end so that the user is asked to press a key after the script runs, giving them the opportunity to read any output generated by the script. You could even make this conditional so that it only happens if an error occurs (which requires returning a proper exit code from the script). I'll leave that as an exercise. :-)
Is there a problem with modifying the script to take the directory to process as a command line argument?
You could then configure the different shortcuts to pass in the appropriate directory.
Type the following into a batch file (i.e. script.bat):
python \absolute\path\to\your\script.py %~dp0
pause
Then add these imports at the top of your python file script.py (if not already included):
import os
import sys
And add this to the bottom of the python file (or combine it with a similar statement):
if __name__ == "__main__":
# set current working directory:
if len(sys.argv) > 1:
os.chdir(sys.argv[1])
main()
replace main() with whatever function you want to call or code you want to run.
The following is how I came to my answer:
I tried using kindall's answer and had the following issues:
The first suggestion of storing the script somewhere in PYTHONPATH could not be applied to my situation because my script will be used on a server and needs to be independent of the client computer's python environment (besides having the required pip installations).
I tried calling my python script from a Windows Batch File which could be moved to a different location. Instead of the batch file's location being used as the current working directory, it was C:\Windows.
I tried passing %cd% as an argument to my python script, then setting that to be my CWD. This still resulted in a CWD of C:\Windows.
After reviewing the comments, I tried Eryk Sun's suggestion of instead passing %~dp0 as an argument to the python script. This resulted in the CWD being correctly set to the batch file's location.
I hope this helps others facing similar difficulties.
I have a test case for an algorithm, which gives a different result after the first execution.
The test imports the algorithm and the test data from two files.
The first execution returns the correct results and creates a .pyc file for the test data file.
The second and all following executions return incorrect results.
When I delete the test data's .pyc file the next execution returns the correct results again (and creates a new .pyc file again).
When I move the test data into the same file as the test case itself (i.e. avoiding the creation of a .pyc file) the test always passes.
I cannot apply this fix to my full program.
Is this a known issue, is there a fix?
.pyc files contain byte code, which is what the Python interpreter compiles the source to. This code is then executed by Python's virtual machine.
Python's documentation explains the definition like this:
Python is an interpreted language, as opposed to a compiled one,
though the distinction can be blurry because of the presence of the
bytecode compiler. This means that source files can be run directly
without explicitly creating an executable which is then run
The .pyc files are created (and possibly overwritten) only when that python file is imported by some other script. If the import is called, Python checks to see if the .pyc file's internal timestamp matches the corresponding .py file. If it does, it loads the .pyc; if it does not or if the .pyc does not yet exist, Python compiles the .py file into a .pyc and loads it.
One thing I found that changes is the value of file (.pyc vs .py), which tripped me up writing a utility invoking stack traces.
I have a python library that reads a config file or environment variables to set some global configuration variables.
I would like to run my test suite multiple times with different settings.
I could do this manually like
MYLIB_SETTINGS=enable_foo=True nosetests
MYLIB_SETTINGS=enable_foo=False nosetests
I'm wondering if there's a way to do this automatically using the nose api and combine the results.
Normally, you would run your test in some sort of Continuous Integration framework (like Jenkins) with --with-xunit and --xunit-file TEST_NAME_XXX.xml. Each test run will produce a separate xml file, and the CI tool will combine them together into a pretty table, showing all tests from both cases.
You can do something similar using nose API, by setting os.env variables appropriately in python and calling nose.run()