I'm using Pycharm to write tests and running them with behave. I'm running the behave commands with cli. To write the features and scenarios i'm using Pycharm. How can i debug each step?
You need Pycharm Professional to easily setup debuging. Just create run/debug configuration, choose behave framework, then specify feature files folder and behave params.
Otherwise, if you doesn't have PyCharm Professional, you can create just basic python configuration, specify module behave and enter path to your feature folders in parameters.
If you don't have PyCharm proffesional and you want to launch behave from commands, you can resort to the well-known technique of placing prints with debug information wherever you think necessary to help you solve possible errors.
For these prints to be shown in the console, you must launch the behave command with the --no-capture option. An example would be:
features/test.feature
Feature: Test
Scenario: Scenario title
Given This is one step
steps/steps.py
from behave import *
#given("This is one step")
def step_impl(context):
print("I'm executing this code??")
#given("this is other setp")
def step_impl(context):
print("or I'm executing this other code??")
ouptut of behave --no-capture features/test.feature
$ behave --no-capture features/test.feature
Feature: Test # features/test.feature:1
Scenario: Scenario title # features/test.feature:3
Given This is one step # steps/steps.py:4
I'm executing this code??
1 feature passed, 0 failed, 0 skipped
1 scenario passed, 0 failed, 0 skipped
1 step passed, 0 failed, 0 skipped, 0 undefined
Took 0m0.000s
As you can see, the print tells you exactly which step you are running. With this technique you can debug your code by printing variable values or viewing the execution flow of your code.
Related
I like using hypothesis for my unit tests. I also like using pdb for debugging when things go wrong. But trying to use these two together can be very annoying. If I set a breakpoint in a file that is run by hypothesis using pytest <PATH-TO-FILE> -s, it will stop at the breakpoint as expected, and I can do my analysis. But after I am done, I want to be able to exit out of the test. However, if I do ctrl+c from inside the breakpoint, the test doesn't quit, it simply goes to the next hypothesis test case. And I have to keep doing this until hypothesis is done generating all it's test cases.
I usually end up opening system monitor and killing the pytest process everytime I want to be able to quit the test.
I'm hoping there is a better way.
The issue can be reproduced by the following snippet -
import hypothesis
from hypothesis import strategies as st
#hypothesis.given(st.integers())
def test_some_function(some_arg):
breakpoint()
print(some_arg)
test_some_function()
I am using python 3.8 with hypothesis 5.37.0
This happens under Linux but not under Windows, and it's unclear whether or not that's a bug in Hypothesis, or in Pdb, or 'just' undesirable behaviour from a combination of features.
As a workaround, you can import os; os._exit(0) to skip all cleanup logic and exit instantly.
A better, albeit somewhat more involved, solution is to disable multi-bug reporting and the shrinking phase when you use a debugger, so that Hypothesis stops generating examples immediately after the first failure. You can create a settings profile for use with the debugger, and then activate it via the --hypothesis-profile= argument to pytest.
It's hard to describe the issue without sharing the entire codebase but I'll do my best. I'm using a big QA project that is organized with pytest. I try to debug it in PyCharm.
class TestDownloadHistoricalRaw(base_test.BaseTest):
#classmethod
def callme(cls):
logger.info("INFO: Download Raw data!")
print("==debug== 1")
print("==debug== 2") # breakpoint
print("==debug== 3") # breakpoint
...
...
I set breakpoints at the ==debug== 2 and ==debug== 3 lines. Then I ran pytest on class TestDownloadHistoricalRaw.
PyCharm correctly executes the program and pauses at the ==debug== 2 line. But it has trouble showing variables. And Evaluation doesn't work for any expressions at all.
When I click Step Over, the program hangs there without any progression. It can't reach ==debug== 3.
I tried to add breakpoints to a hello world program wrapped in a pytest class. I can set breakpoints and see variables all fine. So now I'm stuck and not sure what to do.
We have been running a script on partner's computer for 18 hours. We underestimated how long it would take, and now need to turn in the results. Is it possible to stop the script from running, but still have access to all the lists we are building?
We need to add additional code to the one we are currently running that will use the lists being populated right now. Is there a way to stop the process, but still use (what has been generated of) the lists in the next portion of code?
My partner was using python interactively.
update
We were able to successfully print the results and copy and paste after interrupting the program with control-C.
Well, OP doesn't seem to need an answer anymore. But I'll answer anyway for anyone else coming accross this.
While it is true that stopping the program will delete all data from memory you can still save it. You can inject a debug session and save whatever you need before you kill the process.
Both PyCharm and PyDev support attaching their debugger to a running python application.
See here for an explanation how it works in PyCharm.
Once you've attached the debugger, you can set a breakpoint in your code and the program will stop when it hits that line the next time. Then you can inspect all variables and run some code via the 'Evaluate' feature. This code may save whatever variable you need.
I've tested this with PyCharm 2018.1.1 Community Edition and Python 3.6.4.
In order to do so I ran this code which I saved as test.py
import collections
import time
data = collections.deque(maxlen=100)
i = 0
while True:
data.append(i % 1000)
i += 1
time.sleep(0.001)
via the command python3 test.py from an external Windows PowerShell instance.
Then I've opened that file in PyCharm and attached the debugger. I set a Breakpoint at the line i += 1 and it halted right there. Then I evaluated the following code fragment:
import json
with open('data.json', 'w') as ofile:
json.dump(list(data), ofile)
And found all entries from data in the json file data.json.
Follow-up:
This even works in an interactive session! I ran the very same code in a jupyter notebook cell and then attached the debugger to the kernel. Still having test.py open, I set the breakpoint again on the same line as before and the kernel halted. Then I could see all variables from the interactive notebook session.
I don't think so. Stopping the program should also release all of the memory it was using.
edit: See Swenzel's comment for one way of doing it.
I have a long running python script(let's call it upgrade.py).
The script has many steps or parts (essentially XML API calls to a router to run certain commands on the router).
I need suggestions on how to achieve the following:
I'm looking to compartmentalize the script such that if any step fails the script execution should pause and it notifies the user via email (I can handle the emailing part).
The user can then fix the issue on his router and should be able to RESUME his script i.e. script resumes execution starting from the step that failed.
In short how do I go about compartmentalizing the script into steps (or test cases) so that:
The script PAUSES at a certain step that failed
The user is able to later RESUME the script (starting from that failed step)
Most test automation approaches will break off the test suite and then re-try all test cases after a fix has been applied. This has the added benefit that when a fix impacts already run scripts, this is also discovered.
Given the lengthy nature of your test, this may not be practical. The below scipt will use the Dialogs and the Wait Until Keyword Succeeds to allow for 3 retries before continuing with the next step in the test case.
*** Settings ***
Library Dialogs
*** Test Cases ***
Test Case
Wait Until Keyword Succeeds 3 times 1 second Failing Keyword
Log To Console End Test Case
*** Keywords ***
Failing Keyword
Fail Keyword failed
[Teardown] Dialogs.Pause Execution Please Check your settings.
I want to create a build pipeline, and developers need to set up a few things into a properties file which gets populated using a front end GUI.
I tried running sample CLI interactive script using python that just asked for a name and prints it out afterwards, but Jenkins just waited for ages then hanged. I see that it asked for the input, but there was no way for the user to input the data.
EDIT: Currently running Jenkins as a service..Or is there a good plugin anyone recommends or is it the way I created the python script?
Preference:
I would prefer to use Python because it is a little lightweight, but if people had success with other languages I can comprise.
Using a GUI menu to populate the data, would be cool because I can use option boxes, drop down menus and make it fancy but it isn't a necessity, a CLI is considerably better than our current deployment.
BTW, running all this on Windows 7 laptop running Python 2.7 and Java 1.7
Sorry for the essay! Hopefully people can help me!
Sorry, but Jenkins is not an interactive application. It is designed for automated execution.
The only viable way to get input to a Jenkins job (and everything that is executed from that job) is with the job parameters that are populated before the job is started. Granted, Jenkins GUI for parameter entry is not the greatest, but it does the job. Once the Jenkins job collected the job parameters at the start of the job, it can pass those parameters to anything it executes (Python, shell, whatever) at any time during the job. Two things have to be true for that to happen:
You need to collect all the input data before the job starts
Whatever your job calls (Python, shell, etc) need to be able to receive their input not interactively, but through command line.
How to get input into program
A well designed script should be able to simply accept parameters on the command line:
./goodscript.sh MyName will be the simplest way of doing it, where value MyName will be stored in $1 first parameter of the script. Subsequent command line parameters will be available in variables $2, $3 and so on.
./goodscript.sh -name MyName -age 30 will be a better way of doing it, where the script can take multiple parameters regardless of their order by specifying a parameter name before parameter value. You can read about using getopt for this method of parameter passing
Both examples above assume that the goodscript.sh is written well enough to be able to process those command line parameters. If the script does not explicitly process command line parameters, doing the above will be useless.
You can "pipe" some output to an interactive script that is not designed to handle command line parameters explicitly:
echo MyName | ./interactivescript.sh will pass value MyName to the first interactive prompt that interactivescript.sh provides to the user. Problem with this is that you can only pass a value to the first interactive prompt.
Jenkins job parameters GUI
Like I said above, you can use Jenkins GUI to gather all sorts of job parameters (dropdown lists, checkboxes, text entry). I assume you know how to setup Jenkins job with parameters. If not, in the job configuration click "This build is parameterized" checkbox. If you can't figure out how to set this up, that's a different question and will need to be explained separately.
However, once your Jenkins job collected all the parameters up front, you can reference them in your "execute shell" step. If you are using Windows, you will reference them as %PARAM_NAME%, and for Linux as $PARAM_NAME.
Explain what you need help with: getting your script to accept command line parameters, or passing those command line parameters from jenkins job GUI, and I will expand this answer further