How to test a console print with pytest and python? - python-2.7

I would like to test the print of a function with unitest on python 2.7 :
Example:
def load_parse_xml(data_file):
if os.path.isfile(data_file):
print "Parsing..."
data_parse = ET.ElementTree(file=data_file)
return data_parse.getroot()
else:
print data_file + " --> File not exist"
In the example I want to test that we have "Parsing ..." in the console
here is my test:
def test_load_parse_xml(self):
data_file = os.getcwd() + "/xml_tests/xmltest.xml"
load_parse_xml(data_file)
.......
But then I don't know how to test what is written "Parsing ..." in the console. I am blocked!
I just want to test if we have the same message in the console as "Parsing ..."

You can use capsys from pytest.
See also: https://docs.pytest.org/en/6.2.x/capture.html#accessing-captured-output-from-a-test-function
You could do something like this:
def test_test(capsys):
print("Your print out from load_parse_xml")
captured = capsys.readouterr()
assert captured.out.strip() == "Your print out from load_parse_xml"

Related

Can anyone help me with the below code as it is working fine without flask in local system but not with FLASK? [duplicate]

This question already has answers here:
Method Not Allowed flask error 405
(7 answers)
Closed 3 years ago.
Code is running fine with local system but I'm getting the following error whenever I try to submit data to my Flask form:
Error: Method Not Allowed The method is not allowed for the requested URL.
Relevant parts of my code are as follows:
pytesseract.pytesseract.tesseract_cmd = 'C:\\Users\\Abhi\\AppData\\Local\\Programs\\Python\\Python37-32\\Lib\\site-packages\\pytesseract\\Tesseract-OCR\\tesseract.exe'
#Poppler executable file is mandatory to load
PDFTOPPMPATH = r"C:\Users\Abhi\Downloads\poppler-0.68.0_x86\poppler-0.68.0\bin\pdftoppm.exe"
PDFFILE = "C:\\Users\\Abhi\\rep.pdf"
subprocess.Popen('"%s" -png "%s" out' % (PDFTOPPMPATH, PDFFILE))
app = Flask(__name__)
#app.route('/', methods=['POST'])
def predict():
im = Image.open("out-2.png")
rgb_im = im.convert('RGB')
rgb_im.save('m.jpg')
im = Image.open("m.jpg")
text1 = pytesseract.image_to_string(im, lang = 'eng')
with open("report.txt","w") as f:
f.write(text1)
para = ["Emissivity","Refl. temp.","Distance","Relative humidity","Atmospheric temperature","Transmission"]
f=open('report.txt')
lines=f.readlines()
#lines.remove("\n")
for i in range(0,len(lines)):
if "jpg" in lines[i]:
end1 = i-1
if "MEASUREMENTS (°C)" in lines[i]:
start1 = i+1
if "Report" in lines[i]:
end2 = i-1
if "Transmission" in lines[i]:
trans = i+1
#print(str(start1) + " " + str(end1)+" " +str(trans) + " " + str(end2))
for i in range(start1-1,trans):
return str(lines[i])
if __name__ == '__main__':
#p = int(os.getenv('PORT', 5000))
#app.run(debug = True, port=p, host='0.0.0.0')
#app.run()
app.run(debug=True, use_reloader=False)
What is happening here is that route does not accept any url methods.its look like you are trying to return a string.U have to convert that in to a json.use Mashmellow to serialize ur output.or use bellow method(using json lib to covert list to a json format)
import json
def index():
lines=[1,2,3,4,5]
return json.dumps(lines[0])
use above template and customize it to your needs.hope this help

How to set failed in POSTMAN Collection runner via script

How can I set a "FAILED" via script? I have a IF and in this if I want to check is X compare to Y. If not I want to get an "FAILED". For now I get an "FAILED" in my console but the test is "PASS". I already searched other sites but found nothing about this. Hope u now what I mean.
if(pm.iterationData.get("ProfileSeries") == response.ProfileSeries){
console.log("expProfileSeries " + pm.iterationData.get("ProfileSeries") + " = "+ response.ProfileSeries);
}
else{
console.log("FAILED");
}
Add pm.test with relevant pm.expect:
pm.test('ProfileSeries should be equal', function () {
pm.expect(pm.iterationData.get("ProfileSeries")).to.equal(response.ProfileSeries);
});

How to save result of a function into a string so it can be sent via email (using smtplib and MIME)?

I am new to Python and very much a rookie. I am trying to write a program that uses the requests module to make a request to the Dark Sky API for a weather forecast, and then uses smtplib to send that forecast in an email to myself. I have truncated my code to only show the relevant parts. I have been unable to find any answers so far so I apologise if this is a duplicate. The below code will print the function to the console without any issues, but when I try to assign it to the "body" variable and email it, the email is blank. Or if I use str(ds.current)) the email just has "none" as the body text.
How can I make it work so that the body text of the email contains the forecast that has been requested from the API? Many thanks in advance, and sorry for any rookie errors.
import requests
import json
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
class Darksky():
r = requests.get('https://api.darksky.net/forecast/e01635ccacb5548e3d1fa40403bbb3a5/-45.0312,168.6626?units=ca')
wx_json = r.json()
def __init__(self, source):
self.source = source
print "\n", "-" * 20, source, "-" * 20, "\n"
def current(self):
def summary():
return "CURRENT WEATHER:"
x = self.wx_json['currently']['summary']
return x
# I have tried using print instead of return but that did not work either.
def temp():
return "TEMPERATURE:"
y = self.wx_json['currently']['temperature']
return y
summary()
temp()
ds = Darksky("DARKSKY WX")
fromaddr = "watsonthevirtualbutler#gmail.com"
toaddr = "matt#peakpixel.nz"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "YOUR DAILY WEATHER, SIR."
body = ds.current()
# This is where I am trying to save the function result as a string that can be emailed.
# I have tried using "str(ds.current())" but that just returns "none".
print body
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "virtualbutler")
text = msg.as_string()
msg = "CAN YOU HEAR ME, SIR?"
server.sendmail(fromaddr, toaddr, text)
server.quit()
Your summary() and temp() has two return operators, while only one return is acceptable. If you want your_function() to return few values, you can do something like: return {"first_parameter": "first_value", "second_parameter": "second_value"} and then call each value as your_function()["first_parameter"] or your_function()["second_parameter"]
Try following code and let me know the result:
class Darksky():
r = requests.get('https://api.darksky.net/forecast/e01635ccacb5548e3d1fa40403bbb3a5/-45.0312,168.6626?units=ca')
wx_json = r.json()
def __init__(self, source):
self.source = source
print "\n", "-" * 20, source, "-" * 20, "\n"
def current(self):
return "CURRENT WEATHER: {0}. TEMPERATURE: {1}".format(self.wx_json['currently']['summary'], self.wx_json['currently']['temperature'])
ds = Darksky("DARKSKY WX")
body = ds.current()

How can you make a timer run simultaneously with the rest of the code in Python?

I am making a simple math test for my friend's class. The students will only have 45 seconds to solve each answer. Is there a way to make a timer that will count at the same time as the rest of the code runs and when it reaches 45 stops?
The test looks like this:
test = raw_input("How much is 62x5-23?")
if test == '287':
print "Well done!"
Here's some code I used once (lifted off some page on the web which is now in the hands of a domain squatter, so no credit where credit is due, sadly):
import signal
class TimeoutException(Exception):
pass
def timeout(timeout_time, default = None):
def timeout_function(f):
def f2(*args, **kwargs):
def timeout_handler(signum, frame):
raise TimeoutException()
old_handler = signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout_time) # triger alarm in timeout_time seconds
try:
retval = f(*args, **kwargs)
except TimeoutException, e:
if default == None:
raise e
return default
finally:
signal.signal(signal.SIGALRM, old_handler)
signal.alarm(0)
return retval
return f2
return timeout_function
# use like this:
#timeout(45)
def run():
test = raw_input("How much is 62x5-23? ")
if test == '287':
print "Well done!"
# alternatively, pass a value that will be returned when the timeout is reached:
#timeout(45, False)
def run2():
test = raw_input("How much is 62x5-23? ")
if test == '287':
print "Well done!"
if __name__ == '__main__':
try:
run()
except TimeoutException:
print "\nSorry, you took too long."
# alternative call:
if run2() == False:
print "\nSorry, you took too long."
EDIT: probably works on Unix-type OS'es only.

django served file returned empty on windows, not on mac

def _tarFiles(filepaths):
print "create tar file from all files in file list and save to temp working dir. returns tarfile path "
try:
savePathDir = settings.TAR_FILE_TARGET_DIRECTORY
if not os.path.exists(savePathDir):
os.makedirs(savePathDir)
tarredfiles = tarfile.open(settings.TAR_FILE_TARGET_DIRECTORY + '/' + 'responsefiles.tar',mode='w')
for f in filepaths:
tarredfiles.add(f)
tarredfiles.close()
return ("Ok", settings.TAR_FILE_TARGET_DIRECTORY + '/' + 'responsefiles.tar')
except Exception as e:
return ("Error in "+ inspect.stack()[0][3] + " " + e.message, None)
def sendFiles(files):
try:
result, tarfilename = _tarFiles(files)
if result == 'Ok':
try:
print tarfilename
wrapper = FileWrapper(file(tarfilename))
response = HttpResponse(wrapper, content_type='application/x-tar') #zip,avi,png,jpeg, etc...
response['Content-Disposition'] = 'attachment; filename=' + tarfilename#tarredfiles.name #eg. myfile.zip
response['Content-Length'] = str(os.path.getsize(tarfilename))
return ("Ok",response)
except Exception as e:
return ("Error in "+ inspect.stack()[0][3] + " " + e.message, None)
else:
return (result,None)
except Exception as e:
return ("Error in "+ inspect.stack()[0][3] + " " +e.message,None)
tarfilename is the complete path to the file.
The content-length looks right (comparing actual file to getsize).
Works on a mac running runserver. Returns a partial file on windows running runserver. Or completely empty file if I step through on windows.
The target directory and filename generated is "tarred_files/responsefiles.tar"
the file size is 90K and the os.path.getsize returned is 92160
What am I doing that would cause an empty file to be downloaded?
For windows, you need to add "rb" to file.
like so:
wrapper = FileWrapper(file(tarfilename,'rb'))
Also, Content-Length should use a integer, not a string
like so:
response['Content-Length'] = os.path.getsize(tarfilename)